Default fields fix for cdrs.processCdr

This commit is contained in:
DanB
2015-08-22 18:31:34 +02:00
parent 29a5b1e927
commit cf3cdc8530
4 changed files with 67 additions and 15 deletions

View File

@@ -5,8 +5,15 @@ cgrates.org,1001,Cli,+4986517174963
cgrates.org,1001,Account,1001
cgrates.org,1001,Subject,1001
cgrates.org,1001,Uuid,388539dfd4f5cefee8f488b78c6c244b9e19138e
cgrates.org,1001,ReqType,*prepaid
cgrates.org,1002,SysUserName,rif
cgrates.org,1002,RifAttr,RifVal
cgrates.org,1002,Account,1002
cgrates.org,1002,Subject,1002
cgrates.org,1002,Uuid,27f37edec0670fa34cf79076b80ef5021e39c5b5
cgrates.org,1004,SysUserName,danb4
cgrates.org,1004,SysPassword,hisPass321
cgrates.org,1004,Cli,+4986517174964
cgrates.org,1004,Account,1004
cgrates.org,1004,Subject,1004
cgrates.org,1004,ReqType,*rated
1 #Tenant[0] UserName[1] AttributeName[2] AttributeValue[3]
5 cgrates.org 1001 Account 1001
6 cgrates.org 1001 Subject 1001
7 cgrates.org 1001 Uuid 388539dfd4f5cefee8f488b78c6c244b9e19138e
8 cgrates.org 1001 ReqType *prepaid
9 cgrates.org 1002 SysUserName rif
10 cgrates.org 1002 RifAttr RifVal
11 cgrates.org 1002 Account 1002
12 cgrates.org 1002 Subject 1002
13 cgrates.org 1002 Uuid 27f37edec0670fa34cf79076b80ef5021e39c5b5
14 cgrates.org 1004 SysUserName danb4
15 cgrates.org 1004 SysPassword hisPass321
16 cgrates.org 1004 Cli +4986517174964
17 cgrates.org 1004 Account 1004
18 cgrates.org 1004 Subject 1004
19 cgrates.org 1004 ReqType *rated

View File

@@ -148,9 +148,22 @@ func (self *CdrServer) RateCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqT
// Returns error if not able to properly store the CDR, mediation is async since we can always recover offline
func (self *CdrServer) processCdr(storedCdr *StoredCdr) (err error) {
if storedCdr.Direction == "" {
storedCdr.Direction = utils.OUT
}
if storedCdr.ReqType == "" {
storedCdr.ReqType = self.cgrCfg.DefaultReqType
}
if storedCdr.Tenant == "" {
storedCdr.Tenant = self.cgrCfg.DefaultTenant
}
if storedCdr.Category == "" {
storedCdr.Category = self.cgrCfg.DefaultCategory
}
if storedCdr.Subject == "" { // Use account information as rating subject if missing
storedCdr.Subject = storedCdr.Account
}
if upData, err := LoadUserProfile(storedCdr, "ExtraFields"); err != nil {
return err
} else {

View File

@@ -33,13 +33,7 @@ const (
// Freswitch event property names
FS_CDR_MAP = "variables"
FS_DIRECTION = "direction"
FS_SUBJECT = "cgr_subject"
FS_ACCOUNT = "cgr_account"
FS_DESTINATION = "cgr_destination"
FS_REQTYPE = "cgr_reqtype" //prepaid or postpaid
FS_CATEGORY = "cgr_category"
FS_UUID = "uuid" // -Unique ID for this call leg
FS_CSTMID = "cgr_tenant"
FS_CALL_DEST_NR = "dialed_extension"
FS_PARK_TIME = "start_epoch"
FS_SETUP_TIME = "start_epoch"
@@ -125,20 +119,19 @@ func (fsCdr FSCdr) searchExtraField(field string, body map[string]interface{}) (
}
func (fsCdr FSCdr) AsStoredCdr(timezone string) *StoredCdr {
storCdr := new(StoredCdr)
storCdr.CgrId = fsCdr.getCgrId(timezone)
storCdr.TOR = utils.VOICE
storCdr.AccId = fsCdr.vars[FS_UUID]
storCdr.CdrHost = fsCdr.vars[FS_IP]
storCdr.CdrSource = FS_CDR_SOURCE
storCdr.ReqType = utils.FirstNonEmpty(fsCdr.vars[FS_REQTYPE], fsCdr.cgrCfg.DefaultReqType)
storCdr.ReqType = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_REQTYPE], fsCdr.cgrCfg.DefaultReqType)
storCdr.Direction = "*out"
storCdr.Tenant = utils.FirstNonEmpty(fsCdr.vars[FS_CSTMID], fsCdr.cgrCfg.DefaultTenant)
storCdr.Category = utils.FirstNonEmpty(fsCdr.vars[FS_CATEGORY], fsCdr.cgrCfg.DefaultCategory)
storCdr.Account = utils.FirstNonEmpty(fsCdr.vars[FS_ACCOUNT], fsCdr.vars[FS_USERNAME])
storCdr.Subject = utils.FirstNonEmpty(fsCdr.vars[FS_SUBJECT], fsCdr.vars[FS_USERNAME])
storCdr.Destination = utils.FirstNonEmpty(fsCdr.vars[FS_DESTINATION], fsCdr.vars[FS_CALL_DEST_NR], fsCdr.vars[FS_SIP_REQUSER])
storCdr.Tenant = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_TENANT], fsCdr.cgrCfg.DefaultTenant)
storCdr.Category = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_CATEGORY], fsCdr.cgrCfg.DefaultCategory)
storCdr.Account = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_ACCOUNT], fsCdr.vars[FS_USERNAME])
storCdr.Subject = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_SUBJECT], fsCdr.vars[utils.CGR_ACCOUNT], fsCdr.vars[FS_USERNAME])
storCdr.Destination = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_DESTINATION], fsCdr.vars[FS_CALL_DEST_NR], fsCdr.vars[FS_SIP_REQUSER])
storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME], timezone) // Not interested to process errors, should do them if necessary in a previous step
pddStr := utils.FirstNonEmpty(fsCdr.vars[FS_PROGRESS_MEDIAMSEC], fsCdr.vars[FS_PROGRESSMS])
pddStr = pddStr + "ms"

