From ea47d051ecee138b35923e29b56cf4cc41c1b7a3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 23 Nov 2018 15:49:26 +0200 Subject: [PATCH] Replace RSRFields in FsAgentConfig with RSRParsers --- agents/fsevent.go | 48 ++++++++++++++++++------------------- agents/fsevent_test.go | 52 ++++++++++++++++++++++------------------ apier/v1/cdre_it_test.go | 20 ++++++++++++---- config/config_test.go | 4 ++-- config/smconfig.go | 4 ++-- config/smconfig_test.go | 1 + engine/action.go | 6 +++-- 7 files changed, 77 insertions(+), 58 deletions(-) diff --git a/agents/fsevent.go b/agents/fsevent.go index 636acbb34..306939c45 100644 --- a/agents/fsevent.go +++ b/agents/fsevent.go @@ -297,60 +297,60 @@ func (fsev FSEvent) GetExtraFields() map[string]string { config.CgrConfig().GeneralCfg().DefaultTimezone); err != nil { utils.Logger.Warning(fmt.Sprintf("<%s> error: %s parsing event rule: %+v", utils.FreeSWITCHAgent, err.Error(), fldRule)) } else { - extraFields[fldRule.Id] = parsed + extraFields[fldRule.AttrName()] = parsed } } return extraFields } // Used in derived charging and sittuations when we need to run regexp on fields -func (fsev FSEvent) ParseEventValue(rsrFld *utils.RSRField, timezone string) (parsed string, err error) { - switch rsrFld.Id { +func (fsev FSEvent) ParseEventValue(rsrFld *config.RSRParser, timezone string) (parsed string, err error) { + switch rsrFld.AttrName() { case utils.ToR: - return rsrFld.Parse(utils.VOICE) + return rsrFld.ParseValue(utils.VOICE) case utils.OriginID: - return rsrFld.Parse(fsev.GetUUID()) + return rsrFld.ParseValue(fsev.GetUUID()) case utils.OriginHost: - return rsrFld.Parse(utils.FirstNonEmpty(fsev[VarCGROriginHost], fsev[FS_IPv4])) + return rsrFld.ParseValue(utils.FirstNonEmpty(fsev[VarCGROriginHost], fsev[FS_IPv4])) case utils.Source: - return rsrFld.Parse("FS_EVENT") + return rsrFld.ParseValue("FS_EVENT") case utils.RequestType: - return rsrFld.Parse(fsev.GetReqType("")) + return rsrFld.ParseValue(fsev.GetReqType("")) case utils.Direction: - return rsrFld.Parse(fsev.GetDirection("")) + return rsrFld.ParseValue(fsev.GetDirection("")) case utils.Tenant: - return rsrFld.Parse(fsev.GetTenant("")) + return rsrFld.ParseValue(fsev.GetTenant("")) case utils.Category: - return rsrFld.Parse(fsev.GetCategory("")) + return rsrFld.ParseValue(fsev.GetCategory("")) case utils.Account: - return rsrFld.Parse(fsev.GetAccount("")) + return rsrFld.ParseValue(fsev.GetAccount("")) case utils.Subject: - return rsrFld.Parse(fsev.GetSubject("")) + return rsrFld.ParseValue(fsev.GetSubject("")) case utils.Destination: - return rsrFld.Parse(fsev.GetDestination("")) + return rsrFld.ParseValue(fsev.GetDestination("")) case utils.SetupTime: st, _ := fsev.GetSetupTime("", timezone) - return rsrFld.Parse(st.String()) + return rsrFld.ParseValue(st.String()) case utils.AnswerTime: at, _ := fsev.GetAnswerTime("", timezone) - return rsrFld.Parse(at.String()) + return rsrFld.ParseValue(at.String()) case utils.Usage: dur, _ := fsev.GetDuration("") - return rsrFld.Parse(strconv.FormatInt(dur.Nanoseconds(), 10)) + return rsrFld.ParseValue(strconv.FormatInt(dur.Nanoseconds(), 10)) case utils.PDD: PDD, _ := fsev.GetPdd(utils.META_DEFAULT) - return rsrFld.Parse(strconv.FormatFloat(PDD.Seconds(), 'f', -1, 64)) + return rsrFld.ParseValue(strconv.FormatFloat(PDD.Seconds(), 'f', -1, 64)) case utils.SUPPLIER: - return rsrFld.Parse(fsev.GetSupplier("")) + return rsrFld.ParseValue(fsev.GetSupplier("")) case utils.DISCONNECT_CAUSE: - return rsrFld.Parse(fsev.GetDisconnectCause("")) + return rsrFld.ParseValue(fsev.GetDisconnectCause("")) case utils.RunID: - return rsrFld.Parse(utils.DEFAULT_RUNID) + return rsrFld.ParseValue(utils.DEFAULT_RUNID) case utils.Cost: - return rsrFld.Parse(strconv.FormatFloat(-1, 'f', -1, 64)) // Recommended to use FormatCost + return rsrFld.ParseValue(strconv.FormatFloat(-1, 'f', -1, 64)) // Recommended to use FormatCost default: - if parsed, err = rsrFld.Parse(fsev[rsrFld.Id]); err != nil { - parsed, err = rsrFld.Parse(fsev[FS_VARPREFIX+rsrFld.Id]) + if parsed, err = rsrFld.ParseValue(fsev[rsrFld.AttrName()]); err != nil { + parsed, err = rsrFld.ParseValue(fsev[FS_VARPREFIX+rsrFld.AttrName()]) } return } diff --git a/agents/fsevent_test.go b/agents/fsevent_test.go index 50c86ac3d..4b14f645e 100644 --- a/agents/fsevent_test.go +++ b/agents/fsevent_test.go @@ -498,63 +498,63 @@ func TestParseEventValue(t *testing.T) { cfg, _ := config.NewDefaultCGRConfig() config.SetCgrConfig(cfg) ev := NewFSEvent(hangupEv) - if tor, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.ToR}, ""); tor != utils.VOICE { + if tor, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.ToR, true), ""); tor != utils.VOICE { t.Error("Unexpected tor parsed", tor) } - if accid, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.OriginID}, ""); accid != "e3133bf7-dcde-4daf-9663-9a79ffcef5ad" { + if accid, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.OriginID, true), ""); accid != "e3133bf7-dcde-4daf-9663-9a79ffcef5ad" { t.Error("Unexpected result parsed", accid) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.OriginHost}, ""); parsed != "10.0.3.15" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.OriginHost, true), ""); parsed != "10.0.3.15" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.Source}, ""); parsed != "FS_EVENT" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.Source, true), ""); parsed != "FS_EVENT" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.RequestType}, ""); parsed != utils.META_PREPAID { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.RequestType, true), ""); parsed != utils.META_PREPAID { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.Direction}, ""); parsed != utils.OUT { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.Direction, true), ""); parsed != utils.OUT { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.Tenant}, ""); parsed != "cgrates.org" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.Tenant, true), ""); parsed != "cgrates.org" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.Category}, ""); parsed != "call" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.Category, true), ""); parsed != "call" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.Account}, ""); parsed != "1001" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.Account, true), ""); parsed != "1001" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.Subject}, ""); parsed != "1001" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.Subject, true), ""); parsed != "1001" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.Destination}, ""); parsed != "1003" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.Destination, true), ""); parsed != "1003" { t.Error("Unexpected result parsed", parsed) } sTime, _ := utils.ParseTimeDetectLayout("1436280728471153"[:len("1436280728471153")-6], "") // We discard nanoseconds information so we can correlate csv - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.SetupTime}, ""); parsed != sTime.String() { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.SetupTime, true), ""); parsed != sTime.String() { t.Errorf("Expecting: %s, parsed: %s", sTime.String(), parsed) } aTime, _ := utils.ParseTimeDetectLayout("1436280728971147"[:len("1436280728971147")-6], "") - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.AnswerTime}, ""); parsed != aTime.String() { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.AnswerTime, true), ""); parsed != aTime.String() { t.Errorf("Expecting: %s, parsed: %s", aTime.String(), parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.Usage}, ""); parsed != "66000000000" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.Usage, true), ""); parsed != "66000000000" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.PDD}, ""); parsed != "0.028" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.PDD, true), ""); parsed != "0.028" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.SUPPLIER}, ""); parsed != "supplier1" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.SUPPLIER, true), ""); parsed != "supplier1" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.RunID}, ""); parsed != utils.DEFAULT_RUNID { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.RunID, true), ""); parsed != utils.DEFAULT_RUNID { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: utils.COST}, ""); parsed != "-1" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+utils.COST, true), ""); parsed != "-1" { t.Error("Unexpected result parsed", parsed) } - if parsed, _ := ev.ParseEventValue(&utils.RSRField{Id: "Hangup-Cause"}, ""); parsed != "NORMAL_CLEARING" { + if parsed, _ := ev.ParseEventValue(config.NewRSRParserMustCompile("~"+"Hangup-Cause", true), ""); parsed != "NORMAL_CLEARING" { t.Error("Unexpected result parsed", parsed) } } @@ -616,10 +616,16 @@ func TestFsEvAsMapStringInterface(t *testing.T) { func TestFsEvGetExtraFields(t *testing.T) { cfg, _ := config.NewDefaultCGRConfig() - cfg.FsAgentCfg().ExtraFields = []*utils.RSRField{ - {Id: "Channel-Read-Codec-Name"}, - {Id: "Channel-Write-Codec-Name"}, - {Id: "NonExistingHeader"}} + var err error + err = nil + cfg.FsAgentCfg().ExtraFields, err = config.NewRSRParsersFromSlice([]string{ + "~Channel-Read-Codec-Name", + "~Channel-Write-Codec-Name", + "~NonExistingHeader", + }, true) + if err != nil { + t.Error(err) + } config.SetCgrConfig(cfg) ev := NewFSEvent(hangupEv) expectedExtraFields := map[string]string{ diff --git a/apier/v1/cdre_it_test.go b/apier/v1/cdre_it_test.go index fce76fdb4..1e4fc239a 100755 --- a/apier/v1/cdre_it_test.go +++ b/apier/v1/cdre_it_test.go @@ -170,11 +170,21 @@ func testCDReFromFolder(t *testing.T) { // Test CDR from external sources func testCDReProcessExternalCdr(t *testing.T) { - cdr := &engine.ExternalCDR{ToR: utils.VOICE, - OriginID: "testextcdr1", OriginHost: "127.0.0.1", Source: utils.UNIT_TEST, RequestType: utils.META_RATED, - Tenant: "cgrates.org", Category: "call", Account: "1003", Subject: "1003", Destination: "1001", - SetupTime: "2014-08-04T13:00:00Z", AnswerTime: "2014-08-04T13:00:07Z", - Usage: "1s", ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + cdr := &engine.ExternalCDR{ + ToR: utils.VOICE, + OriginID: "testextcdr1", + OriginHost: "127.0.0.1", + Source: utils.UNIT_TEST, + RequestType: utils.META_RATED, + Tenant: "cgrates.org", + Category: "call", + Account: "1003", + Subject: "1003", + Destination: "1001", + SetupTime: "2014-08-04T13:00:00Z", + AnswerTime: "2014-08-04T13:00:07Z", + Usage: "1s", + ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, } var reply string if err := cdreRPC.Call("CdrsV1.ProcessExternalCdr", cdr, &reply); err != nil { diff --git a/config/config_test.go b/config/config_test.go index 35a1847f9..04174e11a 100755 --- a/config/config_test.go +++ b/config/config_test.go @@ -738,7 +738,7 @@ func TestCgrCfgJSONDefaultsFsAgentConfig(t *testing.T) { {Address: "*internal"}}, SubscribePark: true, CreateCdr: false, - ExtraFields: nil, + ExtraFields: RSRParsers{}, EmptyBalanceContext: "", EmptyBalanceAnnFile: "", MaxWaitConnection: 2 * time.Second, @@ -751,7 +751,7 @@ func TestCgrCfgJSONDefaultsFsAgentConfig(t *testing.T) { } if !reflect.DeepEqual(cgrCfg.fsAgentCfg, eFsAgentCfg) { - t.Errorf("received: %+v, expecting: %+v", cgrCfg.fsAgentCfg, eFsAgentCfg) + t.Errorf("received: %+v, expecting: %+v", utils.ToJSON(cgrCfg.fsAgentCfg), utils.ToJSON(eFsAgentCfg)) } } diff --git a/config/smconfig.go b/config/smconfig.go index aa249b0f3..e69de2090 100644 --- a/config/smconfig.go +++ b/config/smconfig.go @@ -248,7 +248,7 @@ type FsAgentCfg struct { SessionSConns []*HaPoolConfig SubscribePark bool CreateCdr bool - ExtraFields []*utils.RSRField + ExtraFields RSRParsers //MinDurLowBalance time.Duration //LowBalanceAnnFile string EmptyBalanceContext string @@ -279,7 +279,7 @@ func (self *FsAgentCfg) loadFromJsonCfg(jsnCfg *FreeswitchAgentJsonCfg) error { self.CreateCdr = *jsnCfg.Create_cdr } if jsnCfg.Extra_fields != nil { - if self.ExtraFields, err = utils.ParseRSRFieldsFromSlice(*jsnCfg.Extra_fields); err != nil { + if self.ExtraFields, err = NewRSRParsersFromSlice(*jsnCfg.Extra_fields, true); err != nil { return err } } diff --git a/config/smconfig_test.go b/config/smconfig_test.go index a073fbde9..0efd2389f 100644 --- a/config/smconfig_test.go +++ b/config/smconfig_test.go @@ -163,6 +163,7 @@ func TestFsAgentCfgloadFromJsonCfg2(t *testing.T) { SessionSConns: []*HaPoolConfig{{Address: "*internal"}}, SubscribePark: true, MaxWaitConnection: time.Duration(2 * time.Second), + ExtraFields: RSRParsers{}, EventSocketConns: []*FsConnCfg{{ Address: "127.0.0.1:8021", Password: "ClueCon", diff --git a/engine/action.go b/engine/action.go index d38e6be36..0d7f68851 100644 --- a/engine/action.go +++ b/engine/action.go @@ -171,12 +171,14 @@ func cdrLogAction(acc *Account, a *Action, acs Actions, extraData interface{}) ( action.Balance == nil { continue // Only log specific actions } - cdr := &CDR{RunID: action.ActionType, + cdr := &CDR{ + RunID: action.ActionType, Source: CDRLOG, SetupTime: time.Now(), AnswerTime: time.Now(), OriginID: utils.GenUUID(), ExtraFields: make(map[string]string), - PreRated: true} + PreRated: true, + } cdr.CGRID = utils.Sha1(cdr.OriginID, cdr.SetupTime.String()) cdr.Usage = time.Duration(1) elem := reflect.ValueOf(cdr).Elem()