Add inline filter validation before writing to database

Implement a function that takes as parameters a list of filters
and it checks only whether the inline filters are valid.

Add it inside the functions that load the profiles inside
the TPReader. This prevents the case where it returns error
after indexing had already started when it is already too
late.

Add unit tests for the implemented function.
This commit is contained in:
ionutboangiu
2023-04-20 11:08:16 -04:00
committed by Dan Christian Bogos
parent 4cd2dc3de8
commit 3ea21e43d7
3 changed files with 62 additions and 0 deletions

View File

@@ -571,3 +571,14 @@ func (fS *FilterS) getFieldValueDataProvider(initialDP utils.DataProvider,
return
}
func validateInlineFilters(fltrs []string) (err error) {
for _, fltr := range fltrs {
if strings.HasPrefix(fltr, utils.Meta) {
if _, err = NewFilterFromInline(utils.EmptyString, fltr); err != nil {
return
}
}
}
return
}

View File

@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"fmt"
"reflect"
"strings"
"testing"
@@ -2180,3 +2181,32 @@ func TestFilterSPass11(t *testing.T) {
t.Error(err)
}
}
func TestValidateInlineFilters(t *testing.T) {
cases := []struct {
fltrs []string
expectedErr string
}{
{[]string{"FLTR", "*string:~*req.Account:1001"}, ""},
{[]string{"FLTR", "*string:~*req,Acoount1001"}, "inline parse error for string: <*string:~*req,Acoount1001>"},
{[]string{"*exists:~*req.Supplier:"}, ""},
{[]string{"*exists:*req.Supplier"}, "inline parse error for string: <*exists:*req.Supplier>"},
{[]string{"*rsr:~*req.Account:(10)"}, "invalid RSRFilter start rule in string: <(10)>"},
}
computeTestName := func(idx int, params []string) string {
return fmt.Sprintf("Test No %d with parameters: %v", idx, params)
}
for i, c := range cases {
t.Run(computeTestName(i, c.fltrs), func(t *testing.T) {
err := validateInlineFilters(c.fltrs)
if err != nil {
if c.expectedErr == "" {
t.Errorf("did not expect error, received: %v", err)
}
} else if c.expectedErr != "" {
t.Errorf("expected error: %v", err)
}
})
}
}

View File

@@ -1128,6 +1128,9 @@ func (tpr *TpReader) LoadResourceProfilesFiltered(tag string) (err error) {
}
mapRsPfls := make(map[utils.TenantID]*utils.TPResourceProfile)
for _, rl := range rls {
if err = validateInlineFilters(rl.FilterIDs); err != nil {
return
}
mapRsPfls[utils.TenantID{Tenant: rl.Tenant, ID: rl.ID}] = rl
}
tpr.resProfiles = mapRsPfls
@@ -1152,6 +1155,9 @@ func (tpr *TpReader) LoadStatsFiltered(tag string) (err error) {
}
mapSTs := make(map[utils.TenantID]*utils.TPStatProfile)
for _, st := range tps {
if err = validateInlineFilters(st.FilterIDs); err != nil {
return
}
mapSTs[utils.TenantID{Tenant: st.Tenant, ID: st.ID}] = st
}
tpr.sqProfiles = mapSTs
@@ -1176,6 +1182,9 @@ func (tpr *TpReader) LoadThresholdsFiltered(tag string) (err error) {
}
mapTHs := make(map[utils.TenantID]*utils.TPThresholdProfile)
for _, th := range tps {
if err = validateInlineFilters(th.FilterIDs); err != nil {
return
}
mapTHs[utils.TenantID{Tenant: th.Tenant, ID: th.ID}] = th
}
tpr.thProfiles = mapTHs
@@ -1217,6 +1226,9 @@ func (tpr *TpReader) LoadSupplierProfilesFiltered(tag string) (err error) {
}
mapRsPfls := make(map[utils.TenantID]*utils.TPSupplierProfile)
for _, rl := range rls {
if err = validateInlineFilters(rl.FilterIDs); err != nil {
return
}
mapRsPfls[utils.TenantID{Tenant: rl.Tenant, ID: rl.ID}] = rl
}
tpr.sppProfiles = mapRsPfls
@@ -1234,6 +1246,9 @@ func (tpr *TpReader) LoadAttributeProfilesFiltered(tag string) (err error) {
}
mapAttrPfls := make(map[utils.TenantID]*utils.TPAttributeProfile)
for _, attr := range attrs {
if err = validateInlineFilters(attr.FilterIDs); err != nil {
return
}
mapAttrPfls[utils.TenantID{Tenant: attr.Tenant, ID: attr.ID}] = attr
}
tpr.attributeProfiles = mapAttrPfls
@@ -1251,6 +1266,9 @@ func (tpr *TpReader) LoadChargerProfilesFiltered(tag string) (err error) {
}
mapChargerProfile := make(map[utils.TenantID]*utils.TPChargerProfile)
for _, rl := range rls {
if err = validateInlineFilters(rl.FilterIDs); err != nil {
return
}
mapChargerProfile[utils.TenantID{Tenant: rl.Tenant, ID: rl.ID}] = rl
}
tpr.chargerProfiles = mapChargerProfile
@@ -1268,6 +1286,9 @@ func (tpr *TpReader) LoadDispatcherProfilesFiltered(tag string) (err error) {
}
mapDispatcherProfile := make(map[utils.TenantID]*utils.TPDispatcherProfile)
for _, rl := range rls {
if err = validateInlineFilters(rl.FilterIDs); err != nil {
return
}
mapDispatcherProfile[utils.TenantID{Tenant: rl.Tenant, ID: rl.ID}] = rl
}
tpr.dispatcherProfiles = mapDispatcherProfile