Change types of resources opts to map

This commit is contained in:
ionutboangiu
2021-09-24 18:42:20 +03:00
committed by Dan Christian Bogos
parent 91d56988a3
commit 7d01526866
8 changed files with 227 additions and 84 deletions

View File

@@ -697,8 +697,8 @@ const CGRATES_CFG_JSON = `
"nested_fields": false, // determines which field is checked when matching indexed filters(true: all; false: only the one on the first level)
"opts":{ //
// "*usageID": "", //
"*usageTTL": "1m", //
"*units": 1, //
// "*usageTTL": "1m", //
// "*units": 1, //
},
},

View File

@@ -313,8 +313,12 @@ func testCGRConfigReloadResourceS(t *testing.T) {
IndexedSelects: true,
ThresholdSConns: []string{utils.MetaLocalHost},
Opts: &ResourcesOpts{
UsageTTL: utils.DurationPointer(time.Duration(time.Minute)),
Units: 1,
UsageTTL: map[string]time.Duration{
utils.EmptyString: time.Minute,
},
Units: map[string]float64{
utils.EmptyString: float64(1),
},
},
}
if !reflect.DeepEqual(expAttr, cfg.ResourceSCfg()) {

View File

@@ -835,10 +835,7 @@ func TestDfResourceLimiterSJsonCfg(t *testing.T) {
Prefix_indexed_fields: &[]string{},
Suffix_indexed_fields: &[]string{},
Nested_fields: utils.BoolPointer(false),
Opts: &ResourcesOptsJson{
UsageTTL: utils.StringPointer("1m"),
Units: utils.Float64Pointer(1),
},
Opts: &ResourcesOptsJson{},
}
dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
if err != nil {

File diff suppressed because one or more lines are too long

View File

@@ -26,9 +26,9 @@ import (
)
type ResourcesOpts struct {
UsageID string
UsageTTL *time.Duration
Units float64
UsageID map[string]string
UsageTTL map[string]time.Duration
Units map[string]float64
}
// ResourceSConfig is resorces section config
@@ -58,17 +58,19 @@ func (rsOpts *ResourcesOpts) loadFromJSONCfg(jsnCfg *ResourcesOptsJson) (err err
return nil
}
if jsnCfg.UsageID != nil {
rsOpts.UsageID = *jsnCfg.UsageID
rsOpts.UsageID = jsnCfg.UsageID
}
if jsnCfg.UsageTTL != nil {
var usageTTL time.Duration
if usageTTL, err = utils.ParseDurationWithNanosecs(*jsnCfg.UsageTTL); err != nil {
return
for key, durStr := range jsnCfg.UsageTTL {
var usageTTL time.Duration
if usageTTL, err = utils.ParseDurationWithNanosecs(durStr); err != nil {
return
}
rsOpts.UsageTTL[key] = usageTTL
}
rsOpts.UsageTTL = utils.DurationPointer(usageTTL)
}
if jsnCfg.Units != nil {
rsOpts.Units = *jsnCfg.Units
rsOpts.Units = jsnCfg.Units
}
return nil
@@ -113,11 +115,9 @@ func (rlcfg *ResourceSConfig) loadFromJSONCfg(jsnCfg *ResourceSJsonCfg) (err err
// AsMapInterface returns the config as a map[string]interface{}
func (rlcfg ResourceSConfig) AsMapInterface(string) interface{} {
opts := map[string]interface{}{
utils.MetaUsageIDCfg: rlcfg.Opts.UsageID,
utils.MetaUnitsCfg: rlcfg.Opts.Units,
}
if rlcfg.Opts.UsageTTL != nil {
opts[utils.MetaUsageTTLCfg] = (*rlcfg.Opts.UsageTTL).String()
utils.MetaUsageIDCfg: rlcfg.Opts.UsageID,
utils.MetaUsageTTLCfg: rlcfg.Opts.UsageTTL,
utils.MetaUnitsCfg: rlcfg.Opts.Units,
}
mp := map[string]interface{}{
utils.EnabledCfg: rlcfg.Enabled,
@@ -149,11 +149,9 @@ func (rlcfg ResourceSConfig) CloneSection() Section { return rlcfg.Clone() }
func (rsOpts *ResourcesOpts) Clone() (cln *ResourcesOpts) {
cln = &ResourcesOpts{
UsageID: rsOpts.UsageID,
Units: rsOpts.Units,
}
if rsOpts.UsageTTL != nil {
cln.UsageTTL = utils.DurationPointer(*rsOpts.UsageTTL)
UsageID: rsOpts.UsageID,
UsageTTL: rsOpts.UsageTTL,
Units: rsOpts.Units,
}
return
}
@@ -184,9 +182,9 @@ func (rlcfg ResourceSConfig) Clone() (cln *ResourceSConfig) {
}
type ResourcesOptsJson struct {
UsageID *string `json:"*usageID"`
UsageTTL *string `json:"*usageTTL"`
Units *float64 `json:"*units"`
UsageID map[string]string `json:"*usageID"`
UsageTTL map[string]string `json:"*usageTTL"`
Units map[string]float64 `json:"*units"`
}
// ResourceLimiter service config section
@@ -206,15 +204,9 @@ func diffResourcesOptsJsonCfg(d *ResourcesOptsJson, v1, v2 *ResourcesOpts) *Reso
if d == nil {
d = new(ResourcesOptsJson)
}
if v1.UsageID != v2.UsageID {
d.UsageID = utils.StringPointer(v2.UsageID)
}
if v1.UsageTTL != v2.UsageTTL {
d.UsageTTL = utils.StringPointer((*v2.UsageTTL).String())
}
if v1.Units != v2.Units {
d.Units = utils.Float64Pointer(v2.Units)
}
d.UsageID = diffMapStringString(d.UsageID, v1.UsageID, v2.UsageID)
d.UsageTTL = diffMapStringDuration(d.UsageTTL, v1.UsageTTL, v2.UsageTTL)
d.Units = diffMapStringFloat64(d.Units, v1.Units, v2.Units)
return d
}
@@ -243,3 +235,39 @@ func diffResourceSJsonCfg(d *ResourceSJsonCfg, v1, v2 *ResourceSConfig) *Resourc
d.Opts = diffResourcesOptsJsonCfg(d.Opts, v1.Opts, v2.Opts)
return d
}
func diffMapStringString(d, v1, v2 map[string]string) map[string]string {
if d == nil {
d = make(map[string]string)
}
for k, v := range v2 {
if val, has := v1[k]; !has || val != v {
d[k] = v
}
}
return d
}
func diffMapStringFloat64(d, v1, v2 map[string]float64) map[string]float64 {
if d == nil {
d = make(map[string]float64)
}
for k, v := range v2 {
if val, has := v1[k]; !has || val != v {
d[k] = v
}
}
return d
}
func diffMapStringDuration(d map[string]string, v1, v2 map[string]time.Duration) map[string]string {
if d == nil {
d = make(map[string]string)
}
for k, v := range v2 {
if val, has := v1[k]; !has || val != v {
d[k] = v.String()
}
}
return d
}

View File

@@ -45,10 +45,7 @@ func TestResourceSConfigloadFromJsonCfgCase1(t *testing.T) {
PrefixIndexedFields: &[]string{"*req.index1"},
SuffixIndexedFields: &[]string{"*req.index1"},
NestedFields: true,
Opts: &ResourcesOpts{
UsageTTL: utils.DurationPointer(time.Duration(time.Minute)),
Units: 1,
},
Opts: &ResourcesOpts{},
}
cfg := NewDefaultCGRConfig()
if err = cfg.resourceSCfg.loadFromJSONCfg(cfgJSON); err != nil {
@@ -82,9 +79,9 @@ func TestResourceSConfigAsMapInterface(t *testing.T) {
utils.SuffixIndexedFieldsCfg: []string{},
utils.NestedFieldsCfg: false,
utils.OptsCfg: map[string]interface{}{
utils.MetaUsageIDCfg: utils.EmptyString,
utils.MetaUsageTTLCfg: time.Duration(time.Minute).String(),
utils.MetaUnitsCfg: float64(1),
utils.MetaUsageIDCfg: map[string]string(nil),
utils.MetaUsageTTLCfg: map[string]time.Duration(nil),
utils.MetaUnitsCfg: map[string]float64(nil),
},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
@@ -117,9 +114,9 @@ func TestResourceSConfigAsMapInterface1(t *testing.T) {
utils.SuffixIndexedFieldsCfg: []string{"*req.prefix_indexed_fields1"},
utils.NestedFieldsCfg: true,
utils.OptsCfg: map[string]interface{}{
utils.MetaUsageIDCfg: utils.EmptyString,
utils.MetaUsageTTLCfg: time.Duration(time.Minute).String(),
utils.MetaUnitsCfg: float64(1),
utils.MetaUsageIDCfg: map[string]string(nil),
utils.MetaUsageTTLCfg: map[string]time.Duration(nil),
utils.MetaUnitsCfg: map[string]float64(nil),
},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
@@ -172,9 +169,15 @@ func TestDiffResourceSJsonCfg(t *testing.T) {
SuffixIndexedFields: &[]string{"*req.index3"},
NestedFields: false,
Opts: &ResourcesOpts{
UsageID: "usg1",
UsageTTL: utils.DurationPointer(time.Second),
Units: 1,
UsageID: map[string]string{
utils.EmptyString: "usg1",
},
UsageTTL: map[string]time.Duration{
utils.EmptyString: time.Second,
},
Units: map[string]float64{
utils.EmptyString: float64(1),
},
},
}
@@ -188,9 +191,15 @@ func TestDiffResourceSJsonCfg(t *testing.T) {
SuffixIndexedFields: &[]string{"*req.index33"},
NestedFields: true,
Opts: &ResourcesOpts{
UsageID: "usg2",
UsageTTL: utils.DurationPointer(time.Minute),
Units: 2,
UsageID: map[string]string{
utils.EmptyString: "usg2",
},
UsageTTL: map[string]time.Duration{
utils.EmptyString: time.Minute,
},
Units: map[string]float64{
utils.EmptyString: float64(2),
},
},
}
@@ -204,9 +213,15 @@ func TestDiffResourceSJsonCfg(t *testing.T) {
Suffix_indexed_fields: &[]string{"*req.index33"},
Nested_fields: utils.BoolPointer(true),
Opts: &ResourcesOptsJson{
UsageID: utils.StringPointer("usg2"),
UsageTTL: utils.StringPointer("1m0s"),
Units: utils.Float64Pointer(2),
UsageID: map[string]string{
utils.EmptyString: "usg2",
},
UsageTTL: map[string]string{
utils.EmptyString: "1m0s",
},
Units: map[string]float64{
utils.EmptyString: float64(2),
},
},
}
@@ -217,7 +232,11 @@ func TestDiffResourceSJsonCfg(t *testing.T) {
v1 = v2
expected = &ResourceSJsonCfg{
Opts: &ResourcesOptsJson{},
Opts: &ResourcesOptsJson{
UsageID: make(map[string]string),
UsageTTL: make(map[string]string),
Units: make(map[string]float64),
},
}
rcv = diffResourceSJsonCfg(d, v1, v2)
if !reflect.DeepEqual(rcv, expected) {

View File

@@ -680,3 +680,54 @@ func (fltr *FilterRule) passRegex(dDP utils.DataProvider) (bool, error) {
}
return false, nil
}
func filterFloat64CfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, opts map[string]float64) (float64, error) {
for filter, opt := range opts {
if filter == utils.EmptyString {
continue
}
if pass, err := fS.Pass(ctx, tnt, []string{filter}, ev); err != nil {
return 0, err
} else if pass {
return opt, nil
}
}
if opt, has := opts[utils.EmptyString]; has {
return opt, nil
}
return 0, utils.ErrNotFound
}
func filterDurationCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, opts map[string]time.Duration) (time.Duration, error) {
for filter, opt := range opts {
if filter == utils.EmptyString {
continue
}
if pass, err := fS.Pass(ctx, tnt, []string{filter}, ev); err != nil {
return 0, err
} else if pass {
return opt, nil
}
}
if opt, has := opts[utils.EmptyString]; has {
return opt, nil
}
return 0, utils.ErrNotFound
}
func filterStringCfgOpts(ctx *context.Context, tnt string, ev utils.DataProvider, fS *FilterS, opts map[string]string) (string, error) {
for filter, opt := range opts {
if filter == utils.EmptyString {
continue
}
if pass, err := fS.Pass(ctx, tnt, []string{filter}, ev); err != nil {
return utils.EmptyString, err
} else if pass {
return opt, nil
}
}
if opt, has := opts[utils.EmptyString]; has {
return opt, nil
}
return utils.EmptyString, utils.ErrNotFound
}

View File

@@ -673,9 +673,19 @@ func (rS *ResourceService) V1ResourcesForEvent(ctx *context.Context, args *utils
return utils.NewErrMandatoryIeMissing(missing...)
}
usageID := args.OptsAsString(rS.cgrcfg.ResourceSCfg().Opts.UsageID, utils.OptsResourcesUsageID)
var usageID string
if usageID, err = filterStringCfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.UsageID); err != nil {
return
}
usageID = args.OptsAsString(usageID, utils.OptsResourcesUsageID)
var ttl time.Duration
if ttl, err = args.OptsAsDuration(*rS.cgrcfg.ResourceSCfg().Opts.UsageTTL, utils.OptsResourcesUsageTTL); err != nil {
if ttl, err = filterDurationCfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.UsageTTL); err != nil {
return
}
if ttl, err = args.OptsAsDuration(ttl, utils.OptsResourcesUsageTTL); err != nil {
return
}
usageTTL := utils.DurationPointer(ttl)
@@ -725,13 +735,28 @@ func (rS *ResourceService) V1AuthorizeResources(ctx *context.Context, args *util
return utils.NewErrMandatoryIeMissing(missing...)
}
usageID := args.OptsAsString(rS.cgrcfg.ResourceSCfg().Opts.UsageID, utils.OptsResourcesUsageID)
var units float64
if units, err = args.OptsAsFloat64(rS.cgrcfg.ResourceSCfg().Opts.Units, utils.OptsResourcesUnits); err != nil {
var usageID string
if usageID, err = filterStringCfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.UsageID); err != nil {
return
}
usageID = args.OptsAsString(usageID, utils.OptsResourcesUsageID)
var units float64
if units, err = filterFloat64CfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.Units); err != nil {
return
}
if units, err = args.OptsAsFloat64(units, utils.OptsResourcesUnits); err != nil {
return
}
var ttl time.Duration
if ttl, err = args.OptsAsDuration(*rS.cgrcfg.ResourceSCfg().Opts.UsageTTL, utils.OptsResourcesUsageTTL); err != nil {
if ttl, err = filterDurationCfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.UsageTTL); err != nil {
return
}
if ttl, err = args.OptsAsDuration(ttl, utils.OptsResourcesUsageTTL); err != nil {
return
}
usageTTL := utils.DurationPointer(ttl)
@@ -793,13 +818,28 @@ func (rS *ResourceService) V1AllocateResources(ctx *context.Context, args *utils
return utils.NewErrMandatoryIeMissing(missing...)
}
usageID := args.OptsAsString(rS.cgrcfg.ResourceSCfg().Opts.UsageID, utils.OptsResourcesUsageID)
var units float64
if units, err = args.OptsAsFloat64(rS.cgrcfg.ResourceSCfg().Opts.Units, utils.OptsResourcesUnits); err != nil {
var usageID string
if usageID, err = filterStringCfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.UsageID); err != nil {
return
}
usageID = args.OptsAsString(usageID, utils.OptsResourcesUsageID)
var units float64
if units, err = filterFloat64CfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.Units); err != nil {
return
}
if units, err = args.OptsAsFloat64(units, utils.OptsResourcesUnits); err != nil {
return
}
var ttl time.Duration
if ttl, err = args.OptsAsDuration(*rS.cgrcfg.ResourceSCfg().Opts.UsageTTL, utils.OptsResourcesUsageTTL); err != nil {
if ttl, err = filterDurationCfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.UsageTTL); err != nil {
return
}
if ttl, err = args.OptsAsDuration(ttl, utils.OptsResourcesUsageTTL); err != nil {
return
}
usageTTL := utils.DurationPointer(ttl)
@@ -865,9 +905,19 @@ func (rS *ResourceService) V1ReleaseResources(ctx *context.Context, args *utils.
return utils.NewErrMandatoryIeMissing(missing...)
}
usageID := args.OptsAsString(rS.cgrcfg.ResourceSCfg().Opts.UsageID, utils.OptsResourcesUsageID)
var usageID string
if usageID, err = filterStringCfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.UsageID); err != nil {
return
}
usageID = args.OptsAsString(usageID, utils.OptsResourcesUsageID)
var ttl time.Duration
if ttl, err = args.OptsAsDuration(*rS.cgrcfg.ResourceSCfg().Opts.UsageTTL, utils.OptsResourcesUsageTTL); err != nil {
if ttl, err = filterDurationCfgOpts(ctx, args.Tenant, args.AsDataProvider(), rS.filterS,
rS.cgrcfg.ResourceSCfg().Opts.UsageTTL); err != nil {
return
}
if ttl, err = args.OptsAsDuration(ttl, utils.OptsResourcesUsageTTL); err != nil {
return
}
usageTTL := utils.DurationPointer(ttl)