mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Diameter data provider with support for group filters
This commit is contained in:
@@ -151,14 +151,53 @@ func (dP *diameterDP) FieldAsInterface(fldPath []string) (data interface{}, err
|
||||
return nil, err
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
// lastPath can contain selector inside
|
||||
lastPath := fldPath[len(fldPath)-1]
|
||||
var slctr *config.RSRParser
|
||||
if splt := strings.Split(lastPath, "["); len(splt) != 1 {
|
||||
lastPath = splt[0]
|
||||
if splt[1][len(splt[1])-1:] != "]" {
|
||||
return nil, fmt.Errorf("filter rule <%s> needs to end in ]", splt[1])
|
||||
}
|
||||
fltrStr := splt[1][:len(splt[1])-1] // also strip the last ]
|
||||
if slctr, err = config.NewRSRParser(fltrStr, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
pathIface := utils.SliceStringToIface(fldPath)
|
||||
if slctr != nil { // last path was having selector inside before
|
||||
pathIface[len(pathIface)-1] = lastPath
|
||||
}
|
||||
var avps []*diam.AVP
|
||||
if avps, err = dP.m.FindAVPsWithPath(
|
||||
utils.SliceStringToIface(fldPath), dict.UndefinedVendorID); err != nil {
|
||||
pathIface, dict.UndefinedVendorID); err != nil {
|
||||
return nil, err
|
||||
} else if len(avps) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if data, err = diamAVPAsIface(avps[0]); err != nil {
|
||||
slectedIdx := 0 // by default we select AVP[0]
|
||||
if len(avps) != 1 && slctr != nil {
|
||||
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 { // 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
|
||||
}
|
||||
}
|
||||
}
|
||||
if data, err = diamAVPAsIface(avps[slectedIdx]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dP.cache.Set(fldPath, data, false)
|
||||
|
||||
@@ -44,6 +44,17 @@ func TestDPFieldAsInterface(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
})
|
||||
m.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{
|
||||
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
|
||||
}})
|
||||
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
|
||||
}})
|
||||
|
||||
dP := newDADataProvider(m)
|
||||
eOut := interface{}("simuhuawei;1449573472;00002")
|
||||
if out, err := dP.FieldAsInterface([]string{"Session-Id"}); err != nil {
|
||||
@@ -57,8 +68,14 @@ func TestDPFieldAsInterface(t *testing.T) {
|
||||
} else if eOut != out {
|
||||
t.Errorf("Expecting: %v, received: %v", eOut, out)
|
||||
}
|
||||
eOut = interface{}(uint32(33))
|
||||
if out, err := dP.FieldAsInterface([]string{"Requested-Service-Unit", "CC-Money", "Currency-Code"}); err != nil {
|
||||
eOut = interface{}("208708000003") // with filter on second group item
|
||||
if out, err := dP.FieldAsInterface([]string{"Subscription-Id", "Subscription-Id-Data[~Subscription-Id-Type(1)]"}); err != nil {
|
||||
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)
|
||||
} else if eOut != out {
|
||||
t.Errorf("Expecting: %v, received: %v", eOut, out)
|
||||
|
||||
@@ -207,6 +207,11 @@ type RSRParser struct {
|
||||
filters utils.RSRFilters // The value to compare when used as filter
|
||||
}
|
||||
|
||||
// AttrName exports the attribute name of the RSRParser
|
||||
func (prsr *RSRParser) AttrName() string {
|
||||
return prsr.attrName
|
||||
}
|
||||
|
||||
// Compile parses Rules string and repopulates other fields
|
||||
func (prsr *RSRParser) Compile() (err error) {
|
||||
var newPrsr *RSRParser
|
||||
|
||||
Reference in New Issue
Block a user