From 511fcfd8f5130d92be98f207301729fb5297751c Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 8 Jul 2014 18:55:37 +0200 Subject: [PATCH] Adding ParseRSRFields for list of RSRFields, modifying NewRSRField static format to add suffix / --- utils/derivedchargers_test.go | 8 ++++---- utils/rsrfield.go | 25 +++++++++++++++++++++++-- utils/rsrfield_test.go | 16 +++++++++++++++- utils/storedcdr_test.go | 6 +++--- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/utils/derivedchargers_test.go b/utils/derivedchargers_test.go index 52e2f1566..0a079a109 100644 --- a/utils/derivedchargers_test.go +++ b/utils/derivedchargers_test.go @@ -67,7 +67,7 @@ func TestNewDerivedCharger(t *testing.T) { } edc2 := &DerivedCharger{ RunId: "test2", - RunFilter: "^cdr_source/tdm_cdrs", + RunFilter: "^cdr_source/tdm_cdrs/", ReqTypeField: "~reqtype2:s/sip:(.+)/$1/", DirectionField: "~direction2:s/sip:(.+)/$1/", TenantField: "~tenant2:s/sip:(.+)/$1/", @@ -79,7 +79,7 @@ func TestNewDerivedCharger(t *testing.T) { AnswerTimeField: "~answertime2:s/sip:(.+)/$1/", UsageField: "~duration2:s/sip:(.+)/$1/", } - edc2.rsrRunFilter, _ = NewRSRField("^cdr_source/tdm_cdrs") + edc2.rsrRunFilter, _ = NewRSRField("^cdr_source/tdm_cdrs/") edc2.rsrReqTypeField, _ = NewRSRField("~reqtype2:s/sip:(.+)/$1/") edc2.rsrDirectionField, _ = NewRSRField("~direction2:s/sip:(.+)/$1/") edc2.rsrTenantField, _ = NewRSRField("~tenant2:s/sip:(.+)/$1/") @@ -91,7 +91,7 @@ func TestNewDerivedCharger(t *testing.T) { edc2.rsrAnswerTimeField, _ = NewRSRField("~answertime2:s/sip:(.+)/$1/") edc2.rsrUsageField, _ = NewRSRField("~duration2:s/sip:(.+)/$1/") if dc2, err := NewDerivedCharger("test2", - "^cdr_source/tdm_cdrs", + "^cdr_source/tdm_cdrs/", "~reqtype2:s/sip:(.+)/$1/", "~direction2:s/sip:(.+)/$1/", "~tenant2:s/sip:(.+)/$1/", @@ -102,7 +102,7 @@ func TestNewDerivedCharger(t *testing.T) { "~setuptime2:s/sip:(.+)/$1/", "~answertime2:s/sip:(.+)/$1/", "~duration2:s/sip:(.+)/$1/"); err != nil { - t.Error("Unexpected error", err.Error) + t.Error("Unexpected error", err) } else if !reflect.DeepEqual(edc2, dc2) { t.Errorf("Expecting: %v, received: %v", edc2, dc2) } diff --git a/utils/rsrfield.go b/utils/rsrfield.go index baf93ca21..6de14784a 100644 --- a/utils/rsrfield.go +++ b/utils/rsrfield.go @@ -30,8 +30,11 @@ func NewRSRField(fldStr string) (*RSRField, error) { } if strings.HasPrefix(fldStr, STATIC_VALUE_PREFIX) { // Special case when RSR is defined as static header/value var staticHdr, staticVal string - if splt := strings.Split(fldStr, HDR_VAL_SEP); len(splt) == 2 { // Using | as separator since ':' is often use in date/time fields - staticHdr, staticVal = splt[0][1:], splt[1] + if splt := strings.Split(fldStr, "/"); len(splt) == 3 { // Using / as separator since ':' is often use in date/time fields + if len(splt[2]) != 0 { // Last split has created empty element + return nil, fmt.Errorf("Invalid static header/value combination: %s", fldStr) + } + staticHdr, staticVal = splt[0][1:], splt[1] // Strip the / suffix } else { staticHdr, staticVal = splt[0][1:], splt[0][1:] // If no split, header will remain as original, value as header without the prefix } @@ -95,3 +98,21 @@ func (rsrf *RSRField) RegexpMatched() bool { // Investigate whether we had a reg } return false } + +// Parses list of RSRFields, used for example as multiple filters in derived charging +func ParseRSRFields(fldsStr string) ([]*RSRField, error) { + //rsrRlsPattern := regexp.MustCompile(`^(~\w+:s/.+/.*/)|(\^.+(/.+/)?)(;(~\w+:s/.+/.*/)|(\^.+(/.+/)?))*$`) //ToDo:Fix here rule able to confirm the content + rulesSplt := strings.Split(fldsStr, ";") + rsrFields := make([]*RSRField, len(rulesSplt)) + for idx, ruleStr := range rulesSplt { + if !strings.HasSuffix(ruleStr, "/") { + return nil, fmt.Errorf("Invalid RSRField string: %s", ruleStr) + } + if rsrField, err := NewRSRField(ruleStr); err != nil { + return nil, err + } else { + rsrFields[idx] = rsrField + } + } + return rsrFields, nil +} diff --git a/utils/rsrfield_test.go b/utils/rsrfield_test.go index 7b215f161..985318003 100644 --- a/utils/rsrfield_test.go +++ b/utils/rsrfield_test.go @@ -86,7 +86,7 @@ func TestConvertPlusNationalAnd00(t *testing.T) { } func TestRSRParseStatic(t *testing.T) { - if rsrField, err := NewRSRField("^static_header/static_value"); err != nil { + if rsrField, err := NewRSRField("^static_header/static_value/"); err != nil { t.Error(err) } else if !reflect.DeepEqual(rsrField, &RSRField{Id: "static_header", staticValue: "static_value"}) { t.Errorf("Unexpected RSRField received: %v", rsrField) @@ -140,3 +140,17 @@ func TestIsStatic(t *testing.T) { t.Error("Non static detected as static value") } } + +func TestParseRSRFields(t *testing.T) { + fieldsStr1 := `~account:s/^\w+[mpls]\d{6}$//;~subject:s/^0\d{9}$//;^destination/+4912345/;~mediation_runid:s/^default$/default/` + rsrFld1, _ := NewRSRField(`~account:s/^\w+[mpls]\d{6}$//`) + rsrFld2, _ := NewRSRField(`~subject:s/^0\d{9}$//`) + rsrFld3, _ := NewRSRField(`^destination/+4912345/`) + rsrFld4, _ := NewRSRField(`~mediation_runid:s/^default$/default/`) + eRSRFields := []*RSRField{rsrFld1, rsrFld2, rsrFld3, rsrFld4} + if rsrFlds, err := ParseRSRFields(fieldsStr1); err != nil { + t.Error("Unexpected error: ", err) + } else if !reflect.DeepEqual(eRSRFields, rsrFlds) { + t.Errorf("Expecting: %v, received: %v", eRSRFields, rsrFlds) + } +} diff --git a/utils/storedcdr_test.go b/utils/storedcdr_test.go index 448b904b7..e71a96ae2 100644 --- a/utils/storedcdr_test.go +++ b/utils/storedcdr_test.go @@ -108,15 +108,15 @@ func TestPassesFieldFilter(t *testing.T) { if pass, _ := cdr.PassesFieldFilter(acntPrefxFltr); pass { t.Error("Passing filter") } - torFltr, _ := NewRSRField(`^tor/*voice`) + torFltr, _ := NewRSRField(`^tor/*voice/`) if pass, _ := cdr.PassesFieldFilter(torFltr); !pass { t.Error("Not passing filter") } - torFltr, _ = NewRSRField(`^tor/*data`) + torFltr, _ = NewRSRField(`^tor/*data/`) if pass, _ := cdr.PassesFieldFilter(torFltr); pass { t.Error("Passing filter") } - inexistentFieldFltr, _ := NewRSRField(`^fakefield/fakevalue`) + inexistentFieldFltr, _ := NewRSRField(`^fakefield/fakevalue/`) if pass, _ := cdr.PassesFieldFilter(inexistentFieldFltr); pass { t.Error("Passing filter") }