mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 10:06:24 +05:00
Added *len dataconverter
This commit is contained in:
committed by
Dan Christian Bogos
parent
c5b22c24ab
commit
5e7860eede
@@ -550,32 +550,22 @@ func (fltr *FilterRule) passRSR(dDP utils.DataProvider) (bool, error) {
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passGreaterThan(dDP utils.DataProvider) (bool, error) {
|
||||
path, err := fltr.rsrElement.CompileDynRule(dDP)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
fldIf, err := utils.DPDynamicInterface(path, dDP)
|
||||
fldStr, err := fltr.rsrElement.ParseDataProviderWithInterfaces(dDP)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if fldStr, castStr := fldIf.(string); castStr { // attempt converting string since deserialization fails here (ie: time.Time fields)
|
||||
fldIf = utils.StringToInterface(fldStr)
|
||||
}
|
||||
fldIf := utils.StringToInterface(fldStr)
|
||||
orEqual := fltr.Type == utils.MetaGreaterOrEqual ||
|
||||
fltr.Type == utils.MetaLessThan
|
||||
for _, val := range fltr.rsrValues {
|
||||
valPath, err := val.CompileDynRule(dDP)
|
||||
sval, err := val.ParseDataProviderWithInterfaces(dDP)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
sval, err := utils.DPDynamicInterface(valPath, dDP)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if gte, err := utils.GreaterThan(fldIf, sval, orEqual); err != nil {
|
||||
if gte, err := utils.GreaterThan(fldIf, utils.StringToInterface(sval), orEqual); err != nil {
|
||||
return false, err
|
||||
} else if (utils.MetaGreaterThan == fltr.Type || utils.MetaGreaterOrEqual == fltr.Type) && gte {
|
||||
return true, nil
|
||||
@@ -587,30 +577,20 @@ func (fltr *FilterRule) passGreaterThan(dDP utils.DataProvider) (bool, error) {
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passEqualTo(dDP utils.DataProvider) (bool, error) {
|
||||
path, err := fltr.rsrElement.CompileDynRule(dDP)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
fldIf, err := utils.DPDynamicInterface(path, dDP)
|
||||
fldStr, err := fltr.rsrElement.ParseDataProviderWithInterfaces(dDP)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if fldStr, castStr := fldIf.(string); castStr { // attempt converting string since deserialization fails here (ie: time.Time fields)
|
||||
fldIf = utils.StringToInterface(fldStr)
|
||||
}
|
||||
fldIf := utils.StringToInterface(fldStr)
|
||||
for _, val := range fltr.rsrValues {
|
||||
valPath, err := val.CompileDynRule(dDP)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sval, err := utils.DPDynamicInterface(valPath, dDP)
|
||||
sval, err := val.ParseDataProviderWithInterfaces(dDP)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if eq, err := utils.EqualTo(fldIf, sval); err != nil {
|
||||
if eq, err := utils.EqualTo(fldIf, utils.StringToInterface(sval)); err != nil {
|
||||
return false, err
|
||||
} else if eq {
|
||||
return true, nil
|
||||
@@ -663,49 +643,42 @@ func (fltr *FilterRule) passAPIBan(dDP utils.DataProvider) (bool, error) {
|
||||
return dm.GetAPIBan(strVal, config.CgrConfig().APIBanCfg().Keys, fltr.Values[0] != utils.MetaAll, true, true)
|
||||
}
|
||||
|
||||
func parseTime(rsr *config.RSRParser, dDp utils.DataProvider) (_ time.Time, err error) {
|
||||
var str string
|
||||
if str, err = rsr.ParseDataProvider(dDp); err != nil {
|
||||
return
|
||||
}
|
||||
return utils.ParseTimeDetectLayout(str, config.CgrConfig().GeneralCfg().DefaultTimezone)
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passActivationInterval(dDp utils.DataProvider) (bool, error) {
|
||||
strVal, err := fltr.rsrElement.ParseDataProvider(dDp)
|
||||
timeVal, err := parseTime(fltr.rsrElement, dDp)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
timeStrVal, err := utils.ParseTimeDetectLayout(strVal, config.CgrConfig().GeneralCfg().DefaultTimezone)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if len(fltr.rsrValues) == 2 {
|
||||
val2, err := fltr.rsrValues[1].CompileDynRule(dDp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
endTime, err := utils.ParseTimeDetectLayout(val2, config.CgrConfig().GeneralCfg().DefaultTimezone)
|
||||
endTime, err := parseTime(fltr.rsrValues[1], dDp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if fltr.rsrValues[0] == nil {
|
||||
return timeStrVal.Before(endTime), nil
|
||||
return timeVal.Before(endTime), nil
|
||||
}
|
||||
val1, err := fltr.rsrValues[0].CompileDynRule(dDp)
|
||||
startTime, err := parseTime(fltr.rsrValues[0], dDp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
startTime, err := utils.ParseTimeDetectLayout(val1, config.CgrConfig().GeneralCfg().DefaultTimezone)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return startTime.Before(timeStrVal) && timeStrVal.Before(endTime), nil
|
||||
return startTime.Before(timeVal) && timeVal.Before(endTime), nil
|
||||
}
|
||||
val1, err := fltr.rsrValues[0].CompileDynRule(dDp)
|
||||
startTime, err := parseTime(fltr.rsrValues[0], dDp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
startTime, err := utils.ParseTimeDetectLayout(val1, config.CgrConfig().GeneralCfg().DefaultTimezone)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return startTime.Before(timeStrVal), nil
|
||||
return startTime.Before(timeVal), nil
|
||||
}
|
||||
|
||||
func verifyInlineFilterS(fltrs []string) (err error) {
|
||||
|
||||
@@ -1059,6 +1059,26 @@ func TestInlineFilterPassFiltersForEvent(t *testing.T) {
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", false, pass)
|
||||
}
|
||||
|
||||
pEv = utils.MapStorage{utils.MetaReq: utils.MapStorage{utils.AccountField: "sip:12345678901234567@abcdefg"}}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*regex:~*req.Account:.{29,}"}, pEv); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*regex:~*req.Account:^.{28}$"}, pEv); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", false, pass)
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*gte:~*req.Account{*len}:29"}, pEv); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassFiltersForEventWithEmptyFilter(t *testing.T) {
|
||||
@@ -2199,7 +2219,7 @@ func TestFiltersPassGreaterThanErrIncomparable(t *testing.T) {
|
||||
}
|
||||
dtP := utils.MapStorage{
|
||||
utils.MetaReq: map[string]interface{}{
|
||||
utils.MetaUsage: "10",
|
||||
utils.Usage: nil,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -165,6 +165,8 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium
|
||||
* [StatS] AverageCallCost and TotalCallCost now returns error for negative Cost field
|
||||
* [SessionS] The sessions are no longer terminated on shutdown if the replication_conns are set
|
||||
* [FilterS] Added *regex filter
|
||||
* [RSRParsers] Added *len dataconverter
|
||||
|
||||
-- DanB <danb@cgrates.org> Wed, 19 Feb 2020 13:25:52 +0200
|
||||
|
||||
cgrates (0.10.0) UNRELEASED; urgency=medium
|
||||
|
||||
@@ -772,6 +772,7 @@ const (
|
||||
MetaIP2Hex = "*ip2hex"
|
||||
MetaString2Hex = "*string2hex"
|
||||
MetaUnixTime = "*unixtime"
|
||||
MetaLen = "*len"
|
||||
MetaSIPURIMethod = "*sipuri_method"
|
||||
MetaSIPURIHost = "*sipuri_host"
|
||||
MetaSIPURIUser = "*sipuri_user"
|
||||
|
||||
@@ -20,6 +20,7 @@ package utils
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
@@ -87,6 +88,8 @@ func NewDataConverter(params string) (conv DataConverter, err error) {
|
||||
return new(SIPURIMethodConverter), nil
|
||||
case params == MetaUnixTime:
|
||||
return new(UnixTimeConverter), nil
|
||||
case params == MetaLen:
|
||||
return new(LengthConverter), nil
|
||||
case strings.HasPrefix(params, MetaLibPhoneNumber):
|
||||
if len(params) == len(MetaLibPhoneNumber) {
|
||||
return NewPhoneNumberConverter(EmptyString)
|
||||
@@ -446,3 +449,19 @@ func (rC *RandomConverter) Convert(in interface{}) (
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LengthConverter converts the interface in the unix time
|
||||
type LengthConverter struct{}
|
||||
|
||||
// Convert implements DataConverter interface
|
||||
func (LengthConverter) Convert(in interface{}) (out interface{}, err error) {
|
||||
src := IfaceAsString(in)
|
||||
if strings.HasPrefix(src, IdxStart) &&
|
||||
strings.HasSuffix(src, IdxEnd) { // it has a similar structure to a json marshaled slice
|
||||
var slice []interface{}
|
||||
if err := json.Unmarshal([]byte(src), &slice); err == nil { // no error when unmarshal safe to asume that this is a slice
|
||||
return len(slice), nil
|
||||
}
|
||||
}
|
||||
return len(src), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user