SM-FreeSWITCH config change, cdr_extra_fields -> extra_fields, using them now also in auth and lcr requests, fixes #150

This commit is contained in:
DanB
2015-08-20 09:13:10 +02:00
parent d782bb9bdb
commit 8ddf45f64b
9 changed files with 42 additions and 43 deletions

View File

@@ -197,7 +197,7 @@ const CGRATES_CFG_JSON = `
"cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
"reconnects": 5, // number of reconnect attempts to rater or cdrs
"create_cdr": false, // create CDR out of events and sends them to CDRS component
"cdr_extra_fields": [], // extra fields to store in CDRs when creating them
"extra_fields": [], // extra fields to store in auth/CDRs when creating them
"debit_interval": "10s", // interval to perform debits on.
"min_call_duration": "0s", // only authorize calls with allowed duration higher than this
"max_call_duration": "3h", // maximum call duration a prepaid call can last

View File

@@ -324,7 +324,7 @@ func TestSmFsJsonCfg(t *testing.T) {
Cdrs: utils.StringPointer("internal"),
Reconnects: utils.IntPointer(5),
Create_cdr: utils.BoolPointer(false),
Cdr_extra_fields: utils.StringSlicePointer([]string{}),
Extra_fields: utils.StringSlicePointer([]string{}),
Debit_interval: utils.StringPointer("10s"),
Min_call_duration: utils.StringPointer("0s"),
Max_call_duration: utils.StringPointer("3h"),

View File

@@ -158,7 +158,7 @@ type SmFsJsonCfg struct {
Cdrs *string
Reconnects *int
Create_cdr *bool
Cdr_extra_fields *[]string
Extra_fields *[]string
Debit_interval *string
Min_call_duration *string
Max_call_duration *string

View File

@@ -61,7 +61,7 @@ type SmFsConfig struct {
Cdrs string
Reconnects int
CreateCdr bool
CdrExtraFields []*utils.RSRField
ExtraFields []*utils.RSRField
DebitInterval time.Duration
MinCallDuration time.Duration
MaxCallDuration time.Duration
@@ -94,8 +94,8 @@ func (self *SmFsConfig) loadFromJsonCfg(jsnCfg *SmFsJsonCfg) error {
if jsnCfg.Create_cdr != nil {
self.CreateCdr = *jsnCfg.Create_cdr
}
if jsnCfg.Cdr_extra_fields != nil {
if self.CdrExtraFields, err = utils.ParseRSRFieldsFromSlice(*jsnCfg.Cdr_extra_fields); err != nil {
if jsnCfg.Extra_fields != nil {
if self.ExtraFields, err = utils.ParseRSRFieldsFromSlice(*jsnCfg.Extra_fields); err != nil {
return err
}
}

View File

@@ -57,6 +57,7 @@ type LcrRequest struct {
SetupTime string
Duration string
IgnoreErrors bool
ExtraFields map[string]string
*utils.Paginator
}
@@ -90,7 +91,7 @@ func (self *LcrRequest) AsCallDescriptor(timezone string) (*CallDescriptor, erro
} else if callDur, err = utils.ParseDurationWithSecs(self.Duration); err != nil {
return nil, err
}
return &CallDescriptor{
cd := &CallDescriptor{
Direction: self.Direction,
Tenant: self.Tenant,
Category: self.Category,
@@ -99,7 +100,14 @@ func (self *LcrRequest) AsCallDescriptor(timezone string) (*CallDescriptor, erro
Destination: self.Destination,
TimeStart: timeStart,
TimeEnd: timeStart.Add(callDur),
}, nil
}
if self.ExtraFields != nil {
cd.ExtraFields = make(map[string]string)
}
for key, val := range self.ExtraFields {
cd.ExtraFields[key] = val
}
return cd, nil
}
// A LCR reply, used in APIer and SM where we need to expose it

View File

@@ -42,7 +42,7 @@ const (
ACCOUNT = "variable_" + utils.CGR_ACCOUNT
DESTINATION = "variable_" + utils.CGR_DESTINATION
REQTYPE = "variable_" + utils.CGR_REQTYPE //prepaid or postpaid
Category = "variable_" + utils.CGR_CATEGORY
CATEGORY = "variable_" + utils.CGR_CATEGORY
VAR_CGR_SUPPLIER = "variable_" + utils.CGR_SUPPLIER
UUID = "Unique-ID" // -Unique ID for this call leg
CSTMID = "variable_" + utils.CGR_TENANT
@@ -101,30 +101,27 @@ func (fsev FSEvent) GetDirection(fieldName string) string {
//TODO: implement direction
return utils.OUT
}
func (fsev FSEvent) GetSubject(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
} else if fieldName == utils.META_DEFAULT {
return utils.FirstNonEmpty(fsev[SUBJECT], fsev[USERNAME])
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[SUBJECT], fsev[USERNAME])
}
// Account calling
func (fsev FSEvent) GetAccount(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
} else if fieldName == utils.META_DEFAULT {
return utils.FirstNonEmpty(fsev[ACCOUNT], fsev[USERNAME])
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[ACCOUNT], fsev[USERNAME])
}
// Rating subject being charged
func (fsev FSEvent) GetSubject(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[SUBJECT], fsev.GetAccount(fieldName))
}
// Charging destination number
func (fsev FSEvent) GetDestination(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
} else if fieldName == utils.META_DEFAULT {
return utils.FirstNonEmpty(fsev[DESTINATION], fsev[CALL_DEST_NR], fsev[SIP_REQ_USER])
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[DESTINATION], fsev[CALL_DEST_NR], fsev[SIP_REQ_USER])
}
@@ -133,18 +130,14 @@ func (fsev FSEvent) GetDestination(fieldName string) string {
func (fsev FSEvent) GetCallDestNr(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
} else if fieldName == utils.META_DEFAULT {
return utils.FirstNonEmpty(fsev[CALL_DEST_NR], fsev[SIP_REQ_USER])
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[CALL_DEST_NR], fsev[SIP_REQ_USER])
}
func (fsev FSEvent) GetCategory(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
} else if fieldName == utils.META_DEFAULT {
return utils.FirstNonEmpty(fsev[Category], config.CgrConfig().DefaultCategory)
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[Category], config.CgrConfig().DefaultCategory)
return utils.FirstNonEmpty(fsev[fieldName], fsev[CATEGORY], config.CgrConfig().DefaultCategory)
}
func (fsev FSEvent) GetCgrId(timezone string) string {
setupTime, _ := fsev.GetSetupTime(utils.META_DEFAULT, timezone)
@@ -159,8 +152,6 @@ func (fsev FSEvent) GetSessionIds() []string {
func (fsev FSEvent) GetTenant(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
} else if fieldName == utils.META_DEFAULT {
return utils.FirstNonEmpty(fsev[CSTMID], config.CgrConfig().DefaultTenant)
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[CSTMID], config.CgrConfig().DefaultTenant)
}
@@ -173,15 +164,13 @@ func (fsev FSEvent) GetReqType(fieldName string) string {
}
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
} else if fieldName == utils.META_DEFAULT {
return utils.FirstNonEmpty(fsev[REQTYPE], reqTypeDetected, config.CgrConfig().DefaultReqType)
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[REQTYPE], reqTypeDetected, config.CgrConfig().DefaultReqType)
}
func (fsev FSEvent) MissingParameter() bool {
return strings.TrimSpace(fsev.GetDirection(utils.META_DEFAULT)) == "" ||
strings.TrimSpace(fsev.GetSubject(utils.META_DEFAULT)) == "" ||
strings.TrimSpace(fsev.GetAccount(utils.META_DEFAULT)) == "" ||
strings.TrimSpace(fsev.GetSubject(utils.META_DEFAULT)) == "" ||
strings.TrimSpace(fsev.GetDestination(utils.META_DEFAULT)) == "" ||
strings.TrimSpace(fsev.GetCategory(utils.META_DEFAULT)) == "" ||
strings.TrimSpace(fsev.GetUUID()) == "" ||
@@ -257,15 +246,13 @@ func (fsev FSEvent) GetDisconnectCause(fieldName string) string {
func (fsev FSEvent) GetOriginatorIP(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
} else if fieldName == utils.META_DEFAULT {
return fsev[FS_IPv4]
}
return utils.FirstNonEmpty(fsev[fieldName], fsev[FS_IPv4])
}
func (fsev FSEvent) GetExtraFields() map[string]string {
extraFields := make(map[string]string)
for _, fldRule := range config.CgrConfig().SmFsConfig.CdrExtraFields {
for _, fldRule := range config.CgrConfig().SmFsConfig.ExtraFields {
extraFields[fldRule.Id] = fsev.ParseEventValue(fldRule, config.CgrConfig().DefaultTimezone)
}
return extraFields
@@ -388,6 +375,7 @@ func (fsev FSEvent) AsCallDescriptor() (*engine.CallDescriptor, error) {
Destination: fsev.GetDestination(utils.META_DEFAULT),
SetupTime: utils.FirstNonEmpty(fsev[SETUP_TIME], fsev[ANSWER_TIME]),
Duration: fsev[DURATION],
ExtraFields: fsev.GetExtraFields(),
}
return lcrReq.AsCallDescriptor(config.CgrConfig().DefaultTimezone)
}

View File

@@ -645,7 +645,7 @@ func TestFsEvAsStoredCdr(t *testing.T) {
func TestFsEvGetExtraFields(t *testing.T) {
cfg, _ := config.NewDefaultCGRConfig()
cfg.SmFsConfig.CdrExtraFields = []*utils.RSRField{&utils.RSRField{Id: "Channel-Read-Codec-Name"}, &utils.RSRField{Id: "Channel-Write-Codec-Name"}, &utils.RSRField{Id: "NonExistingHeader"}}
cfg.SmFsConfig.ExtraFields = []*utils.RSRField{&utils.RSRField{Id: "Channel-Read-Codec-Name"}, &utils.RSRField{Id: "Channel-Write-Codec-Name"}, &utils.RSRField{Id: "NonExistingHeader"}}
config.SetCgrConfig(cfg)
ev := new(FSEvent).AsEvent(hangupEv)
expectedExtraFields := map[string]string{"Channel-Read-Codec-Name": "SPEEX", "Channel-Write-Codec-Name": "SPEEX", "NonExistingHeader": ""}

View File

@@ -129,11 +129,12 @@ func (kev KamEvent) GetAccount(fieldName string) string {
}
return utils.FirstNonEmpty(kev[fieldName], kev[CGR_ACCOUNT])
}
func (kev KamEvent) GetSubject(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
}
return utils.FirstNonEmpty(kev[fieldName], kev[CGR_SUBJECT], kev[CGR_ACCOUNT])
return utils.FirstNonEmpty(kev[fieldName], kev[CGR_SUBJECT], kev.GetAccount(fieldName))
}
func (kev KamEvent) GetDestination(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value

View File

@@ -97,13 +97,7 @@ func (osipsev *OsipsEvent) GetDirection(fieldName string) string {
return utils.OUT
}
func (osipsev *OsipsEvent) GetSubject(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
}
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_SUBJECT], osipsev.GetAccount(fieldName))
}
// Account being charged
func (osipsev *OsipsEvent) GetAccount(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
@@ -111,6 +105,14 @@ func (osipsev *OsipsEvent) GetAccount(fieldName string) string {
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_ACCOUNT])
}
// Rating subject being charged, falls back on account if missing
func (osipsev *OsipsEvent) GetSubject(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
}
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_SUBJECT], osipsev.GetAccount(fieldName))
}
func (osipsev *OsipsEvent) GetDestination(fieldName string) string {
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
return fieldName[len(utils.STATIC_VALUE_PREFIX):]