View File

@@ -118,7 +118,7 @@ func TestTutLocalCacheStats(t *testing.T) {
var rcvStats *utils.CacheStats
expectedStats := &utils.CacheStats{Destinations: 4, RatingPlans: 3, RatingProfiles: 8, Actions: 7, SharedGroups: 1, Aliases: 3,
DerivedChargers: 1, LcrProfiles: 5, CdrStats: 6, Users: 2}
DerivedChargers: 1, LcrProfiles: 5, CdrStats: 6, Users: 3}
var args utils.AttrCacheStats
if err := tutLocalRpc.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil {
t.Error("Got error on ApierV1.GetCacheStats: ", err.Error())
@@ -190,7 +190,7 @@ func TestTutLocalGetUsers(t *testing.T) {
var users engine.UserProfiles
if err := tutLocalRpc.Call("UsersV1.GetUsers", engine.UserProfile{}, &users); err != nil {
t.Error("Got error on UsersV1.GetUsers: ", err.Error())
} else if len(users) != 2 {
} else if len(users) != 3 {
t.Error("Calling UsersV1.GetUsers got users:", len(users))
}
}
@@ -554,6 +554,45 @@ func TestTutLocalProcessExternalCdr(t *testing.T) {
}
}
// Test CDR from external sources
func TestTutLocalProcessExternalCdrUP(t *testing.T) {
if !*testLocal {
return
}
cdr := &engine.ExternalCdr{TOR: utils.VOICE,
AccId: "testextcdr2", CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, Direction: utils.OUT,
ReqType: utils.USERS, Tenant: utils.USERS, Account: utils.USERS, Destination: "1001", Supplier: "SUPPL1",
SetupTime: "2014-08-04T13:00:00Z", AnswerTime: "2014-08-04T13:00:07Z",
Usage: "2", Pdd: "0.2", DisconnectCause: "NORMAL_DISCONNECT",
ExtraFields: map[string]string{"Cli": "+4986517174964", "fieldextr2": "valextr2", "SysUserName": utils.USERS},
}
var reply string
if err := tutLocalRpc.Call("CdrsV2.ProcessExternalCdr", cdr, &reply); err != nil {
t.Error("Unexpected error: ", err.Error())
} else if reply != utils.OK {
t.Error("Unexpected reply received: ", reply)
}
eCdr := &engine.ExternalCdr{CgrId: "63a8d2bfeca2cfb790826c3ec461696d6574cfde", OrderId: 2,
TOR: utils.VOICE,
AccId: "testextcdr2", CdrHost: "192.168.1.1", CdrSource: utils.UNIT_TEST, ReqType: utils.META_RATED, Direction: utils.OUT,
Tenant: "cgrates.org", Category: "call", Account: "1004", Subject: "1004", Destination: "1001", Supplier: "SUPPL1",
SetupTime: time.Date(2014, 8, 4, 13, 0, 0, 0, time.UTC).Local().Format(time.RFC3339), AnswerTime: time.Date(2014, 8, 4, 13, 0, 7, 0, time.UTC).Local().Format(time.RFC3339),
Usage: "2", Pdd: "0.2", DisconnectCause: "NORMAL_DISCONNECT",
ExtraFields: map[string]string{"Cli": "+4986517174964", "fieldextr2": "valextr2", "SysUserName": "danb4"},
MediationRunId: utils.DEFAULT_RUNID, Cost: 1}
var cdrs []*engine.ExternalCdr
req := utils.RpcCdrsFilter{RunIds: []string{utils.META_DEFAULT}, Accounts: []string{"1004"}, DestPrefixes: []string{"1001"}}
if err := tutLocalRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil {
t.Error("Unexpected error: ", err.Error())
} else if len(cdrs) != 1 {
t.Error("Unexpected number of CDRs returned: ", len(cdrs))
} else {
if !reflect.DeepEqual(eCdr, cdrs[0]) {
t.Errorf("Expecting: %+v, received: %+v", eCdr, cdrs[0])
}
}
}
// Make sure queueids were created
func TestTutFsCallsCdrStats(t *testing.T) {
if !*testLocal {