mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
engine.Responder with ProcessCdr method, moved cdrs and mediator to engine
This commit is contained in:
@@ -1458,7 +1458,6 @@ func TestLocalProcessCdr(t *testing.T) {
|
|||||||
t.Error("Unexpected reply received: ", reply)
|
t.Error("Unexpected reply received: ", reply)
|
||||||
}
|
}
|
||||||
var cdrs []*utils.StoredCdr
|
var cdrs []*utils.StoredCdr
|
||||||
time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time to CDR to reach db
|
|
||||||
req := utils.AttrGetCdrs{}
|
req := utils.AttrGetCdrs{}
|
||||||
if err := rater.Call("ApierV1.GetCdrs", req, &cdrs); err != nil {
|
if err := rater.Call("ApierV1.GetCdrs", req, &cdrs); err != nil {
|
||||||
t.Error("Unexpected error: ", err.Error())
|
t.Error("Unexpected error: ", err.Error())
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Real-time Charging System for Telecom & ISP environments
|
Real-time Charging System for Telecom & ISP environments
|
||||||
Copyright (C) 2012-2014 ITsysCOM GmbH
|
Copyright (C) ITsysCOM GmbH
|
||||||
|
|
||||||
This program is free software: you can Storagetribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,4 +16,26 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package mediator
|
package apier
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/cgrates/cgrates/engine"
|
||||||
|
"github.com/cgrates/cgrates/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Receive CDRs via RPC methods
|
||||||
|
type CDRSV1 struct {
|
||||||
|
CdrSrv *engine.CDRS
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cdrsrv *CDRSV1) ProcessCdr(cdr *utils.StoredCdr, reply *string) error {
|
||||||
|
if cdrsrv.CdrSrv == nil {
|
||||||
|
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, "CDRS_NOT_RUNNING")
|
||||||
|
}
|
||||||
|
if err := cdrsrv.CdrSrv.ProcessCdr(cdr); err != nil {
|
||||||
|
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||||
|
}
|
||||||
|
*reply = utils.OK
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -20,13 +20,13 @@ package apier
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/cgrates/cgrates/mediator"
|
"github.com/cgrates/cgrates/engine"
|
||||||
"github.com/cgrates/cgrates/utils"
|
"github.com/cgrates/cgrates/utils"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MediatorV1 struct {
|
type MediatorV1 struct {
|
||||||
Medi *mediator.Mediator
|
Medi *engine.Mediator
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remotely start mediation with specific runid, runs asynchronously, it's status will be displayed in syslog
|
// Remotely start mediation with specific runid, runs asynchronously, it's status will be displayed in syslog
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/cgrates/cgrates/cdrs"
|
|
||||||
"github.com/cgrates/cgrates/engine"
|
"github.com/cgrates/cgrates/engine"
|
||||||
"github.com/cgrates/cgrates/utils"
|
"github.com/cgrates/cgrates/utils"
|
||||||
"github.com/howeyc/fsnotify"
|
"github.com/howeyc/fsnotify"
|
||||||
@@ -43,7 +42,7 @@ const (
|
|||||||
FS_CSV = "freeswitch_csv"
|
FS_CSV = "freeswitch_csv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCdrc(cdrsAddress, cdrType, cdrInDir, cdrOutDir, cdrSourceId string, runDelay time.Duration, csvSep string, cdrFields map[string][]*utils.RSRField, cdrServer *cdrs.CDRS) (*Cdrc, error) {
|
func NewCdrc(cdrsAddress, cdrType, cdrInDir, cdrOutDir, cdrSourceId string, runDelay time.Duration, csvSep string, cdrFields map[string][]*utils.RSRField, cdrServer *engine.CDRS) (*Cdrc, error) {
|
||||||
if len(csvSep) != 1 {
|
if len(csvSep) != 1 {
|
||||||
return nil, fmt.Errorf("Unsupported csv separator: %s", csvSep)
|
return nil, fmt.Errorf("Unsupported csv separator: %s", csvSep)
|
||||||
}
|
}
|
||||||
@@ -69,7 +68,7 @@ type Cdrc struct {
|
|||||||
runDelay time.Duration
|
runDelay time.Duration
|
||||||
csvSep rune
|
csvSep rune
|
||||||
cdrFields map[string][]*utils.RSRField
|
cdrFields map[string][]*utils.RSRField
|
||||||
cdrServer *cdrs.CDRS // Reference towards internal cdrServer if that is the case
|
cdrServer *engine.CDRS // Reference towards internal cdrServer if that is the case
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import (
|
|||||||
//"bytes"
|
//"bytes"
|
||||||
//"encoding/csv"
|
//"encoding/csv"
|
||||||
//"fmt"
|
//"fmt"
|
||||||
"github.com/cgrates/cgrates/cdrs"
|
|
||||||
"github.com/cgrates/cgrates/config"
|
"github.com/cgrates/cgrates/config"
|
||||||
|
"github.com/cgrates/cgrates/engine"
|
||||||
"github.com/cgrates/cgrates/utils"
|
"github.com/cgrates/cgrates/utils"
|
||||||
//"io"
|
//"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -37,7 +37,7 @@ func TestRecordForkCdr(t *testing.T) {
|
|||||||
cgrConfig.CdrcCdrFields["supplier"] = []*utils.RSRField{&utils.RSRField{Id: "14"}}
|
cgrConfig.CdrcCdrFields["supplier"] = []*utils.RSRField{&utils.RSRField{Id: "14"}}
|
||||||
csvSepRune, _ := utf8.DecodeRune([]byte(cgrConfig.CdrcCsvSep))
|
csvSepRune, _ := utf8.DecodeRune([]byte(cgrConfig.CdrcCsvSep))
|
||||||
cdrc := &Cdrc{cgrConfig.CdrcCdrs, cgrConfig.CdrcCdrType, cgrConfig.CdrcCdrInDir, cgrConfig.CdrcCdrOutDir, cgrConfig.CdrcSourceId, cgrConfig.CdrcRunDelay, csvSepRune,
|
cdrc := &Cdrc{cgrConfig.CdrcCdrs, cgrConfig.CdrcCdrType, cgrConfig.CdrcCdrInDir, cgrConfig.CdrcCdrOutDir, cgrConfig.CdrcSourceId, cgrConfig.CdrcRunDelay, csvSepRune,
|
||||||
cgrConfig.CdrcCdrFields, new(cdrs.CDRS), nil}
|
cgrConfig.CdrcCdrFields, new(engine.CDRS), nil}
|
||||||
cdrRow := []string{"firstField", "secondField"}
|
cdrRow := []string{"firstField", "secondField"}
|
||||||
_, err := cdrc.recordToStoredCdr(cdrRow)
|
_, err := cdrc.recordToStoredCdr(cdrRow)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -31,11 +31,9 @@ import (
|
|||||||
"github.com/cgrates/cgrates/apier"
|
"github.com/cgrates/cgrates/apier"
|
||||||
"github.com/cgrates/cgrates/balancer2go"
|
"github.com/cgrates/cgrates/balancer2go"
|
||||||
"github.com/cgrates/cgrates/cdrc"
|
"github.com/cgrates/cgrates/cdrc"
|
||||||
"github.com/cgrates/cgrates/cdrs"
|
|
||||||
"github.com/cgrates/cgrates/config"
|
"github.com/cgrates/cgrates/config"
|
||||||
"github.com/cgrates/cgrates/engine"
|
"github.com/cgrates/cgrates/engine"
|
||||||
"github.com/cgrates/cgrates/history"
|
"github.com/cgrates/cgrates/history"
|
||||||
"github.com/cgrates/cgrates/mediator"
|
|
||||||
"github.com/cgrates/cgrates/scheduler"
|
"github.com/cgrates/cgrates/scheduler"
|
||||||
"github.com/cgrates/cgrates/sessionmanager"
|
"github.com/cgrates/cgrates/sessionmanager"
|
||||||
"github.com/cgrates/cgrates/utils"
|
"github.com/cgrates/cgrates/utils"
|
||||||
@@ -66,9 +64,9 @@ var (
|
|||||||
exitChan = make(chan bool)
|
exitChan = make(chan bool)
|
||||||
server = &engine.Server{}
|
server = &engine.Server{}
|
||||||
scribeServer history.Scribe
|
scribeServer history.Scribe
|
||||||
cdrServer *cdrs.CDRS
|
cdrServer *engine.CDRS
|
||||||
sm sessionmanager.SessionManager
|
sm sessionmanager.SessionManager
|
||||||
medi *mediator.Mediator
|
medi *engine.Mediator
|
||||||
cfg *config.CGRConfig
|
cfg *config.CGRConfig
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
@@ -111,7 +109,7 @@ func startMediator(responder *engine.Responder, loggerDb engine.LogStorage, cdrD
|
|||||||
connector = &engine.RPCClientConnector{Client: client}
|
connector = &engine.RPCClientConnector{Client: client}
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
medi, err = mediator.NewMediator(connector, loggerDb, cdrDb, cfg)
|
medi, err = engine.NewMediator(connector, loggerDb, cdrDb, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
engine.Logger.Crit(fmt.Sprintf("Mediator config parsing error: %v", err))
|
engine.Logger.Crit(fmt.Sprintf("Mediator config parsing error: %v", err))
|
||||||
exitChan <- true
|
exitChan <- true
|
||||||
@@ -185,10 +183,11 @@ func startCDRS(responder *engine.Responder, cdrDb engine.CdrStorage, mediChan, d
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cdrServer = cdrs.New(cdrDb, medi, cfg)
|
cdrServer = engine.NewCdrS(cdrDb, medi, cfg)
|
||||||
cdrServer.RegisterHanlersToServer(server)
|
cdrServer.RegisterHanlersToServer(server)
|
||||||
engine.Logger.Info("Registering CDRS RPC service.")
|
engine.Logger.Info("Registering CDRS RPC service.")
|
||||||
server.RpcRegister(&apier.CDRSV1{CdrSrv: cdrServer})
|
server.RpcRegister(&apier.CDRSV1{CdrSrv: cdrServer})
|
||||||
|
responder.CdrSrv = cdrServer // Make the cdrserver available for internal communication
|
||||||
close(doneChan)
|
close(doneChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package cdrs
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -24,15 +24,13 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/cgrates/cgrates/config"
|
"github.com/cgrates/cgrates/config"
|
||||||
"github.com/cgrates/cgrates/engine"
|
|
||||||
"github.com/cgrates/cgrates/mediator"
|
|
||||||
"github.com/cgrates/cgrates/utils"
|
"github.com/cgrates/cgrates/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cfg *config.CGRConfig // Share the configuration with the rest of the package
|
cfg *config.CGRConfig // Share the configuration with the rest of the package
|
||||||
storage engine.CdrStorage
|
storage CdrStorage
|
||||||
medi *mediator.Mediator
|
medi *Mediator
|
||||||
)
|
)
|
||||||
|
|
||||||
// Returns error if not able to properly store the CDR, mediation is async since we can always recover offline
|
// Returns error if not able to properly store the CDR, mediation is async since we can always recover offline
|
||||||
@@ -43,7 +41,7 @@ func storeAndMediate(storedCdr *utils.StoredCdr) error {
|
|||||||
if cfg.CDRSMediator == utils.INTERNAL {
|
if cfg.CDRSMediator == utils.INTERNAL {
|
||||||
go func() {
|
go func() {
|
||||||
if err := medi.RateCdr(storedCdr); err != nil {
|
if err := medi.RateCdr(storedCdr); err != nil {
|
||||||
engine.Logger.Err(fmt.Sprintf("Could not run mediation on CDR: %s", err.Error()))
|
Logger.Err(fmt.Sprintf("Could not run mediation on CDR: %s", err.Error()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@@ -54,10 +52,10 @@ func storeAndMediate(storedCdr *utils.StoredCdr) error {
|
|||||||
func cgrCdrHandler(w http.ResponseWriter, r *http.Request) {
|
func cgrCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
cgrCdr, err := utils.NewCgrCdrFromHttpReq(r)
|
cgrCdr, err := utils.NewCgrCdrFromHttpReq(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
engine.Logger.Err(fmt.Sprintf("Could not create CDR entry: %s", err.Error()))
|
Logger.Err(fmt.Sprintf("Could not create CDR entry: %s", err.Error()))
|
||||||
}
|
}
|
||||||
if err := storeAndMediate(cgrCdr.AsStoredCdr()); err != nil {
|
if err := storeAndMediate(cgrCdr.AsStoredCdr()); err != nil {
|
||||||
engine.Logger.Err(fmt.Sprintf("Errors when storing CDR entry: %s", err.Error()))
|
Logger.Err(fmt.Sprintf("Errors when storing CDR entry: %s", err.Error()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,23 +64,23 @@ func fsCdrHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
body, _ := ioutil.ReadAll(r.Body)
|
body, _ := ioutil.ReadAll(r.Body)
|
||||||
fsCdr, err := NewFSCdr(body)
|
fsCdr, err := NewFSCdr(body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
engine.Logger.Err(fmt.Sprintf("Could not create CDR entry: %s", err.Error()))
|
Logger.Err(fmt.Sprintf("Could not create CDR entry: %s", err.Error()))
|
||||||
}
|
}
|
||||||
if err := storeAndMediate(fsCdr.AsStoredCdr()); err != nil {
|
if err := storeAndMediate(fsCdr.AsStoredCdr()); err != nil {
|
||||||
engine.Logger.Err(fmt.Sprintf("Errors when storing CDR entry: %s", err.Error()))
|
Logger.Err(fmt.Sprintf("Errors when storing CDR entry: %s", err.Error()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type CDRS struct{}
|
type CDRS struct{}
|
||||||
|
|
||||||
func New(s engine.CdrStorage, m *mediator.Mediator, c *config.CGRConfig) *CDRS {
|
func NewCdrS(s CdrStorage, m *Mediator, c *config.CGRConfig) *CDRS {
|
||||||
storage = s
|
storage = s
|
||||||
medi = m
|
medi = m
|
||||||
cfg = c
|
cfg = c
|
||||||
return &CDRS{}
|
return &CDRS{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cdrs *CDRS) RegisterHanlersToServer(server *engine.Server) {
|
func (cdrs *CDRS) RegisterHanlersToServer(server *Server) {
|
||||||
server.RegisterHttpFunc("/cgr", cgrCdrHandler)
|
server.RegisterHttpFunc("/cgr", cgrCdrHandler)
|
||||||
server.RegisterHttpFunc("/freeswitch_json", fsCdrHandler)
|
server.RegisterHttpFunc("/freeswitch_json", fsCdrHandler)
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package cdrs
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/cgrates/cgrates/engine"
|
|
||||||
"github.com/cgrates/cgrates/utils"
|
"github.com/cgrates/cgrates/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -111,11 +110,11 @@ func (fsCdr FSCdr) searchExtraField(field string, body map[string]interface{}) (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
engine.Logger.Warning(fmt.Sprintf("Slice with no maps: %v", reflect.TypeOf(item)))
|
Logger.Warning(fmt.Sprintf("Slice with no maps: %v", reflect.TypeOf(item)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
engine.Logger.Warning(fmt.Sprintf("Unexpected type: %v", reflect.TypeOf(v)))
|
Logger.Warning(fmt.Sprintf("Unexpected type: %v", reflect.TypeOf(v)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package cdrs
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -44,7 +44,7 @@ README:
|
|||||||
var ratingDbCsv, ratingDbStor, ratingDbApier RatingStorage // Each ratingDb will have it's own sources to collect data
|
var ratingDbCsv, ratingDbStor, ratingDbApier RatingStorage // Each ratingDb will have it's own sources to collect data
|
||||||
var accountDbCsv, accountDbStor, accountDbApier AccountingStorage // Each ratingDb will have it's own sources to collect data
|
var accountDbCsv, accountDbStor, accountDbApier AccountingStorage // Each ratingDb will have it's own sources to collect data
|
||||||
var storDb LoadStorage
|
var storDb LoadStorage
|
||||||
var cfg *config.CGRConfig
|
var lCfg *config.CGRConfig
|
||||||
|
|
||||||
// Arguments received via test command
|
// 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 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
|
||||||
@@ -57,27 +57,27 @@ func TestConnDataDbs(t *testing.T) {
|
|||||||
if !*testLocal {
|
if !*testLocal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cfg, _ = config.NewDefaultCGRConfig()
|
lCfg, _ = config.NewDefaultCGRConfig()
|
||||||
var err error
|
var err error
|
||||||
if ratingDbCsv, err = ConfigureRatingStorage(cfg.RatingDBType, cfg.RatingDBHost, cfg.RatingDBPort, "4", cfg.RatingDBUser, cfg.RatingDBPass, cfg.DBDataEncoding); err != nil {
|
if ratingDbCsv, err = ConfigureRatingStorage(lCfg.RatingDBType, lCfg.RatingDBHost, lCfg.RatingDBPort, "4", lCfg.RatingDBUser, lCfg.RatingDBPass, lCfg.DBDataEncoding); err != nil {
|
||||||
t.Fatal("Error on ratingDb connection: ", err.Error())
|
t.Fatal("Error on ratingDb connection: ", err.Error())
|
||||||
}
|
}
|
||||||
if ratingDbStor, err = ConfigureRatingStorage(cfg.RatingDBType, cfg.RatingDBHost, cfg.RatingDBPort, "5", cfg.RatingDBUser, cfg.RatingDBPass, cfg.DBDataEncoding); err != nil {
|
if ratingDbStor, err = ConfigureRatingStorage(lCfg.RatingDBType, lCfg.RatingDBHost, lCfg.RatingDBPort, "5", lCfg.RatingDBUser, lCfg.RatingDBPass, lCfg.DBDataEncoding); err != nil {
|
||||||
t.Fatal("Error on ratingDb connection: ", err.Error())
|
t.Fatal("Error on ratingDb connection: ", err.Error())
|
||||||
}
|
}
|
||||||
if ratingDbApier, err = ConfigureRatingStorage(cfg.RatingDBType, cfg.RatingDBHost, cfg.RatingDBPort, "6", cfg.RatingDBUser, cfg.RatingDBPass, cfg.DBDataEncoding); err != nil {
|
if ratingDbApier, err = ConfigureRatingStorage(lCfg.RatingDBType, lCfg.RatingDBHost, lCfg.RatingDBPort, "6", lCfg.RatingDBUser, lCfg.RatingDBPass, lCfg.DBDataEncoding); err != nil {
|
||||||
t.Fatal("Error on ratingDb connection: ", err.Error())
|
t.Fatal("Error on ratingDb connection: ", err.Error())
|
||||||
}
|
}
|
||||||
if accountDbCsv, err = ConfigureAccountingStorage(cfg.AccountDBType, cfg.AccountDBHost, cfg.AccountDBPort, "7",
|
if accountDbCsv, err = ConfigureAccountingStorage(lCfg.AccountDBType, lCfg.AccountDBHost, lCfg.AccountDBPort, "7",
|
||||||
cfg.AccountDBUser, cfg.AccountDBPass, cfg.DBDataEncoding); err != nil {
|
lCfg.AccountDBUser, lCfg.AccountDBPass, lCfg.DBDataEncoding); err != nil {
|
||||||
t.Fatal("Error on ratingDb connection: ", err.Error())
|
t.Fatal("Error on ratingDb connection: ", err.Error())
|
||||||
}
|
}
|
||||||
if accountDbStor, err = ConfigureAccountingStorage(cfg.AccountDBType, cfg.AccountDBHost, cfg.AccountDBPort, "8",
|
if accountDbStor, err = ConfigureAccountingStorage(lCfg.AccountDBType, lCfg.AccountDBHost, lCfg.AccountDBPort, "8",
|
||||||
cfg.AccountDBUser, cfg.AccountDBPass, cfg.DBDataEncoding); err != nil {
|
lCfg.AccountDBUser, lCfg.AccountDBPass, lCfg.DBDataEncoding); err != nil {
|
||||||
t.Fatal("Error on ratingDb connection: ", err.Error())
|
t.Fatal("Error on ratingDb connection: ", err.Error())
|
||||||
}
|
}
|
||||||
if accountDbApier, err = ConfigureAccountingStorage(cfg.AccountDBType, cfg.AccountDBHost, cfg.AccountDBPort, "9",
|
if accountDbApier, err = ConfigureAccountingStorage(lCfg.AccountDBType, lCfg.AccountDBHost, lCfg.AccountDBPort, "9",
|
||||||
cfg.AccountDBUser, cfg.AccountDBPass, cfg.DBDataEncoding); err != nil {
|
lCfg.AccountDBUser, lCfg.AccountDBPass, lCfg.DBDataEncoding); err != nil {
|
||||||
t.Fatal("Error on ratingDb connection: ", err.Error())
|
t.Fatal("Error on ratingDb connection: ", err.Error())
|
||||||
}
|
}
|
||||||
for _, db := range []Storage{ratingDbCsv, ratingDbStor, ratingDbApier, accountDbCsv, accountDbStor, accountDbApier} {
|
for _, db := range []Storage{ratingDbCsv, ratingDbStor, ratingDbApier, accountDbCsv, accountDbStor, accountDbApier} {
|
||||||
@@ -94,7 +94,7 @@ func TestCreateStorTpTables(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var db *MySQLStorage
|
var db *MySQLStorage
|
||||||
if d, err := NewMySQLStorage(cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass); err != nil {
|
if d, err := NewMySQLStorage(lCfg.StorDBHost, lCfg.StorDBPort, lCfg.StorDBName, lCfg.StorDBUser, lCfg.StorDBPass); err != nil {
|
||||||
t.Error("Error on opening database connection: ", err)
|
t.Error("Error on opening database connection: ", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package mediator
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@@ -24,11 +24,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cgrates/cgrates/config"
|
"github.com/cgrates/cgrates/config"
|
||||||
"github.com/cgrates/cgrates/engine"
|
|
||||||
"github.com/cgrates/cgrates/utils"
|
"github.com/cgrates/cgrates/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewMediator(connector engine.Connector, logDb engine.LogStorage, cdrDb engine.CdrStorage, cfg *config.CGRConfig) (m *Mediator, err error) {
|
func NewMediator(connector Connector, logDb LogStorage, cdrDb CdrStorage, cfg *config.CGRConfig) (m *Mediator, err error) {
|
||||||
m = &Mediator{
|
m = &Mediator{
|
||||||
connector: connector,
|
connector: connector,
|
||||||
logDb: logDb,
|
logDb: logDb,
|
||||||
@@ -39,16 +38,16 @@ func NewMediator(connector engine.Connector, logDb engine.LogStorage, cdrDb engi
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Mediator struct {
|
type Mediator struct {
|
||||||
connector engine.Connector
|
connector Connector
|
||||||
logDb engine.LogStorage
|
logDb LogStorage
|
||||||
cdrDb engine.CdrStorage
|
cdrDb CdrStorage
|
||||||
cgrCfg *config.CGRConfig
|
cgrCfg *config.CGRConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrive the cost from logging database, nil in case of no log
|
// Retrive the cost from logging database, nil in case of no log
|
||||||
func (self *Mediator) getCostsFromDB(cgrid, runId string) (cc *engine.CallCost, err error) {
|
func (self *Mediator) 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
|
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, engine.SESSION_MANAGER_SOURCE, runId)
|
cc, err = self.logDb.GetCallCostLog(cgrid, SESSION_MANAGER_SOURCE, runId)
|
||||||
if cc != nil {
|
if cc != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -58,13 +57,13 @@ func (self *Mediator) getCostsFromDB(cgrid, runId string) (cc *engine.CallCost,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrive the cost from engine
|
// Retrive the cost from engine
|
||||||
func (self *Mediator) getCostFromRater(storedCdr *utils.StoredCdr) (*engine.CallCost, error) {
|
func (self *Mediator) getCostFromRater(storedCdr *utils.StoredCdr) (*CallCost, error) {
|
||||||
cc := &engine.CallCost{}
|
cc := &CallCost{}
|
||||||
var err error
|
var err error
|
||||||
if storedCdr.Usage == time.Duration(0) { // failed call, returning empty callcost, no error
|
if storedCdr.Usage == time.Duration(0) { // failed call, returning empty callcost, no error
|
||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
cd := engine.CallDescriptor{
|
cd := CallDescriptor{
|
||||||
TOR: storedCdr.TOR,
|
TOR: storedCdr.TOR,
|
||||||
Direction: storedCdr.Direction,
|
Direction: storedCdr.Direction,
|
||||||
Tenant: storedCdr.Tenant,
|
Tenant: storedCdr.Tenant,
|
||||||
@@ -82,16 +81,16 @@ func (self *Mediator) getCostFromRater(storedCdr *utils.StoredCdr) (*engine.Call
|
|||||||
err = self.connector.GetCost(cd, cc)
|
err = self.connector.GetCost(cd, cc)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.logDb.LogError(storedCdr.CgrId, engine.MEDIATOR_SOURCE, storedCdr.MediationRunId, err.Error())
|
self.logDb.LogError(storedCdr.CgrId, MEDIATOR_SOURCE, storedCdr.MediationRunId, err.Error())
|
||||||
} else {
|
} else {
|
||||||
// If the mediator calculated a price it will write it to logdb
|
// If the mediator calculated a price it will write it to logdb
|
||||||
self.logDb.LogCallCost(storedCdr.CgrId, engine.MEDIATOR_SOURCE, storedCdr.MediationRunId, cc)
|
self.logDb.LogCallCost(storedCdr.CgrId, MEDIATOR_SOURCE, storedCdr.MediationRunId, cc)
|
||||||
}
|
}
|
||||||
return cc, err
|
return cc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Mediator) rateCDR(storedCdr *utils.StoredCdr) error {
|
func (self *Mediator) rateCDR(storedCdr *utils.StoredCdr) error {
|
||||||
var qryCC *engine.CallCost
|
var qryCC *CallCost
|
||||||
var errCost error
|
var errCost error
|
||||||
if storedCdr.ReqType == utils.PREPAID {
|
if storedCdr.ReqType == utils.PREPAID {
|
||||||
// Should be previously calculated and stored in DB
|
// Should be previously calculated and stored in DB
|
||||||
@@ -116,7 +115,7 @@ func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr) error {
|
|||||||
var dcs utils.DerivedChargers
|
var dcs utils.DerivedChargers
|
||||||
if err := self.connector.GetDerivedChargers(attrsDC, &dcs); err != nil {
|
if err := self.connector.GetDerivedChargers(attrsDC, &dcs); err != nil {
|
||||||
errText := fmt.Sprintf("Could not get derived charging for cgrid %s, error: %s", storedCdr.CgrId, err.Error())
|
errText := fmt.Sprintf("Could not get derived charging for cgrid %s, error: %s", storedCdr.CgrId, err.Error())
|
||||||
engine.Logger.Err(errText)
|
Logger.Err(errText)
|
||||||
return errors.New(errText)
|
return errors.New(errText)
|
||||||
}
|
}
|
||||||
for _, dc := range dcs {
|
for _, dc := range dcs {
|
||||||
@@ -156,7 +155,7 @@ func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr) error {
|
|||||||
extraInfo = err.Error()
|
extraInfo = err.Error()
|
||||||
}
|
}
|
||||||
if err := self.cdrDb.SetRatedCdr(cdr, extraInfo); err != nil {
|
if err := self.cdrDb.SetRatedCdr(cdr, extraInfo); err != nil {
|
||||||
engine.Logger.Err(fmt.Sprintf("<Mediator> Could not record cost for cgrid: <%s>, ERROR: <%s>, cost: %f, extraInfo: %s",
|
Logger.Err(fmt.Sprintf("<Mediator> Could not record cost for cgrid: <%s>, ERROR: <%s>, cost: %f, extraInfo: %s",
|
||||||
cdr.CgrId, err.Error(), cdr.Cost, extraInfo))
|
cdr.CgrId, err.Error(), cdr.Cost, extraInfo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package mediator
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
@@ -31,7 +31,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cgrates/cgrates/config"
|
"github.com/cgrates/cgrates/config"
|
||||||
"github.com/cgrates/cgrates/engine"
|
|
||||||
"github.com/cgrates/cgrates/utils"
|
"github.com/cgrates/cgrates/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,13 +48,11 @@ README:
|
|||||||
* Execute remote Apis and test their replies(follow prepaid1cent scenario so we can test load in dataDb also).
|
* Execute remote Apis and test their replies(follow prepaid1cent scenario so we can test load in dataDb also).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var cfg *config.CGRConfig
|
var cgrCfg *config.CGRConfig
|
||||||
var cgrRpc *rpc.Client
|
var cgrRpc *rpc.Client
|
||||||
var cdrStor engine.CdrStorage
|
var cdrStor CdrStorage
|
||||||
var httpClient *http.Client
|
var httpClient *http.Client
|
||||||
|
|
||||||
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 storDbType = flag.String("stordb_type", utils.MYSQL, "The type of the storDb database <mysql>")
|
var storDbType = flag.String("stordb_type", utils.MYSQL, "The type of the storDb database <mysql>")
|
||||||
var startDelay = flag.Int("delay_start", 300, "Number of miliseconds to it for rater to start and cache")
|
var startDelay = flag.Int("delay_start", 300, "Number of miliseconds to it for rater to start and cache")
|
||||||
var cfgPath = path.Join(*dataDir, "conf", "samples", "mediator_test1.cfg")
|
var cfgPath = path.Join(*dataDir, "conf", "samples", "mediator_test1.cfg")
|
||||||
@@ -65,11 +62,11 @@ func TestInitRatingDb(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
cfg, err = config.NewCGRConfigFromFile(&cfgPath)
|
cgrCfg, err = config.NewCGRConfigFromFile(&cfgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Got config error: ", err.Error())
|
t.Fatal("Got config error: ", err.Error())
|
||||||
}
|
}
|
||||||
ratingDb, err := engine.ConfigureRatingStorage(cfg.RatingDBType, cfg.RatingDBHost, cfg.RatingDBPort, cfg.RatingDBName, cfg.RatingDBUser, cfg.RatingDBPass, cfg.DBDataEncoding)
|
ratingDb, err := ConfigureRatingStorage(cgrCfg.RatingDBType, cgrCfg.RatingDBHost, cgrCfg.RatingDBPort, cgrCfg.RatingDBName, cgrCfg.RatingDBUser, cgrCfg.RatingDBPass, cgrCfg.DBDataEncoding)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Cannot connect to dataDb", err)
|
t.Fatal("Cannot connect to dataDb", err)
|
||||||
}
|
}
|
||||||
@@ -86,14 +83,14 @@ func TestInitStorDb(t *testing.T) {
|
|||||||
if *storDbType != utils.MYSQL {
|
if *storDbType != utils.MYSQL {
|
||||||
t.Fatal("Unsupported storDbType")
|
t.Fatal("Unsupported storDbType")
|
||||||
}
|
}
|
||||||
var mysql *engine.MySQLStorage
|
var mysql *MySQLStorage
|
||||||
var err error
|
var err error
|
||||||
if cdrStor, err = engine.ConfigureCdrStorage(cfg.StorDBType, cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass); err != nil {
|
if cdrStor, err = ConfigureCdrStorage(cgrCfg.StorDBType, cgrCfg.StorDBHost, cgrCfg.StorDBPort, cgrCfg.StorDBName, cgrCfg.StorDBUser, cgrCfg.StorDBPass); err != nil {
|
||||||
t.Fatal("Error on opening database connection: ", err)
|
t.Fatal("Error on opening database connection: ", err)
|
||||||
} else {
|
} else {
|
||||||
mysql = cdrStor.(*engine.MySQLStorage)
|
mysql = cdrStor.(*MySQLStorage)
|
||||||
}
|
}
|
||||||
if err := mysql.CreateTablesFromScript(path.Join(*dataDir, "storage", *storDbType, engine.CREATE_CDRS_TABLES_SQL)); err != nil {
|
if err := mysql.CreateTablesFromScript(path.Join(*dataDir, "storage", *storDbType, CREATE_CDRS_TABLES_SQL)); err != nil {
|
||||||
t.Fatal("Error on mysql creation: ", err.Error())
|
t.Fatal("Error on mysql creation: ", err.Error())
|
||||||
return // No point in going further
|
return // No point in going further
|
||||||
}
|
}
|
||||||
@@ -129,7 +126,7 @@ func TestRpcConn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
//cgrRpc, err = rpc.Dial("tcp", cfg.RPCGOBListen) //ToDo: Fix with automatic config
|
//cgrRpc, err = rpc.Dial("tcp", cfg.RPCGOBListen) //ToDo: Fix with automatic config
|
||||||
cgrRpc, err = jsonrpc.Dial("tcp", cfg.RPCJSONListen)
|
cgrRpc, err = jsonrpc.Dial("tcp", cgrCfg.RPCJSONListen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Could not connect to CGR GOB-RPC Server: ", err.Error())
|
t.Fatal("Could not connect to CGR GOB-RPC Server: ", err.Error())
|
||||||
}
|
}
|
||||||
@@ -151,8 +148,8 @@ func TestPostCdrs(t *testing.T) {
|
|||||||
utils.ACCOUNT: []string{"1010"}, utils.SUBJECT: []string{"1010"}, utils.ANSWER_TIME: []string{"2013-11-07T08:42:26Z"},
|
utils.ACCOUNT: []string{"1010"}, utils.SUBJECT: []string{"1010"}, utils.ANSWER_TIME: []string{"2013-11-07T08:42:26Z"},
|
||||||
utils.USAGE: []string{"10"}, "field_extr1": []string{"val_extr1"}, "fieldextr2": []string{"valextr2"}}
|
utils.USAGE: []string{"10"}, "field_extr1": []string{"val_extr1"}, "fieldextr2": []string{"valextr2"}}
|
||||||
for _, cdrForm := range []url.Values{cdrForm1, cdrForm2, cdrFormData1} {
|
for _, cdrForm := range []url.Values{cdrForm1, cdrForm2, cdrFormData1} {
|
||||||
cdrForm.Set(utils.CDRSOURCE, engine.TEST_SQL)
|
cdrForm.Set(utils.CDRSOURCE, TEST_SQL)
|
||||||
if _, err := httpClient.PostForm(fmt.Sprintf("http://%s/cgr", cfg.HTTPListen), cdrForm); err != nil {
|
if _, err := httpClient.PostForm(fmt.Sprintf("http://%s/cgr", cgrCfg.HTTPListen), cdrForm); err != nil {
|
||||||
t.Error(err.Error())
|
t.Error(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,10 +171,10 @@ func TestInjectCdrs(t *testing.T) {
|
|||||||
if !*testLocal {
|
if !*testLocal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cgrCdr1 := utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaaaadsafdsaf", "cdrsource": engine.TEST_SQL, utils.CDRHOST: "192.168.1.1", utils.REQTYPE: "rated", utils.DIRECTION: "*out",
|
cgrCdr1 := utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaaaadsafdsaf", "cdrsource": TEST_SQL, utils.CDRHOST: "192.168.1.1", utils.REQTYPE: "rated", utils.DIRECTION: "*out",
|
||||||
utils.TENANT: "cgrates.org", utils.CATEGORY: "call", utils.ACCOUNT: "dan", utils.SUBJECT: "dan", utils.DESTINATION: "+4986517174963",
|
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"}
|
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "10"}
|
||||||
cgrCdr2 := utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "baaaadsafdsaf", "cdrsource": engine.TEST_SQL, utils.CDRHOST: "192.168.1.1", utils.REQTYPE: "rated", utils.DIRECTION: "*out",
|
cgrCdr2 := utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "baaaadsafdsaf", "cdrsource": TEST_SQL, utils.CDRHOST: "192.168.1.1", utils.REQTYPE: "rated", utils.DIRECTION: "*out",
|
||||||
utils.TENANT: "cgrates.org", utils.CATEGORY: "call", utils.ACCOUNT: "dan", utils.SUBJECT: "dan", utils.DESTINATION: "+4986517173964",
|
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"}
|
utils.ANSWER_TIME: "2013-11-07T09:42:26Z", utils.USAGE: "20"}
|
||||||
for _, cdr := range []utils.CgrCdr{cgrCdr1, cgrCdr2} {
|
for _, cdr := range []utils.CgrCdr{cgrCdr1, cgrCdr2} {
|
||||||
@@ -36,6 +36,7 @@ import (
|
|||||||
type Responder struct {
|
type Responder struct {
|
||||||
Bal *balancer2go.Balancer
|
Bal *balancer2go.Balancer
|
||||||
ExitChan chan bool
|
ExitChan chan bool
|
||||||
|
CdrSrv *CDRS
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -128,6 +129,17 @@ func (rs *Responder) GetDerivedChargers(attrs utils.AttrDerivedChargers, dcs *ut
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rs *Responder) ProcessCdr(cdr *utils.StoredCdr, reply *string) error {
|
||||||
|
if rs.CdrSrv == nil {
|
||||||
|
return errors.New("CdrServerNotRunning")
|
||||||
|
}
|
||||||
|
if err := rs.CdrSrv.ProcessCdr(cdr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*reply = utils.OK
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (rs *Responder) FlushCache(arg CallDescriptor, reply *float64) (err error) {
|
func (rs *Responder) FlushCache(arg CallDescriptor, reply *float64) (err error) {
|
||||||
if rs.Bal != nil {
|
if rs.Bal != nil {
|
||||||
*reply, err = rs.callMethod(&arg, "Responder.FlushCache")
|
*reply, err = rs.callMethod(&arg, "Responder.FlushCache")
|
||||||
@@ -287,6 +299,7 @@ type Connector interface {
|
|||||||
RefundIncrements(CallDescriptor, *float64) error
|
RefundIncrements(CallDescriptor, *float64) error
|
||||||
GetMaxSessionTime(CallDescriptor, *float64) error
|
GetMaxSessionTime(CallDescriptor, *float64) error
|
||||||
GetDerivedChargers(utils.AttrDerivedChargers, *utils.DerivedChargers) error
|
GetDerivedChargers(utils.AttrDerivedChargers, *utils.DerivedChargers) error
|
||||||
|
ProcessCdr(*utils.StoredCdr, *string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type RPCClientConnector struct {
|
type RPCClientConnector struct {
|
||||||
@@ -316,3 +329,7 @@ func (rcc *RPCClientConnector) GetMaxSessionTime(cd CallDescriptor, resp *float6
|
|||||||
func (rcc *RPCClientConnector) GetDerivedChargers(attrs utils.AttrDerivedChargers, dcs *utils.DerivedChargers) error {
|
func (rcc *RPCClientConnector) GetDerivedChargers(attrs utils.AttrDerivedChargers, dcs *utils.DerivedChargers) error {
|
||||||
return rcc.Client.Call("ApierV1.GetDerivedChargers", attrs, dcs)
|
return rcc.Client.Call("ApierV1.GetDerivedChargers", attrs, dcs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rcc *RPCClientConnector) ProcessCdr(cdr *utils.StoredCdr, reply *string) error {
|
||||||
|
return rcc.Client.Call("CDRSV1.ProcessCdr", cdr, reply)
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ package general_tests
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/cgrates/cgrates/cdrs"
|
|
||||||
"github.com/cgrates/cgrates/config"
|
"github.com/cgrates/cgrates/config"
|
||||||
|
"github.com/cgrates/cgrates/engine"
|
||||||
"github.com/cgrates/cgrates/sessionmanager"
|
"github.com/cgrates/cgrates/sessionmanager"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -215,12 +215,12 @@ var jsonCdr = []byte(`{"core-uuid":"feef0b51-7fdf-4c4a-878e-aff233752de2","chann
|
|||||||
|
|
||||||
func TestEvCorelate(t *testing.T) {
|
func TestEvCorelate(t *testing.T) {
|
||||||
cfg, _ := config.NewDefaultCGRConfig()
|
cfg, _ := config.NewDefaultCGRConfig()
|
||||||
cdrs.New(nil, nil, cfg) // So we can set the package cfg
|
engine.NewCdrS(nil, nil, cfg) // So we can set the package cfg
|
||||||
answerEv := new(sessionmanager.FSEvent).New(answerEvent)
|
answerEv := new(sessionmanager.FSEvent).New(answerEvent)
|
||||||
if answerEv.GetName() != "CHANNEL_ANSWER" {
|
if answerEv.GetName() != "CHANNEL_ANSWER" {
|
||||||
t.Error("Event not parsed correctly: ", answerEv)
|
t.Error("Event not parsed correctly: ", answerEv)
|
||||||
}
|
}
|
||||||
cdrEv, err := cdrs.NewFSCdr(jsonCdr)
|
cdrEv, err := engine.NewFSCdr(jsonCdr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error loading cdr: %v", err.Error())
|
t.Errorf("Error loading cdr: %v", err.Error())
|
||||||
} else if cdrEv.AsStoredCdr().AccId != "86cfd6e2-dbda-45a3-b59d-f683ec368e8b" {
|
} else if cdrEv.AsStoredCdr().AccId != "86cfd6e2-dbda-45a3-b59d-f683ec368e8b" {
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ go test github.com/cgrates/cgrates/engine -local
|
|||||||
en=$?
|
en=$?
|
||||||
go test github.com/cgrates/cgrates/cdrc -local
|
go test github.com/cgrates/cgrates/cdrc -local
|
||||||
cdrc=$?
|
cdrc=$?
|
||||||
go test github.com/cgrates/cgrates/mediator -local
|
|
||||||
med=$?
|
|
||||||
go test github.com/cgrates/cgrates/config -local
|
go test github.com/cgrates/cgrates/config -local
|
||||||
cfg=$?
|
cfg=$?
|
||||||
go test github.com/cgrates/cgrates/utils -local
|
go test github.com/cgrates/cgrates/utils -local
|
||||||
@@ -20,5 +18,5 @@ utl=$?
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
exit $gen && $ap && $en && $cdrc && $med && $cfg && $utl
|
exit $gen && $ap && $en && $cdrc && $cfg && $utl
|
||||||
|
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
Rating system designed to be used in VoIP Carriers World
|
|
||||||
Copyright (C) 2013 ITsysCOM
|
|
||||||
|
|
||||||
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 <http://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
|
|
||||||
package mediator
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/cgrates/cgrates/config"
|
|
||||||
"github.com/cgrates/cgrates/utils"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FScsvCDR struct {
|
|
||||||
rowData []string // The original row extracted form csv file
|
|
||||||
accIdIdx,
|
|
||||||
subjectIdx,
|
|
||||||
reqtypeIdx,
|
|
||||||
directionIdx,
|
|
||||||
tenantIdx,
|
|
||||||
torIdx,
|
|
||||||
accountIdx,
|
|
||||||
destinationIdx,
|
|
||||||
setupTimeIdx,
|
|
||||||
answerTimeIdx,
|
|
||||||
durationIdx int // Field indexes
|
|
||||||
cgrCfg *config.CGRConfig // CGR Config instance
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFScsvCDR(cdrRow []string, accIdIdx, subjectIdx, reqtypeIdx, directionIdx, tenantIdx, torIdx,
|
|
||||||
accountIdx, destinationIdx, setupTimeIdx, answerTimeIdx, durationIdx int, cfg *config.CGRConfig) (*FScsvCDR, error) {
|
|
||||||
fscdr := FScsvCDR{cdrRow, accIdIdx, subjectIdx, reqtypeIdx, directionIdx, tenantIdx,
|
|
||||||
torIdx, accountIdx, destinationIdx, setupTimeIdx, answerTimeIdx, durationIdx, cfg}
|
|
||||||
return &fscdr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetCgrId() string {
|
|
||||||
return utils.Sha1(self.rowData[self.accIdIdx], self.rowData[self.setupTimeIdx])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetAccId() string {
|
|
||||||
return self.rowData[self.accIdIdx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetCdrHost() string {
|
|
||||||
return utils.LOCALHOST // ToDo: Maybe extract dynamically the external IP address here
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetDirection() string {
|
|
||||||
return "*out"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetSubject() string {
|
|
||||||
return self.rowData[self.subjectIdx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetAccount() string {
|
|
||||||
return self.rowData[self.accountIdx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetDestination() string {
|
|
||||||
return self.rowData[self.destinationIdx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetTOR() string {
|
|
||||||
return self.rowData[self.torIdx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetTenant() string {
|
|
||||||
return self.rowData[self.tenantIdx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetReqType() string {
|
|
||||||
if self.reqtypeIdx == -1 {
|
|
||||||
return self.cgrCfg.DefaultReqType
|
|
||||||
}
|
|
||||||
return self.rowData[self.reqtypeIdx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetAnswerTime() (time.Time, error) {
|
|
||||||
return time.Parse("2006-01-02 15:04:05", self.rowData[self.answerTimeIdx])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetDuration() int64 {
|
|
||||||
dur, _ := strconv.ParseInt(self.rowData[self.durationIdx], 0, 64)
|
|
||||||
return dur
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FScsvCDR) GetExtraFields() map[string]string {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Real-time Charging System for Telecom & ISP environments
|
Real-time Charging System for Telecom & ISP environments
|
||||||
Copyright (C) 2012-2014 ITsysCOM GmbH
|
Copyright (C) ITsysCOM GmbH
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
8
test.sh
8
test.sh
@@ -4,10 +4,8 @@ go test -i github.com/cgrates/cgrates/engine
|
|||||||
go test -i github.com/cgrates/cgrates/sessionmanager
|
go test -i github.com/cgrates/cgrates/sessionmanager
|
||||||
go test -i github.com/cgrates/cgrates/config
|
go test -i github.com/cgrates/cgrates/config
|
||||||
go test -i github.com/cgrates/cgrates/cmd/cgr-engine
|
go test -i github.com/cgrates/cgrates/cmd/cgr-engine
|
||||||
go test -i github.com/cgrates/cgrates/mediator
|
|
||||||
go test -i github.com/cgrates/fsock
|
go test -i github.com/cgrates/fsock
|
||||||
go test -i github.com/cgrates/cgrates/cache2go
|
go test -i github.com/cgrates/cgrates/cache2go
|
||||||
go test -i github.com/cgrates/cgrates/cdrs
|
|
||||||
go test -i github.com/cgrates/cgrates/cdrc
|
go test -i github.com/cgrates/cgrates/cdrc
|
||||||
go test -i github.com/cgrates/cgrates/utils
|
go test -i github.com/cgrates/cgrates/utils
|
||||||
go test -i github.com/cgrates/cgrates/history
|
go test -i github.com/cgrates/cgrates/history
|
||||||
@@ -23,10 +21,6 @@ go test github.com/cgrates/cgrates/config
|
|||||||
cfg=$?
|
cfg=$?
|
||||||
go test github.com/cgrates/cgrates/cmd/cgr-engine
|
go test github.com/cgrates/cgrates/cmd/cgr-engine
|
||||||
cr=$?
|
cr=$?
|
||||||
go test github.com/cgrates/cgrates/mediator
|
|
||||||
md=$?
|
|
||||||
go test github.com/cgrates/cgrates/cdrs
|
|
||||||
cdrs=$?
|
|
||||||
go test github.com/cgrates/cgrates/cdrc
|
go test github.com/cgrates/cgrates/cdrc
|
||||||
cdrcs=$?
|
cdrcs=$?
|
||||||
go test github.com/cgrates/cgrates/utils
|
go test github.com/cgrates/cgrates/utils
|
||||||
@@ -41,4 +35,4 @@ go test github.com/cgrates/cgrates/cdre
|
|||||||
cdre=$?
|
cdre=$?
|
||||||
|
|
||||||
|
|
||||||
exit $en && $gt && $sm && $cfg && $bl && $cr && $md && $cdrs && $cdrc && $fs && $ut && $hs && $c2g && $cdre
|
exit $en && $gt && $sm && $cfg && $bl && $cr && $cdrc && $fs && $ut && $hs && $c2g && $cdre
|
||||||
|
|||||||
281
utils/consts.go
281
utils/consts.go
@@ -1,134 +1,159 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
const (
|
const (
|
||||||
VERSION = "0.9.1rc5"
|
VERSION = "0.9.1rc5"
|
||||||
POSTGRES = "postgres"
|
POSTGRES = "postgres"
|
||||||
MYSQL = "mysql"
|
MYSQL = "mysql"
|
||||||
MONGO = "mongo"
|
MONGO = "mongo"
|
||||||
REDIS = "redis"
|
REDIS = "redis"
|
||||||
LOCALHOST = "127.0.0.1"
|
LOCALHOST = "127.0.0.1"
|
||||||
FSCDR_FILE_CSV = "freeswitch_file_csv"
|
FSCDR_FILE_CSV = "freeswitch_file_csv"
|
||||||
FSCDR_HTTP_JSON = "freeswitch_http_json"
|
FSCDR_HTTP_JSON = "freeswitch_http_json"
|
||||||
NOT_IMPLEMENTED = "not implemented"
|
NOT_IMPLEMENTED = "not implemented"
|
||||||
PREPAID = "prepaid"
|
PREPAID = "prepaid"
|
||||||
POSTPAID = "postpaid"
|
POSTPAID = "postpaid"
|
||||||
PSEUDOPREPAID = "pseudoprepaid"
|
PSEUDOPREPAID = "pseudoprepaid"
|
||||||
RATED = "rated"
|
RATED = "rated"
|
||||||
ERR_NOT_IMPLEMENTED = "NOT_IMPLEMENTED"
|
ERR_NOT_IMPLEMENTED = "NOT_IMPLEMENTED"
|
||||||
ERR_SERVER_ERROR = "SERVER_ERROR"
|
ERR_SERVER_ERROR = "SERVER_ERROR"
|
||||||
ERR_NOT_FOUND = "NOT_FOUND"
|
ERR_NOT_FOUND = "NOT_FOUND"
|
||||||
ERR_MANDATORY_IE_MISSING = "MANDATORY_IE_MISSING"
|
ERR_MANDATORY_IE_MISSING = "MANDATORY_IE_MISSING"
|
||||||
ERR_EXISTS = "EXISTS"
|
ERR_EXISTS = "EXISTS"
|
||||||
ERR_BROKEN_REFERENCE = "BROKEN_REFERENCE"
|
ERR_BROKEN_REFERENCE = "BROKEN_REFERENCE"
|
||||||
ERR_PARSER_ERROR = "PARSER_ERROR"
|
ERR_PARSER_ERROR = "PARSER_ERROR"
|
||||||
TBL_TP_TIMINGS = "tp_timings"
|
TBL_TP_TIMINGS = "tp_timings"
|
||||||
TBL_TP_DESTINATIONS = "tp_destinations"
|
TBL_TP_DESTINATIONS = "tp_destinations"
|
||||||
TBL_TP_RATES = "tp_rates"
|
TBL_TP_RATES = "tp_rates"
|
||||||
TBL_TP_DESTINATION_RATES = "tp_destination_rates"
|
TBL_TP_DESTINATION_RATES = "tp_destination_rates"
|
||||||
TBL_TP_RATING_PLANS = "tp_rating_plans"
|
TBL_TP_RATING_PLANS = "tp_rating_plans"
|
||||||
TBL_TP_RATE_PROFILES = "tp_rating_profiles"
|
TBL_TP_RATE_PROFILES = "tp_rating_profiles"
|
||||||
TBL_TP_SHARED_GROUPS = "tp_shared_groups"
|
TBL_TP_SHARED_GROUPS = "tp_shared_groups"
|
||||||
TBL_TP_LCRS = "tp_lcr_rules"
|
TBL_TP_LCRS = "tp_lcr_rules"
|
||||||
TBL_TP_ACTIONS = "tp_actions"
|
TBL_TP_ACTIONS = "tp_actions"
|
||||||
TBL_TP_ACTION_PLANS = "tp_action_plans"
|
TBL_TP_ACTION_PLANS = "tp_action_plans"
|
||||||
TBL_TP_ACTION_TRIGGERS = "tp_action_triggers"
|
TBL_TP_ACTION_TRIGGERS = "tp_action_triggers"
|
||||||
TBL_TP_ACCOUNT_ACTIONS = "tp_account_actions"
|
TBL_TP_ACCOUNT_ACTIONS = "tp_account_actions"
|
||||||
TBL_CDRS_PRIMARY = "cdrs_primary"
|
TBL_CDRS_PRIMARY = "cdrs_primary"
|
||||||
TBL_CDRS_EXTRA = "cdrs_extra"
|
TBL_CDRS_EXTRA = "cdrs_extra"
|
||||||
TBL_COST_DETAILS = "cost_details"
|
TBL_COST_DETAILS = "cost_details"
|
||||||
TBL_RATED_CDRS = "rated_cdrs"
|
TBL_RATED_CDRS = "rated_cdrs"
|
||||||
TIMINGS_CSV = "Timings.csv"
|
TIMINGS_CSV = "Timings.csv"
|
||||||
DESTINATIONS_CSV = "Destinations.csv"
|
DESTINATIONS_CSV = "Destinations.csv"
|
||||||
RATES_CSV = "Rates.csv"
|
RATES_CSV = "Rates.csv"
|
||||||
DESTINATION_RATES_CSV = "DestinationRates.csv"
|
DESTINATION_RATES_CSV = "DestinationRates.csv"
|
||||||
RATING_PLANS_CSV = "RatingPlans.csv"
|
RATING_PLANS_CSV = "RatingPlans.csv"
|
||||||
RATING_PROFILES_CSV = "RatingProfiles.csv"
|
RATING_PROFILES_CSV = "RatingProfiles.csv"
|
||||||
SHARED_GROUPS_CSV = "SharedGroups.csv"
|
SHARED_GROUPS_CSV = "SharedGroups.csv"
|
||||||
LCRS_CSV = "LCRRules.csv"
|
LCRS_CSV = "LCRRules.csv"
|
||||||
ACTIONS_CSV = "Actions.csv"
|
ACTIONS_CSV = "Actions.csv"
|
||||||
ACTION_PLANS_CSV = "ActionPlans.csv"
|
ACTION_PLANS_CSV = "ActionPlans.csv"
|
||||||
ACTION_TRIGGERS_CSV = "ActionTriggers.csv"
|
ACTION_TRIGGERS_CSV = "ActionTriggers.csv"
|
||||||
ACCOUNT_ACTIONS_CSV = "AccountActions.csv"
|
ACCOUNT_ACTIONS_CSV = "AccountActions.csv"
|
||||||
DERIVED_CHARGERS_CSV = "DerivedChargers.csv"
|
DERIVED_CHARGERS_CSV = "DerivedChargers.csv"
|
||||||
TIMINGS_NRCOLS = 6
|
TIMINGS_NRCOLS = 6
|
||||||
DESTINATIONS_NRCOLS = 2
|
DESTINATIONS_NRCOLS = 2
|
||||||
RATES_NRCOLS = 6
|
RATES_NRCOLS = 6
|
||||||
DESTINATION_RATES_NRCOLS = 5
|
DESTINATION_RATES_NRCOLS = 5
|
||||||
DESTRATE_TIMINGS_NRCOLS = 4
|
DESTRATE_TIMINGS_NRCOLS = 4
|
||||||
RATE_PROFILES_NRCOLS = 7
|
RATE_PROFILES_NRCOLS = 7
|
||||||
SHARED_GROUPS_NRCOLS = 4
|
SHARED_GROUPS_NRCOLS = 4
|
||||||
LCRS_NRCOLS = 9
|
LCRS_NRCOLS = 9
|
||||||
ACTIONS_NRCOLS = 12
|
ACTIONS_NRCOLS = 12
|
||||||
ACTION_PLANS_NRCOLS = 4
|
ACTION_PLANS_NRCOLS = 4
|
||||||
ACTION_TRIGGERS_NRCOLS = 9
|
ACTION_TRIGGERS_NRCOLS = 9
|
||||||
ACCOUNT_ACTIONS_NRCOLS = 5
|
ACCOUNT_ACTIONS_NRCOLS = 5
|
||||||
DERIVED_CHARGERS_NRCOLS = 17
|
DERIVED_CHARGERS_NRCOLS = 17
|
||||||
ROUNDING_UP = "*up"
|
ROUNDING_UP = "*up"
|
||||||
ROUNDING_MIDDLE = "*middle"
|
ROUNDING_MIDDLE = "*middle"
|
||||||
ROUNDING_DOWN = "*down"
|
ROUNDING_DOWN = "*down"
|
||||||
ANY = "*any"
|
ANY = "*any"
|
||||||
COMMENT_CHAR = '#'
|
COMMENT_CHAR = '#'
|
||||||
CSV_SEP = ','
|
CSV_SEP = ','
|
||||||
FALLBACK_SEP = ';'
|
FALLBACK_SEP = ';'
|
||||||
INFIELD_SEP = ";"
|
INFIELD_SEP = ";"
|
||||||
FIELDS_SEP = ","
|
FIELDS_SEP = ","
|
||||||
REGEXP_PREFIX = "~"
|
REGEXP_PREFIX = "~"
|
||||||
JSON = "json"
|
JSON = "json"
|
||||||
GOB = "gob"
|
GOB = "gob"
|
||||||
MSGPACK = "msgpack"
|
MSGPACK = "msgpack"
|
||||||
CSV_LOAD = "CSVLOAD"
|
CSV_LOAD = "CSVLOAD"
|
||||||
CGRID = "cgrid"
|
CGRID = "cgrid"
|
||||||
ORDERID = "orderid"
|
ORDERID = "orderid"
|
||||||
ACCID = "accid"
|
ACCID = "accid"
|
||||||
CDRHOST = "cdrhost"
|
CDRHOST = "cdrhost"
|
||||||
CDRSOURCE = "cdrsource"
|
CDRSOURCE = "cdrsource"
|
||||||
REQTYPE = "reqtype"
|
REQTYPE = "reqtype"
|
||||||
DIRECTION = "direction"
|
DIRECTION = "direction"
|
||||||
TENANT = "tenant"
|
TENANT = "tenant"
|
||||||
CATEGORY = "category"
|
CATEGORY = "category"
|
||||||
ACCOUNT = "account"
|
ACCOUNT = "account"
|
||||||
SUBJECT = "subject"
|
SUBJECT = "subject"
|
||||||
DESTINATION = "destination"
|
DESTINATION = "destination"
|
||||||
SETUP_TIME = "setup_time"
|
SETUP_TIME = "setup_time"
|
||||||
ANSWER_TIME = "answer_time"
|
ANSWER_TIME = "answer_time"
|
||||||
USAGE = "usage"
|
USAGE = "usage"
|
||||||
MEDI_RUNID = "mediation_runid"
|
MEDI_RUNID = "mediation_runid"
|
||||||
RATED_ACCOUNT = "rated_account"
|
RATED_ACCOUNT = "rated_account"
|
||||||
RATED_SUBJECT = "rated_subject"
|
RATED_SUBJECT = "rated_subject"
|
||||||
COST = "cost"
|
COST = "cost"
|
||||||
DEFAULT_RUNID = "default"
|
DEFAULT_RUNID = "default"
|
||||||
STATIC_VALUE_PREFIX = "^"
|
STATIC_VALUE_PREFIX = "^"
|
||||||
CSV = "csv"
|
CSV = "csv"
|
||||||
CDRE_DRYRUN = "dry_run"
|
CDRE_DRYRUN = "dry_run"
|
||||||
INTERNAL = "internal"
|
INTERNAL = "internal"
|
||||||
ZERO_RATING_SUBJECT_PREFIX = "*zero"
|
ZERO_RATING_SUBJECT_PREFIX = "*zero"
|
||||||
OK = "OK"
|
OK = "OK"
|
||||||
CDRE_FIXED_WIDTH = "fwv"
|
CDRE_FIXED_WIDTH = "fwv"
|
||||||
XML_PROFILE_PREFIX = "*xml:"
|
XML_PROFILE_PREFIX = "*xml:"
|
||||||
CDRE = "cdre"
|
CDRE = "cdre"
|
||||||
CDRC = "cdrc"
|
CDRC = "cdrc"
|
||||||
MASK_CHAR = "*"
|
MASK_CHAR = "*"
|
||||||
CONCATENATED_KEY_SEP = ":"
|
CONCATENATED_KEY_SEP = ":"
|
||||||
META_DEFAULT = "*default"
|
META_DEFAULT = "*default"
|
||||||
FORKED_CDR = "forked_cdr"
|
FORKED_CDR = "forked_cdr"
|
||||||
UNIT_TEST = "UNIT_TEST"
|
UNIT_TEST = "UNIT_TEST"
|
||||||
HDR_VAL_SEP = "/"
|
HDR_VAL_SEP = "/"
|
||||||
MONETARY = "*monetary"
|
MONETARY = "*monetary"
|
||||||
SMS = "*sms"
|
SMS = "*sms"
|
||||||
DATA = "*data"
|
DATA = "*data"
|
||||||
VOICE = "*voice"
|
VOICE = "*voice"
|
||||||
TOR = "tor"
|
TOR = "tor"
|
||||||
HOURS = "hours"
|
HOURS = "hours"
|
||||||
MINUTES = "minutes"
|
MINUTES = "minutes"
|
||||||
NANOSECONDS = "nanoseconds"
|
NANOSECONDS = "nanoseconds"
|
||||||
SECONDS = "seconds"
|
SECONDS = "seconds"
|
||||||
OUT = "*out"
|
OUT = "*out"
|
||||||
CDR_IMPORT = "cdr_import"
|
CDR_IMPORT = "cdr_import"
|
||||||
CDR_EXPORT = "cdr_export"
|
CDR_EXPORT = "cdr_export"
|
||||||
CDRFIELD = "cdrfield"
|
CDRFIELD = "cdrfield"
|
||||||
ASR = "ASR"
|
ASR = "ASR"
|
||||||
ACD = "ACD"
|
ACD = "ACD"
|
||||||
FILTER_REGEXP_TPL = "$1$2$3$4$5"
|
FILTER_REGEXP_TPL = "$1$2$3$4$5"
|
||||||
|
ACTION_TIMING_PREFIX = "apl_"
|
||||||
|
RATING_PLAN_PREFIX = "rpl_"
|
||||||
|
RATING_PROFILE_PREFIX = "rpf_"
|
||||||
|
RP_ALIAS_PREFIX = "ral_"
|
||||||
|
ACC_ALIAS_PREFIX = "aal_"
|
||||||
|
ACTION_PREFIX = "act_"
|
||||||
|
SHARED_GROUP_PREFIX = "shg_"
|
||||||
|
ACCOUNT_PREFIX = "ubl_"
|
||||||
|
DESTINATION_PREFIX = "dst_"
|
||||||
|
LCR_PREFIX = "lcr_"
|
||||||
|
DERIVEDCHARGERS_PREFIX = "dcs_"
|
||||||
|
TEMP_DESTINATION_PREFIX = "tmp_"
|
||||||
|
LOG_CALL_COST_PREFIX = "cco_"
|
||||||
|
LOG_ACTION_TIMMING_PREFIX = "ltm_"
|
||||||
|
LOG_ACTION_TRIGGER_PREFIX = "ltr_"
|
||||||
|
LOG_ERR = "ler_"
|
||||||
|
LOG_CDR = "cdr_"
|
||||||
|
LOG_MEDIATED_CDR = "mcd_"
|
||||||
|
SESSION_MANAGER_SOURCE = "SMR"
|
||||||
|
MEDIATOR_SOURCE = "MED"
|
||||||
|
SCHED_SOURCE = "SCH"
|
||||||
|
RATER_SOURCE = "RAT"
|
||||||
|
CREATE_CDRS_TABLES_SQL = "create_cdrs_tables.sql"
|
||||||
|
CREATE_TARIFFPLAN_TABLES_SQL = "create_tariffplan_tables.sql"
|
||||||
|
TEST_SQL = "TEST_SQL"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
Reference in New Issue
Block a user