From 2ccf3f7fa5e097b9211fc87cfcd6e75669e5a6cb Mon Sep 17 00:00:00 2001 From: porosnicuadrian Date: Fri, 19 Feb 2021 16:55:00 +0200 Subject: [PATCH] New type ResourceWithConfig + Available method --- apier/v1/api_interfaces.go | 1 + apier/v1/dispatcher.go | 4 ++++ apier/v1/resourcesv1.go | 4 ++++ dispatchers/resources.go | 18 ++++++++++++++++++ engine/dynamicdp.go | 4 ++-- engine/resources.go | 37 +++++++++++++++++++++++++++++++++++-- utils/consts.go | 21 +++++++++++---------- 7 files changed, 75 insertions(+), 14 deletions(-) diff --git a/apier/v1/api_interfaces.go b/apier/v1/api_interfaces.go index b497f7765..c57c6f956 100644 --- a/apier/v1/api_interfaces.go +++ b/apier/v1/api_interfaces.go @@ -52,6 +52,7 @@ type ResourceSv1Interface interface { AllocateResources(args *utils.ArgRSv1ResourceUsage, reply *string) error ReleaseResources(args *utils.ArgRSv1ResourceUsage, reply *string) error GetResource(args *utils.TenantIDWithOpts, reply *engine.Resource) error + GetResourceWithConfig(args *utils.TenantIDWithOpts, reply *engine.ResourceWithConfig) error Ping(ign *utils.CGREvent, reply *string) error } diff --git a/apier/v1/dispatcher.go b/apier/v1/dispatcher.go index ea63e0332..5154ba5a3 100755 --- a/apier/v1/dispatcher.go +++ b/apier/v1/dispatcher.go @@ -319,6 +319,10 @@ func (dRs *DispatcherResourceSv1) GetResource(args *utils.TenantIDWithOpts, repl return dRs.dRs.ResourceSv1GetResource(args, reply) } +func (dRs *DispatcherResourceSv1) GetResourceWithConfig(args *utils.TenantIDWithOpts, reply *engine.ResourceWithConfig) error { + return dRs.dRs.ResourceSv1GetResourceWithConfig(args, reply) +} + func (dRs *DispatcherResourceSv1) AuthorizeResources(args *utils.ArgRSv1ResourceUsage, reply *string) error { return dRs.dRs.ResourceSv1AuthorizeResources(*args, reply) diff --git a/apier/v1/resourcesv1.go b/apier/v1/resourcesv1.go index dc17976eb..38d393244 100644 --- a/apier/v1/resourcesv1.go +++ b/apier/v1/resourcesv1.go @@ -64,6 +64,10 @@ func (rsv1 *ResourceSv1) GetResource(args *utils.TenantIDWithOpts, reply *engine return rsv1.rls.V1GetResource(args, reply) } +func (rsv1 *ResourceSv1) GetResourceWithConfig(args *utils.TenantIDWithOpts, reply *engine.ResourceWithConfig) error { + return rsv1.rls.V1GetResourceWithConfig(args, reply) +} + // GetResourceProfile returns a resource configuration func (apierSv1 *APIerSv1) GetResourceProfile(arg *utils.TenantID, reply *engine.ResourceProfile) error { if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing diff --git a/dispatchers/resources.go b/dispatchers/resources.go index 16442b4ad..d8fab056d 100755 --- a/dispatchers/resources.go +++ b/dispatchers/resources.go @@ -116,3 +116,21 @@ func (dS *DispatcherService) ResourceSv1GetResource(args *utils.TenantIDWithOpts Opts: args.Opts, }, utils.MetaResources, utils.ResourceSv1GetResource, args, reply) } + +func (dS *DispatcherService) ResourceSv1GetResourceWithConfig(args *utils.TenantIDWithOpts, reply *engine.ResourceWithConfig) (err error) { + tnt := dS.cfg.GeneralCfg().DefaultTenant + if args.TenantID != nil && args.TenantID.Tenant != utils.EmptyString { + tnt = args.TenantID.Tenant + } + if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { + if err = dS.authorize(utils.ResourceSv1GetResourceWithConfig, tnt, + utils.IfaceAsString(args.Opts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil { + return + } + } + return dS.Dispatch(&utils.CGREvent{ + Tenant: tnt, + ID: args.ID, + Opts: args.Opts, + }, utils.MetaResources, utils.ResourceSv1GetResourceWithConfig, args, reply) +} diff --git a/engine/dynamicdp.go b/engine/dynamicdp.go index 6b8e8b193..67bab49fd 100644 --- a/engine/dynamicdp.go +++ b/engine/dynamicdp.go @@ -101,8 +101,8 @@ func (dDP *dynamicDP) fieldAsInterface(fldPath []string) (val interface{}, err e return dp.FieldAsInterface(fldPath[2:]) case utils.MetaResources: // sample of fieldName : ~*resources.ResourceID.Field - var reply *Resource - if err := connMgr.Call(dDP.resConns, nil, utils.ResourceSv1GetResource, + var reply *ResourceWithConfig + if err := connMgr.Call(dDP.resConns, nil, utils.ResourceSv1GetResourceWithConfig, &utils.TenantID{Tenant: dDP.tenant, ID: fldPath[1]}, &reply); err != nil { return nil, err } diff --git a/engine/resources.go b/engine/resources.go index cd54c82a3..d909d6a01 100644 --- a/engine/resources.go +++ b/engine/resources.go @@ -162,8 +162,8 @@ func (r *Resource) TotalUsage() (tU float64) { // Available returns the available number of units // Exported method to be used by filterS -func (r *Resource) Available() float64 { - return r.rPrf.Limit - r.totalUsage() +func (r *ResourceWithConfig) Available() float64 { + return r.Config.Limit - r.totalUsage() } // recordUsage records a new usage @@ -815,6 +815,39 @@ func (rS *ResourceService) V1GetResource(arg *utils.TenantIDWithOpts, reply *Res return nil } +type ResourceWithConfig struct { + *Resource + Config *ResourceProfile +} + +func (rS *ResourceService) V1GetResourceWithConfig(arg *utils.TenantIDWithOpts, reply *ResourceWithConfig) (err error) { + if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + tnt := arg.Tenant + if tnt == utils.EmptyString { + tnt = rS.cgrcfg.GeneralCfg().DefaultTenant + } + var res *Resource + res, err = rS.dm.GetResource(tnt, arg.ID, true, true, utils.NonTransactional) + if err != nil { + return + } + if res.rPrf == nil { + var cfg *ResourceProfile + cfg, err = rS.dm.GetResourceProfile(tnt, arg.ID, true, true, utils.NonTransactional) + if err != nil { + return + } + res.rPrf = cfg + } + *reply = ResourceWithConfig{ + Resource: res, + Config: res.rPrf, + } + return +} + // Reload stops the backupLoop and restarts it func (rS *ResourceService) Reload() { close(rS.stopBackup) diff --git a/utils/consts.go b/utils/consts.go index 0b60057e9..af6f0342b 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -1648,16 +1648,17 @@ const ( // ResourceS APIs const ( - ResourceSv1AuthorizeResources = "ResourceSv1.AuthorizeResources" - ResourceSv1GetResourcesForEvent = "ResourceSv1.GetResourcesForEvent" - ResourceSv1AllocateResources = "ResourceSv1.AllocateResources" - ResourceSv1ReleaseResources = "ResourceSv1.ReleaseResources" - ResourceSv1Ping = "ResourceSv1.Ping" - ResourceSv1GetResource = "ResourceSv1.GetResource" - APIerSv1SetResourceProfile = "APIerSv1.SetResourceProfile" - APIerSv1RemoveResourceProfile = "APIerSv1.RemoveResourceProfile" - APIerSv1GetResourceProfile = "APIerSv1.GetResourceProfile" - APIerSv1GetResourceProfileIDs = "APIerSv1.GetResourceProfileIDs" + ResourceSv1AuthorizeResources = "ResourceSv1.AuthorizeResources" + ResourceSv1GetResourcesForEvent = "ResourceSv1.GetResourcesForEvent" + ResourceSv1AllocateResources = "ResourceSv1.AllocateResources" + ResourceSv1ReleaseResources = "ResourceSv1.ReleaseResources" + ResourceSv1Ping = "ResourceSv1.Ping" + ResourceSv1GetResourceWithConfig = "ResourceSv1.GetResourceWithConfig" + ResourceSv1GetResource = "ResourceSv1.GetResource" + APIerSv1SetResourceProfile = "APIerSv1.SetResourceProfile" + APIerSv1RemoveResourceProfile = "APIerSv1.RemoveResourceProfile" + APIerSv1GetResourceProfile = "APIerSv1.GetResourceProfile" + APIerSv1GetResourceProfileIDs = "APIerSv1.GetResourceProfileIDs" ) // SessionS APIs