mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-22 07:38:45 +05:00
Multiple filter selectors in diameter group AVP rules
This commit is contained in:
@@ -176,30 +176,43 @@ func (dP *diameterDP) FieldAsInterface(fldPath []string) (data interface{}, err
|
||||
slectedIdx := 0 // by default we select AVP[0]
|
||||
if slctrStr != "" {
|
||||
if slectedIdx, err = strconv.Atoi(slctrStr); err != nil { // not int, compile it as RSRParser
|
||||
var slctr config.RSRParsers
|
||||
if slctr, err = config.NewRSRParsersFromSlice(strings.Split(slctrStr, "|"), true); err != nil {
|
||||
return nil, err
|
||||
} else if len(slctr) == 0 {
|
||||
return nil, fmt.Errorf("unsupported filter selector: <%s>", slctrStr)
|
||||
}
|
||||
pathIface[len(pathIface)-1] = slctr[0].AttrName() // search for AVPs which are having common path but different end element
|
||||
fltrAVPs, err := dP.m.FindAVPsWithPath(pathIface, dict.UndefinedVendorID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(fltrAVPs) == 0 || len(fltrAVPs) != len(avps) {
|
||||
return nil, utils.ErrFilterNotPassingNoCaps
|
||||
}
|
||||
for k, fAVP := range fltrAVPs {
|
||||
if dataAVP, err := diamAVPAsIface(fAVP); err != nil {
|
||||
selIndxs := make(map[int][]struct{}) // use it to find intersection of all matched filters
|
||||
slctrStrs := strings.Split(slctrStr, "|")
|
||||
for _, slctrStr := range slctrStrs {
|
||||
slctr, err := config.NewRSRParser(slctrStr, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if _, err := slctr.ParseValue(dataAVP); err != nil { // filter not passing
|
||||
if err != utils.ErrFilterNotPassingNoCaps {
|
||||
return nil, err
|
||||
}
|
||||
continue // filter not passing, not really error
|
||||
} else {
|
||||
slectedIdx = k // filter passing, found our match, select the index of AVP to return
|
||||
}
|
||||
pathIface[len(pathIface)-1] = slctr.AttrName() // search for AVPs which are having common path but different end element
|
||||
fltrAVPs, err := dP.m.FindAVPsWithPath(pathIface, dict.UndefinedVendorID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(fltrAVPs) == 0 || len(fltrAVPs) != len(avps) {
|
||||
return nil, utils.ErrFilterNotPassingNoCaps
|
||||
}
|
||||
for k, fAVP := range fltrAVPs {
|
||||
if dataAVP, err := diamAVPAsIface(fAVP); err != nil {
|
||||
return nil, err
|
||||
} else if _, err := slctr.ParseValue(dataAVP); err != nil {
|
||||
if err != utils.ErrFilterNotPassingNoCaps {
|
||||
return nil, err
|
||||
}
|
||||
continue // filter not passing, not really error
|
||||
} else {
|
||||
selIndxs[k] = append(selIndxs[k], struct{}{}) // filter passing, index it
|
||||
}
|
||||
}
|
||||
}
|
||||
var oneMatches bool
|
||||
for idx, matches := range selIndxs {
|
||||
if len(matches) == len(slctrStrs) { // all filters in selection matching
|
||||
oneMatches = true
|
||||
slectedIdx = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
if !oneMatches {
|
||||
return nil, utils.ErrFilterNotPassingNoCaps
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +48,19 @@ func TestDPFieldAsInterface(t *testing.T) {
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type
|
||||
diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("33708000003")), // Subscription-Id-Data
|
||||
diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(10000)),
|
||||
}})
|
||||
m.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(1)), // Subscription-Id-Type
|
||||
diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("208708000003")), // Subscription-Id-Data
|
||||
diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(20000)),
|
||||
}})
|
||||
m.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(1)), // Subscription-Id-Type
|
||||
diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("208708000004")), // Subscription-Id-Data
|
||||
diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(30000)),
|
||||
}})
|
||||
|
||||
dP := newDADataProvider(m)
|
||||
@@ -81,6 +89,13 @@ func TestDPFieldAsInterface(t *testing.T) {
|
||||
} else if eOut != out {
|
||||
t.Errorf("Expecting: %v, received: %v", eOut, out)
|
||||
}
|
||||
eOut = interface{}("208708000004")
|
||||
if out, err := dP.FieldAsInterface([]string{"Subscription-Id",
|
||||
"Subscription-Id-Data[~Subscription-Id-Type(1)|~Value-Digits(30000)]"}); err != nil { // on multiple filter
|
||||
t.Error(err)
|
||||
} else if eOut != out {
|
||||
t.Errorf("Expecting: %v, received: %v", eOut, out)
|
||||
}
|
||||
eOut = interface{}("33708000003")
|
||||
if out, err := dP.FieldAsInterface([]string{"Subscription-Id", "Subscription-Id-Data"}); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
Reference in New Issue
Block a user