Implement pagination for rates

This commit is contained in:
ionutboangiu
2022-03-30 16:56:05 +03:00
committed by Dan Christian Bogos
parent 1c6176675b
commit f2180fbc2f
4 changed files with 108 additions and 6 deletions

View File

@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package apis
import (
"sort"
"time"
"github.com/cgrates/birpc/context"
@@ -28,7 +29,7 @@ import (
)
// GetRateProfile returns a Rate Profile based on tenant and id
func (admS *AdminSv1) GetRateProfile(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *utils.RateProfile) error {
func (admS *AdminSv1) GetRateProfile(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *utils.RateProfile) (err error) {
if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing
return utils.NewErrMandatoryIeMissing(missing...)
}
@@ -36,16 +37,48 @@ func (admS *AdminSv1) GetRateProfile(ctx *context.Context, arg *utils.TenantIDWi
if tnt == utils.EmptyString {
tnt = admS.cfg.GeneralCfg().DefaultTenant
}
rPrf, err := admS.dm.GetRateProfile(ctx, tnt, arg.ID, true, true, utils.NonTransactional)
var rPrf *utils.RateProfile
rPrf, err = admS.dm.GetRateProfile(ctx, tnt, arg.ID, true, true, utils.NonTransactional)
if err != nil {
if err.Error() != utils.ErrNotFound.Error() {
err = utils.NewErrServerError(err)
}
return err
return
}
rateIDs := make([]string, len(rPrf.Rates))
i := 0
for rateID := range rPrf.Rates {
rateIDs[i] = rateID
i++
}
sort.Strings(rateIDs)
var limit, offset, maxItems int
// if limit, err = engine.GetIntOpts(ctx, tnt, nil, nil, admS.cfg.RateSCfg().Opts.Limit,
// config.RatesLimitDftOpt, utils.OptsRatesLimit); err != nil {
// return
// }
// if offset, err = engine.GetIntOpts(ctx, tnt, nil, nil, admS.cfg.RateSCfg().Opts.Offset,
// config.RatesLimitDftOpt, utils.OptsRatesOffset); err != nil {
// return
// }
// if maxItems, err = engine.GetIntOpts(ctx, tnt, nil, nil, admS.cfg.RateSCfg().Opts.Limit,
// config.RatesLimitDftOpt, utils.OptsRatesMaxItems); err != nil {
// return
// }
if limit, offset, maxItems, err = utils.GetPaginateOpts(arg.APIOpts); err != nil {
return
}
rateIDs, err = utils.Paginate(rateIDs, limit, offset, maxItems)
if err != nil {
return
}
paginatedRates := make(map[string]*utils.Rate)
for _, rateID := range rateIDs {
paginatedRates[rateID] = rPrf.Rates[rateID]
}
rPrf.Rates = paginatedRates
*reply = *rPrf
return nil
return
}
// GetRateProfile returns the rates of a profile based on their profile. Those rates will be returned back by matching a prefix.

View File

@@ -1564,7 +1564,28 @@ const CGRATES_CFG_JSON = `
// "FilterIDs": [],
// "Value": false,
// },
],
],
// "*limit": [
// {
// "Tenant": "*any",
// "FilterIDs": [],
// "Value": 1,
// },
// ],
// "*offset": [
// {
// "Tenant": "*any",
// "FilterIDs": [],
// "Value": 1,
// },
// ],
// "*maxItems": [
// {
// "Tenant": "*any",
// "FilterIDs": [],
// "Value": 1,
// },
// ],
},
},

View File

@@ -35,6 +35,9 @@ var (
const (
RatesStartTimeDftOpt = "*now"
RatesProfileIgnoreFiltersDftOpt = false
RatesLimitDftOpt = 0
RatesOffsetDftOpt = 0
RatesMaxItemsDftOpt = 0
)
type RatesOpts struct {
@@ -43,6 +46,9 @@ type RatesOpts struct {
Usage []*utils.DynamicDecimalBigOpt
IntervalStart []*utils.DynamicDecimalBigOpt
ProfileIgnoreFilters []*utils.DynamicBoolOpt
Limit []*utils.DynamicIntOpt
Offset []*utils.DynamicIntOpt
MaxItems []*utils.DynamicIntOpt
}
// RateSCfg the rates config section
@@ -102,6 +108,15 @@ func (rateOpts *RatesOpts) loadFromJSONCfg(jsnCfg *RatesOptsJson) (err error) {
if jsnCfg.ProfileIgnoreFilters != nil {
rateOpts.ProfileIgnoreFilters = append(rateOpts.ProfileIgnoreFilters, jsnCfg.ProfileIgnoreFilters...)
}
if jsnCfg.Limit != nil {
rateOpts.Limit = append(rateOpts.Limit, jsnCfg.Limit...)
}
if jsnCfg.Offset != nil {
rateOpts.Offset = append(rateOpts.Offset, jsnCfg.Offset...)
}
if jsnCfg.MaxItems != nil {
rateOpts.MaxItems = append(rateOpts.MaxItems, jsnCfg.MaxItems...)
}
return
}
@@ -172,6 +187,9 @@ func (rCfg RateSCfg) AsMapInterface(string) interface{} {
utils.MetaUsage: rCfg.Opts.Usage,
utils.MetaIntervalStartCfg: rCfg.Opts.IntervalStart,
utils.MetaProfileIgnoreFilters: rCfg.Opts.ProfileIgnoreFilters,
utils.MetaLimitCfg: rCfg.Opts.Limit,
utils.MetaOffsetCfg: rCfg.Opts.Offset,
utils.MetaMaxItemsCfg: rCfg.Opts.MaxItems,
}
mp := map[string]interface{}{
utils.EnabledCfg: rCfg.Enabled,
@@ -239,12 +257,27 @@ func (rateOpts *RatesOpts) Clone() *RatesOpts {
if rateOpts.ProfileIgnoreFilters != nil {
profileIgnoreFilters = utils.CloneDynamicBoolOpt(rateOpts.ProfileIgnoreFilters)
}
var limit []*utils.DynamicIntOpt
if rateOpts.Limit != nil {
limit = utils.CloneDynamicIntOpt(rateOpts.Limit)
}
var offset []*utils.DynamicIntOpt
if rateOpts.Offset != nil {
offset = utils.CloneDynamicIntOpt(rateOpts.Offset)
}
var maxItems []*utils.DynamicIntOpt
if rateOpts.MaxItems != nil {
maxItems = utils.CloneDynamicIntOpt(rateOpts.MaxItems)
}
return &RatesOpts{
ProfileIDs: ratePrfIDs,
StartTime: startTime,
Usage: usage,
IntervalStart: intervalStart,
ProfileIgnoreFilters: profileIgnoreFilters,
Limit: limit,
Offset: offset,
MaxItems: maxItems,
}
}
@@ -298,6 +331,9 @@ type RatesOptsJson struct {
Usage []*utils.DynamicStringOpt `json:"*usage"`
IntervalStart []*utils.DynamicStringOpt `json:"*intervalStart"`
ProfileIgnoreFilters []*utils.DynamicBoolOpt `json:"*profileIgnoreFilters"`
Limit []*utils.DynamicIntOpt `json:"*limit"`
Offset []*utils.DynamicIntOpt `json:"*offset"`
MaxItems []*utils.DynamicIntOpt `json:"*maxItems"`
}
type RateSJsonCfg struct {
@@ -339,6 +375,15 @@ func diffRatesOptsJsonCfg(d *RatesOptsJson, v1, v2 *RatesOpts) *RatesOptsJson {
if !utils.DynamicBoolOptEqual(v1.ProfileIgnoreFilters, v2.ProfileIgnoreFilters) {
d.ProfileIgnoreFilters = v2.ProfileIgnoreFilters
}
if !utils.DynamicIntOptEqual(v1.Limit, v2.Limit) {
d.Limit = v2.Limit
}
if !utils.DynamicIntOptEqual(v1.Offset, v2.Offset) {
d.Offset = v2.Offset
}
if !utils.DynamicIntOptEqual(v1.MaxItems, v2.MaxItems) {
d.MaxItems = v2.MaxItems
}
return d
}

View File

@@ -2281,6 +2281,9 @@ const (
OptsRatesStartTime = "*rtsStartTime"
OptsRatesUsage = "*rtsUsage"
OptsRatesIntervalStart = "*rtsIntervalStart"
OptsRatesLimit = "*rtsLimit"
OptsRatesOffset = "*rtsOffset"
OptsRatesMaxItems = "*rtsMaxItems"
// Resources
OptsResourcesUnits = "*rsUnits"