added helper method for repetive logic on GetOpts funcs

This commit is contained in:
gezimbll
2025-02-07 15:22:43 +01:00
committed by Dan Christian Bogos
parent d2c175141f
commit 14515404bb
2 changed files with 93 additions and 116 deletions

View File

@@ -33,19 +33,11 @@ import (
// returns the config option if at least one filter passes or the default value if none of them do
func GetFloat64Opts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicFloat64Opt,
optNames ...string) (cfgOpt float64, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return utils.IfaceAsFloat64(opt)
} else if !errors.Is(err, utils.ErrNotFound) {
return 0, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return utils.IfaceAsFloat64(opt)
}
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
continue
@@ -63,19 +55,11 @@ func GetFloat64Opts(ctx *context.Context, tnt string, dP utils.DataProvider, fS
// returns the config option if at least one filter passes or the default value if none of them do
func GetDurationOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicDurationOpt,
optNames ...string) (cfgOpt time.Duration, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return utils.IfaceAsDuration(opt)
} else if !errors.Is(err, utils.ErrNotFound) {
return 0, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return utils.IfaceAsDuration(opt)
}
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
continue
@@ -93,19 +77,11 @@ func GetDurationOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS
// returns the config option if at least one filter passes or the default value if none of them do
func GetStringOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicStringOpt,
optNames ...string) (cfgOpt string, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return utils.IfaceAsString(opt), nil
} else if !errors.Is(err, utils.ErrNotFound) {
return "", err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return utils.IfaceAsString(opt), nil
}
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
continue
@@ -123,18 +99,10 @@ func GetStringOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *
// returns the config option if at least one filter passes or the default value if none of them do
func GetTimeOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicStringOpt,
tmz string, optNames ...string) (_ time.Time, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
return
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return utils.IfaceAsTime(opt, tmz)
}
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return utils.IfaceAsTime(opt, tmz)
} else if !errors.Is(err, utils.ErrNotFound) {
return time.Time{}, err
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
@@ -159,19 +127,11 @@ func GetTimeOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *Fi
// returns the config option if at least one filter passes or the default value if none of them do
func GetStringSliceOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicStringSliceOpt,
dftOpt []string, optNames ...string) (cfgOpt []string, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return utils.IfaceAsStringSlice(opt)
} else if !errors.Is(err, utils.ErrNotFound) {
return nil, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return utils.IfaceAsStringSlice(opt)
}
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
continue
@@ -189,19 +149,11 @@ func GetStringSliceOpts(ctx *context.Context, tnt string, dP utils.DataProvider,
// returns the config option if at least one filter passes or the default value if none of them do
func GetIntOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicIntOpt,
optNames ...string) (cfgOpt int, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return utils.IfaceAsInt(opt)
} else if !errors.Is(err, utils.ErrNotFound) {
return 0, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return utils.IfaceAsInt(opt)
}
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
continue
@@ -219,19 +171,11 @@ func GetIntOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *Fil
// returns the config option if at least one filter passes or the default value if none of them do
func GetBoolOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicBoolOpt,
optNames ...string) (cfgOpt bool, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return utils.IfaceAsBool(opt)
} else if !errors.Is(err, utils.ErrNotFound) {
return false, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return utils.IfaceAsBool(opt)
}
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
continue
@@ -249,19 +193,11 @@ func GetBoolOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *Fi
// returns the config option if at least one filter passes or the default value if none of them do
func GetDecimalBigOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicDecimalOpt,
optNames ...string) (cfgOpt *decimal.Big, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return utils.IfaceAsBig(opt)
} else if !errors.Is(err, utils.ErrNotFound) {
return nil, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return utils.IfaceAsBig(opt)
}
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
continue
@@ -279,18 +215,10 @@ func GetDecimalBigOpts(ctx *context.Context, tnt string, dP utils.DataProvider,
// returns the config option if at least one filter passes or the default value if none of them do
func GetInterfaceOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicInterfaceOpt,
optNames ...string) (cfgOpt any, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
return nil, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
return opt, nil
}
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
return opt, nil
} else if !errors.Is(err, utils.ErrNotFound) {
return false, err
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
@@ -309,22 +237,14 @@ func GetInterfaceOpts(ctx *context.Context, tnt string, dP utils.DataProvider, f
// returns the config option if at least one filter passes or NOT_FOUND if none of them do
func GetIntPointerOpts(ctx *context.Context, tnt string, dP utils.DataProvider, fS *FilterS, dynOpts []*config.DynamicIntPointerOpt,
optNames ...string) (cfgOpt *int, err error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
return nil, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return
}
for _, optName := range optNames {
if opt, has := opts[optName]; has {
var value int64
if value, err = utils.IfaceAsTInt64(opt); err != nil {
return nil, err
}
return utils.IntPointer(int(value)), nil
if opt, err := optIfaceFromDP(dP, optNames); err == nil {
var value int
if value, err = utils.IfaceAsInt(opt); err != nil {
return nil, err
}
return utils.IntPointer(value), nil
} else if !errors.Is(err, utils.ErrNotFound) {
return nil, err
}
for _, opt := range dynOpts { // iterate through the options
if !slices.Contains([]string{utils.EmptyString, utils.MetaAny, tnt}, opt.Tenant) {
@@ -423,3 +343,21 @@ func ConvertOptsToMapStringAny(in any) (map[string]any, error) {
}
return out, nil
}
// getOptIfaceFromDP is a helper that returns the first option (as interface{}) found in the data provider
func optIfaceFromDP(dP utils.DataProvider, optNames []string) (any, error) {
values, err := dP.FieldAsInterface([]string{utils.MetaOpts})
if err != nil {
return nil, err
}
opts, err := ConvertOptsToMapStringAny(values)
if err != nil {
return nil, err
}
for _, optName := range optNames {
if opt, ok := opts[optName]; ok {
return opt, nil
}
}
return nil, utils.ErrNotFound
}

View File

@@ -2668,3 +2668,42 @@ func TestGetBoolOptsCantCastErr(t *testing.T) {
}
}
func TestOptIfaceFromDP(t *testing.T) {
tests := []struct {
name string
values []string
exp any
err error
}{
{name: "TestOptBoolValue", values: []string{utils.MetaProfileIgnoreFilters}, exp: true, err: nil},
{name: "TestOptBoolValue", values: []string{utils.OptsRoutesIgnoreErrors}, exp: true, err: nil},
{name: "TestOptFloat64Value", values: []string{utils.OptsAttributesProcessRuns}, exp: 5, err: nil},
{name: "TestOptIntValue", values: []string{utils.OptsResourcesUnits}, exp: float64(23.1), err: nil},
{name: "TestOptIntValue", values: []string{utils.OptsAttributesProfileRuns}, exp: 3, err: nil},
{name: "TestOptStringValue", values: []string{utils.OptsRatesStartTime}, exp: "2021-01-01T00:00:00Z", err: nil},
{name: "TestOptFloat64Value", values: []string{utils.OptsResourcesUsageID}, exp: "RES1", err: nil},
{name: "TestFieldNotExist", values: []string{"field1"}, err: utils.ErrNotFound},
}
cgrEv := utils.MapStorage{
utils.MetaReq: map[string]any{},
utils.MetaOpts: map[string]any{
utils.MetaProfileIgnoreFilters: true,
utils.OptsRoutesIgnoreErrors: true,
utils.OptsAttributesProcessRuns: 5,
utils.OptsAttributesProfileRuns: 3,
utils.OptsRatesStartTime: "2021-01-01T00:00:00Z",
utils.OptsResourcesUsageID: "RES1",
utils.OptsResourcesUnits: 23.1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if rcv, err := optIfaceFromDP(cgrEv, tt.values); err != tt.err {
t.Errorf("expected: <%v>,\nreceived: <%v>", tt.err, err)
} else if rcv != tt.exp {
t.Errorf("expected: <%v>,\nreceived: <%v>", tt.exp, rcv)
}
})
}
}