diff --git a/engine/libfilters.go b/engine/libfilters.go index 36eae7ba4..771bcc7f0 100644 --- a/engine/libfilters.go +++ b/engine/libfilters.go @@ -47,6 +47,34 @@ func FilterFloat64CfgOpts(ctx *context.Context, tnt string, ev utils.DataProvide return // return the option or NOT_FOUND if there are no options or none of the filters pass } +// GetFloat64Opts checks the specified option names in order among the keys in APIOpts returning the first value it finds as float64, otherwise it +// returns the config option if at least one filter passes or NOT_FOUND if none of them do +func GetFloat64Opts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicFloat64Opt, + apiOpts map[string]interface{}, optNames ...string) (cfgOpt float64, err error) { + for _, optName := range optNames { + if opt, has := apiOpts[optName]; has { + return utils.IfaceAsFloat64(opt) + } + } + var hasDefault bool + for _, opt := range dynOpts { // iterate through the options + if len(opt.FilterIDs) == 0 { + hasDefault = true + cfgOpt = opt.Value + continue + } + if pass, err := fS.Pass(ctx, tnt, opt.FilterIDs, ev); err != nil { // check if the filter is passing for the DataProvider and return the option if it does + return 0, err + } else if pass { + return opt.Value, nil + } + } + if !hasDefault { + err = utils.ErrNotFound + } + return // return the option or NOT_FOUND if there are no options or none of the filters pass +} + // FilterDurationCfgOpts returns the option as time.Duration if the filters match func FilterDurationCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicDurationOpt) (dft time.Duration, err error) { var hasDefault bool @@ -68,6 +96,34 @@ func FilterDurationCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvid return // return the option or NOT_FOUND if there are no options or none of the filters pass } +// GetDurationOpts checks the specified option names in order among the keys in APIOpts returning the first value it finds as time.Duration, otherwise it +// returns the config option if at least one filter passes or NOT_FOUND if none of them do +func GetDurationOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicDurationOpt, + apiOpts map[string]interface{}, optNames ...string) (cfgOpt time.Duration, err error) { + for _, optName := range optNames { + if opt, has := apiOpts[optName]; has { + return utils.IfaceAsDuration(opt) + } + } + var hasDefault bool + for _, opt := range dynOpts { // iterate through the options + if len(opt.FilterIDs) == 0 { + hasDefault = true + cfgOpt = opt.Value + continue + } + if pass, err := fS.Pass(ctx, tnt, opt.FilterIDs, ev); err != nil { // check if the filter is passing for the DataProvider and return the option if it does + return 0, err + } else if pass { + return opt.Value, nil + } + } + if !hasDefault { + err = utils.ErrNotFound + } + return // return the option or NOT_FOUND if there are no options or none of the filters pass +} + // FilterStringCfgOpts returns the option as string if the filters match func FilterStringCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicStringOpt) (dft string, err error) { var hasDefault bool @@ -89,6 +145,34 @@ func FilterStringCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider return // return the option or NOT_FOUND if there are no options or none of the filters pass } +// GetStringOpts checks the specified option names in order among the keys in APIOpts returning the first value it finds as string, otherwise it +// returns the config option if at least one filter passes or NOT_FOUND if none of them do +func GetStringOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicStringOpt, + apiOpts map[string]interface{}, optNames ...string) (cfgOpt string, err error) { + for _, optName := range optNames { + if opt, has := apiOpts[optName]; has { + return utils.IfaceAsString(opt), nil + } + } + var hasDefault bool + for _, opt := range dynOpts { // iterate through the options + if len(opt.FilterIDs) == 0 { + hasDefault = true + cfgOpt = opt.Value + continue + } + if pass, err := fS.Pass(ctx, tnt, opt.FilterIDs, ev); err != nil { // check if the filter is passing for the DataProvider and return the option if it does + return utils.EmptyString, err + } else if pass { + return opt.Value, nil + } + } + if !hasDefault { + err = utils.ErrNotFound + } + return // return the option or NOT_FOUND if there are no options or none of the filters pass +} + // FilterStringSliceCfgOpts returns the option as []string if the filters match func FilterStringSliceCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicStringSliceOpt) (dft []string, err error) { var hasDefault bool @@ -110,6 +194,34 @@ func FilterStringSliceCfgOpts(ctx *context.Context, tnt string, ev utils.DataPro return // return the option or NOT_FOUND if there are no options or none of the filters pass } +// GetStringSliceOpts checks the specified option names in order among the keys in APIOpts returning the first value it finds as []string, otherwise it +// returns the config option if at least one filter passes or NOT_FOUND if none of them do +func GetStringSliceOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicStringSliceOpt, + apiOpts map[string]interface{}, optNames ...string) (cfgOpt []string, err error) { + for _, optName := range optNames { + if opt, has := apiOpts[optName]; has { + return utils.IfaceAsStringSlice(opt) + } + } + var hasDefault bool + for _, opt := range dynOpts { // iterate through the options + if len(opt.FilterIDs) == 0 { + hasDefault = true + cfgOpt = opt.Value + continue + } + if pass, err := fS.Pass(ctx, tnt, opt.FilterIDs, ev); err != nil { // check if the filter is passing for the DataProvider and return the option if it does + return nil, err + } else if pass { + return opt.Value, nil + } + } + if !hasDefault { + err = utils.ErrNotFound + } + return // return the option or NOT_FOUND if there are no options or none of the filters pass +} + // FilterIntCfgOpts returns the option as int if the filters match func FilterIntCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicIntOpt) (dft int, err error) { var hasDefault bool @@ -131,6 +243,38 @@ func FilterIntCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, f return // return the option or NOT_FOUND if there are no options or none of the filters pass } +// GetIntOpts checks the specified option names in order among the keys in APIOpts returning the first value it finds as int, otherwise it +// returns the config option if at least one filter passes or NOT_FOUND if none of them do +func GetIntOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicIntOpt, + apiOpts map[string]interface{}, optNames ...string) (cfgOpt int, err error) { + for _, optName := range optNames { + if opt, has := apiOpts[optName]; has { + var value int64 + if value, err = utils.IfaceAsTInt64(opt); err != nil { + return 0, err + } + return int(value), nil + } + } + var hasDefault bool + for _, opt := range dynOpts { // iterate through the options + if len(opt.FilterIDs) == 0 { + hasDefault = true + cfgOpt = opt.Value + continue + } + if pass, err := fS.Pass(ctx, tnt, opt.FilterIDs, ev); err != nil { // check if the filter is passing for the DataProvider and return the option if it does + return 0, err + } else if pass { + return opt.Value, nil + } + } + if !hasDefault { + err = utils.ErrNotFound + } + return // return the option or NOT_FOUND if there are no options or none of the filters pass +} + // FilterBoolCfgOpts returns the option as bool if the filters match func FilterBoolCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicBoolOpt) (dft bool, err error) { var hasDefault bool @@ -152,6 +296,34 @@ func FilterBoolCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, return // return the option or NOT_FOUND if there are no options or none of the filters pass } +// GetBoolOpts checks the specified option names in order among the keys in APIOpts returning the first value it finds as bool, otherwise it +// returns the config option if at least one filter passes or NOT_FOUND if none of them do +func GetBoolOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicBoolOpt, + apiOpts map[string]interface{}, optNames ...string) (cfgOpt bool, err error) { + for _, optName := range optNames { + if opt, has := apiOpts[optName]; has { + return utils.IfaceAsBool(opt) + } + } + var hasDefault bool + for _, opt := range dynOpts { // iterate through the options + if len(opt.FilterIDs) == 0 { + hasDefault = true + cfgOpt = opt.Value + continue + } + if pass, err := fS.Pass(ctx, tnt, opt.FilterIDs, ev); err != nil { // check if the filter is passing for the DataProvider and return the option if it does + return false, err + } else if pass { + return opt.Value, nil + } + } + if !hasDefault { + err = utils.ErrNotFound + } + return // return the option or NOT_FOUND if there are no options or none of the filters pass +} + // FilterDurationCfgOpts returns the option as time.Duration if the filters match func FilterDecimalBigCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicDecimalBigOpt) (dft *decimal.Big, err error) { var hasDefault bool @@ -173,6 +345,34 @@ func FilterDecimalBigCfgOpts(ctx *context.Context, tnt string, ev utils.DataProv return // return the option or NOT_FOUND if there are no options or none of the filters pass } +// GetDecimalBigOpts checks the specified option names in order among the keys in APIOpts returning the first value it finds as *decimal.Big, otherwise it +// returns the config option if at least one filter passes or NOT_FOUND if none of them do +func GetDecimalBigOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicDecimalBigOpt, + apiOpts map[string]interface{}, optNames ...string) (cfgOpt *decimal.Big, err error) { + for _, optName := range optNames { + if opt, has := apiOpts[optName]; has { + return utils.IfaceAsBig(opt) + } + } + var hasDefault bool + for _, opt := range dynOpts { // iterate through the options + if len(opt.FilterIDs) == 0 { + hasDefault = true + cfgOpt = opt.Value + continue + } + if pass, err := fS.Pass(ctx, tnt, opt.FilterIDs, ev); err != nil { // check if the filter is passing for the DataProvider and return the option if it does + return nil, err + } else if pass { + return opt.Value, nil + } + } + if !hasDefault { + err = utils.ErrNotFound + } + return // return the option or NOT_FOUND if there are no options or none of the filters pass +} + // FilterInterfaceCfgOpts returns the option as interface{} if the filters match func FilterInterfaceCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicInterfaceOpt) (dft interface{}, err error) { var hasDefault bool @@ -194,12 +394,30 @@ func FilterInterfaceCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvi return // return the option or NOT_FOUND if there are no options or none of the filters pass } +// GetInterfaceOpts checks the specified option names in order among the keys in APIOpts returning the first value it finds as interface{}, otherwise it +// returns the config option if at least one filter passes or NOT_FOUND if none of them do func GetInterfaceOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, dynOpts []*utils.DynamicInterfaceOpt, - apiOpts map[string]interface{}, optNames ...string) (dft interface{}, err error) { + apiOpts map[string]interface{}, optNames ...string) (cfgOpt interface{}, err error) { for _, optName := range optNames { if opt, has := apiOpts[optName]; has { return opt, nil } } - return FilterInterfaceCfgOpts(ctx, tnt, ev, fS, dynOpts) + var hasDefault bool + for _, opt := range dynOpts { // iterate through the options + if len(opt.FilterIDs) == 0 { + hasDefault = true + cfgOpt = opt.Value + continue + } + if pass, err := fS.Pass(ctx, tnt, opt.FilterIDs, ev); err != nil { // check if the filter is passing for the DataProvider and return the option if it does + return false, err + } else if pass { + return opt.Value, nil + } + } + if !hasDefault { + err = utils.ErrNotFound + } + return // return the option or NOT_FOUND if there are no options or none of the filters pass }