From eeecae45764f8e646d80825cee522d581d3029eb Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Tue, 29 Apr 2025 02:04:00 +0300 Subject: [PATCH] move resources to dedicated package --- admins/resources.go | 11 +- apis/filter_indexes_it_test.go | 16 +- apis/filters_test.go | 8 +- apis/loaders_it_test.go | 6 +- apis/replicator.go | 8 +- apis/replicator_test.go | 52 +- apis/resources.go | 50 +- apis/resources_test.go | 278 +- apis/tpes_it_test.go | 8 +- cmd/cgr-loader/cgr-loader_remove_it_test.go | 14 +- console/resource_profile.go | 3 +- console/resource_profile_set.go | 9 +- console/resource_profiles.go | 3 +- console/resources.go | 3 +- console/resources_for_event.go | 4 +- engine/caches.go | 13 +- engine/connmanager_test.go | 12 + engine/datadbmock.go | 16 +- engine/datamanager.go | 28 +- engine/datamanager_test.go | 203 +- engine/dynamicdp.go | 2 +- engine/dynamicdp_test.go | 11 +- engine/libindex_health.go | 2 +- engine/libindex_test.go | 2 +- engine/model_helpers.go | 6 +- engine/model_helpers_test.go | 6 +- engine/storage_csv.go | 2 +- engine/storage_interface.go | 8 +- engine/storage_internal_datadb.go | 12 +- engine/storage_mongo_datadb.go | 12 +- engine/storage_redis.go | 8 +- engine/tpreader.go | 2 +- engine/version.go | 2 +- engine/version_test.go | 4 +- engine/z_filterindexer_it_test.go | 4 +- engine/z_libindex_health_test.go | 4 +- engine/z_onstor_it_test.go | 6 +- engine/z_versions_it_test.go | 2 +- flaky_test.sh | 2 +- general_tests/attributes_it_test.go | 6 +- general_tests/doubleremove_it_test.go | 6 +- general_tests/export_it_test.go | 4 +- general_tests/filtered_replication_it_test.go | 6 +- general_tests/filters_it_test.go | 12 +- general_tests/resourcesv1_it_test.go | 15 +- general_tests/route_it_test.go | 16 +- general_tests/routes_cases_it_test.go | 20 +- general_tests/set_rmv_prfl_dlay_it_test.go | 8 +- integration_test.sh | 2 +- loaders/libloader.go | 2 +- loaders/loader.go | 2 +- loaders/loader_test.go | 4 +- migrator/resource.go | 14 +- migrator/resource_it_test.go | 6 +- {engine => resources}/resources.go | 472 +- {apis => resources}/resources_it_test.go | 82 +- .../resources_test.go | 4377 +++++++---------- routes/libroutes.go | 4 +- routes/libroutes_test.go | 36 +- routes/route_resource_sort.go | 6 +- routes/route_resource_sort_test.go | 24 +- services/resources.go | 5 +- tpes/tpe_resources.go | 2 +- tpes/tpe_resources_test.go | 10 +- tpes/tpes_test.go | 2 +- utils/consts.go | 6 +- utils/resources.go | 242 + utils/resources_test.go | 391 ++ 68 files changed, 3191 insertions(+), 3433 deletions(-) rename {engine => resources}/resources.go (62%) rename {apis => resources}/resources_it_test.go (93%) rename engine/z_resources_test.go => resources/resources_test.go (59%) create mode 100644 utils/resources.go create mode 100644 utils/resources_test.go diff --git a/admins/resources.go b/admins/resources.go index 819856335..638f537c1 100644 --- a/admins/resources.go +++ b/admins/resources.go @@ -23,12 +23,11 @@ import ( "time" "github.com/cgrates/birpc/context" - "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) // GetResourceProfile returns a resource configuration -func (adms *AdminS) V1GetResourceProfile(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *engine.ResourceProfile) error { +func (adms *AdminS) V1GetResourceProfile(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *utils.ResourceProfile) error { if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } @@ -73,7 +72,7 @@ func (adms *AdminS) V1GetResourceProfileIDs(ctx *context.Context, args *utils.Ar } // GetResourceProfiles returns a list of resource profiles registered for a tenant -func (admS *AdminS) V1GetResourceProfiles(ctx *context.Context, args *utils.ArgsItemIDs, rsPrfs *[]*engine.ResourceProfile) (err error) { +func (admS *AdminS) V1GetResourceProfiles(ctx *context.Context, args *utils.ArgsItemIDs, rsPrfs *[]*utils.ResourceProfile) (err error) { tnt := args.Tenant if tnt == utils.EmptyString { tnt = admS.cfg.GeneralCfg().DefaultTenant @@ -82,9 +81,9 @@ func (admS *AdminS) V1GetResourceProfiles(ctx *context.Context, args *utils.Args if err = admS.V1GetResourceProfileIDs(ctx, args, &rsPrfIDs); err != nil { return } - *rsPrfs = make([]*engine.ResourceProfile, 0, len(rsPrfIDs)) + *rsPrfs = make([]*utils.ResourceProfile, 0, len(rsPrfIDs)) for _, rsPrfID := range rsPrfIDs { - var rsPrf *engine.ResourceProfile + var rsPrf *utils.ResourceProfile rsPrf, err = admS.dm.GetResourceProfile(ctx, tnt, rsPrfID, true, true, utils.NonTransactional) if err != nil { return utils.APIErrorHandler(err) @@ -114,7 +113,7 @@ func (admS *AdminS) V1GetResourceProfilesCount(ctx *context.Context, args *utils } // SetResourceProfile adds a new resource configuration -func (adms *AdminS) V1SetResourceProfile(ctx *context.Context, arg *engine.ResourceProfileWithAPIOpts, reply *string) (err error) { +func (adms *AdminS) V1SetResourceProfile(ctx *context.Context, arg *utils.ResourceProfileWithAPIOpts, reply *string) (err error) { if missing := utils.MissingStructFields(arg.ResourceProfile, []string{utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } diff --git a/apis/filter_indexes_it_test.go b/apis/filter_indexes_it_test.go index d32c0e89e..c5e21fafd 100644 --- a/apis/filter_indexes_it_test.go +++ b/apis/filter_indexes_it_test.go @@ -3340,8 +3340,8 @@ func testV1FIdxSetResourceSProfileWithFltr(t *testing.T) { } //we will a ResourceProfile with our filter and check the indexes - resPrfl := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + resPrfl := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RESOURCE1", FilterIDs: []string{"*string:~*req.Account:1001", @@ -3436,8 +3436,8 @@ func testV1FIdxSetResourceSMoreFltrsMoreIndexing(t *testing.T) { } //update our resourceProfile with our filter - resPrfl := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + resPrfl := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RESOURCE1", FilterIDs: []string{"*string:~*req.Account:1001", @@ -3542,8 +3542,8 @@ func testV1FIdxResourceSProfileComputeIndexes(t *testing.T) { func testV1FIdxResourceSMoreProfilesForFltrs(t *testing.T) { // we will add more resources with our filters for matching indexes - resPrfl1 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + resPrfl1 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RESOURCE2", FilterIDs: []string{"*string:~*req.Account:1001", @@ -3556,8 +3556,8 @@ func testV1FIdxResourceSMoreProfilesForFltrs(t *testing.T) { }}, }, } - resPrfl2 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + resPrfl2 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RESOURCE3", FilterIDs: []string{"*string:~*req.Account:1001", diff --git a/apis/filters_test.go b/apis/filters_test.go index 522da4e09..ae2dd89a6 100644 --- a/apis/filters_test.go +++ b/apis/filters_test.go @@ -895,8 +895,8 @@ func TestFiltersSetFilterReloadCache(t *testing.T) { t.Error(err) } - rsPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ ID: "RES_ID", FilterIDs: []string{"FLTR_ID"}, Weights: utils.DynamicWeights{ @@ -1067,8 +1067,8 @@ func TestFiltersSetFilterClearCache(t *testing.T) { t.Error(err) } - rsPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ ID: "RES_ID", FilterIDs: []string{"FLTR_ID"}, Weights: utils.DynamicWeights{ diff --git a/apis/loaders_it_test.go b/apis/loaders_it_test.go index f97c215cd..1c0a893dd 100644 --- a/apis/loaders_it_test.go +++ b/apis/loaders_it_test.go @@ -927,7 +927,7 @@ func testLoadersGetRateProfiles(t *testing.T) { } func testLoadersGetResourceProfiles(t *testing.T) { - expRsPrfs := []*engine.ResourceProfile{ + expRsPrfs := []*utils.ResourceProfile{ { Tenant: "cgrates.org", ID: "ResGroup21", @@ -957,7 +957,7 @@ func testLoadersGetResourceProfiles(t *testing.T) { Limit: 2, }, } - var rsPrfs []*engine.ResourceProfile + var rsPrfs []*utils.ResourceProfile if err := ldrRPC.Call(context.Background(), utils.AdminSv1GetResourceProfiles, &utils.ArgsItemIDs{ Tenant: "cgrates.org", @@ -1394,7 +1394,7 @@ func testLoadersGetResourceProfileAfterRemove(t *testing.T) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } - var rplyRsPrf engine.ResourceProfile + var rplyRsPrf utils.ResourceProfile if err := ldrRPC.Call(context.Background(), utils.AdminSv1GetResourceProfile, utils.TenantID{ Tenant: "cgrates.org", diff --git a/apis/replicator.go b/apis/replicator.go index f40ea3e22..cf08ff4e8 100644 --- a/apis/replicator.go +++ b/apis/replicator.go @@ -135,7 +135,7 @@ func (rplSv1 *ReplicatorSv1) GetTrendProfile(ctx *context.Context, tntID *utils. } // GetResource is the remote method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) GetResource(ctx *context.Context, tntID *utils.TenantIDWithAPIOpts, reply *engine.Resource) error { +func (rplSv1 *ReplicatorSv1) GetResource(ctx *context.Context, tntID *utils.TenantIDWithAPIOpts, reply *utils.Resource) error { engine.UpdateReplicationFilters(utils.ResourcesPrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.APIOpts[utils.RemoteHostOpt])) rcv, err := rplSv1.dm.DataDB().GetResourceDrv(ctx, tntID.Tenant, tntID.ID) if err != nil { @@ -146,7 +146,7 @@ func (rplSv1 *ReplicatorSv1) GetResource(ctx *context.Context, tntID *utils.Tena } // GetResourceProfile is the remote method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) GetResourceProfile(ctx *context.Context, tntID *utils.TenantIDWithAPIOpts, reply *engine.ResourceProfile) error { +func (rplSv1 *ReplicatorSv1) GetResourceProfile(ctx *context.Context, tntID *utils.TenantIDWithAPIOpts, reply *utils.ResourceProfile) error { engine.UpdateReplicationFilters(utils.ResourceProfilesPrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.APIOpts[utils.RemoteHostOpt])) rcv, err := rplSv1.dm.DataDB().GetResourceProfileDrv(ctx, tntID.Tenant, tntID.ID) if err != nil { @@ -348,7 +348,7 @@ func (rplSv1 *ReplicatorSv1) SetFilter(ctx *context.Context, fltr *engine.Filter } // SetResourceProfile is the replication method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) SetResourceProfile(ctx *context.Context, rs *engine.ResourceProfileWithAPIOpts, reply *string) (err error) { +func (rplSv1 *ReplicatorSv1) SetResourceProfile(ctx *context.Context, rs *utils.ResourceProfileWithAPIOpts, reply *string) (err error) { if err = rplSv1.dm.DataDB().SetResourceProfileDrv(ctx, rs.ResourceProfile); err != nil { return } @@ -366,7 +366,7 @@ func (rplSv1 *ReplicatorSv1) SetResourceProfile(ctx *context.Context, rs *engine } // SetResource is the replication method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) SetResource(ctx *context.Context, rs *engine.ResourceWithAPIOpts, reply *string) (err error) { +func (rplSv1 *ReplicatorSv1) SetResource(ctx *context.Context, rs *utils.ResourceWithAPIOpts, reply *string) (err error) { if err = rplSv1.dm.DataDB().SetResourceDrv(ctx, rs.Resource); err != nil { return } diff --git a/apis/replicator_test.go b/apis/replicator_test.go index 8ba788b64..8bc083fc4 100644 --- a/apis/replicator_test.go +++ b/apis/replicator_test.go @@ -470,12 +470,12 @@ func TestReplicatorGetResource(t *testing.T) { ping: struct{}{}, } - var reply engine.Resource + var reply utils.Resource rp := NewReplicatorSv1(dm, v1) - rsc := &engine.Resource{ + rsc := &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), } rp.dm.SetResource(context.Background(), rsc) tntID := &utils.TenantIDWithAPIOpts{ @@ -501,12 +501,12 @@ func TestReplicatorGetResourceError(t *testing.T) { ping: struct{}{}, } - var reply engine.Resource + var reply utils.Resource rp := NewReplicatorSv1(dm, v1) - rsc := &engine.Resource{ + rsc := &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup3", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), } rp.dm.SetResource(context.Background(), rsc) tntID := &utils.TenantIDWithAPIOpts{ @@ -529,9 +529,9 @@ func TestReplicatorGetResourceProfile(t *testing.T) { ping: struct{}{}, } - var reply engine.ResourceProfile + var reply utils.ResourceProfile rp := NewReplicatorSv1(dm, v1) - rsc := &engine.ResourceProfile{ + rsc := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -567,9 +567,9 @@ func TestReplicatorGetResourceProfileError(t *testing.T) { ping: struct{}{}, } - var reply engine.ResourceProfile + var reply utils.ResourceProfile rp := NewReplicatorSv1(dm, v1) - rsc := &engine.ResourceProfile{ + rsc := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup10", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -1415,8 +1415,8 @@ func TestReplicatorSetResourceProfile(t *testing.T) { cfg.AdminSCfg().CachesConns = []string{"*internal"} var reply string rp := NewReplicatorSv1(dm, v1) - rsp := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsp := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -1457,8 +1457,8 @@ func TestReplicatorSetResourceProfileErr1(t *testing.T) { cfg.AdminSCfg().CachesConns = []string{"*internal"} var reply string rp := NewReplicatorSv1(dm, v1) - rsp := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsp := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -1493,11 +1493,11 @@ func TestReplicatorSetResource(t *testing.T) { cfg.AdminSCfg().CachesConns = []string{"*internal"} var reply string rp := NewReplicatorSv1(dm, v1) - rs := &engine.ResourceWithAPIOpts{ - Resource: &engine.Resource{ + rs := &utils.ResourceWithAPIOpts{ + Resource: &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), }, APIOpts: map[string]any{ utils.MetaCache: utils.MetaNone, @@ -1528,11 +1528,11 @@ func TestReplicatorSetResourceErr1(t *testing.T) { cfg.AdminSCfg().CachesConns = []string{"*internal"} var reply string rp := NewReplicatorSv1(dm, v1) - rs := &engine.ResourceWithAPIOpts{ - Resource: &engine.Resource{ + rs := &utils.ResourceWithAPIOpts{ + Resource: &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), }, APIOpts: map[string]any{ utils.MetaCache: utils.OK, @@ -2338,10 +2338,10 @@ func TestReplicatorRemoveResource(t *testing.T) { cfg.AdminSCfg().CachesConns = []string{"*internal"} var reply string rp := NewReplicatorSv1(dm, v1) - rsc := &engine.Resource{ + rsc := &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), } if err := rp.dm.SetResource(context.Background(), rsc); err != nil { t.Error(err) @@ -2374,10 +2374,10 @@ func TestReplicatorRemoveResourceErr(t *testing.T) { cfg.AdminSCfg().CachesConns = []string{"*internal"} var reply string rp := NewReplicatorSv1(dm, v1) - rsc := &engine.Resource{ + rsc := &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), } if err := rp.dm.SetResource(context.Background(), rsc); err != nil { t.Error(err) @@ -2408,7 +2408,7 @@ func TestReplicatorRemoveResourceProfile(t *testing.T) { cfg.AdminSCfg().CachesConns = []string{"*internal"} var reply string rp := NewReplicatorSv1(dm, v1) - rscPrf := &engine.ResourceProfile{ + rscPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -2451,7 +2451,7 @@ func TestReplicatorRemoveResourceProfileErr(t *testing.T) { cfg.AdminSCfg().CachesConns = []string{"*internal"} var reply string rp := NewReplicatorSv1(dm, v1) - rscPrf := &engine.ResourceProfile{ + rscPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, diff --git a/apis/resources.go b/apis/resources.go index 7d32533c0..f368ad4b5 100644 --- a/apis/resources.go +++ b/apis/resources.go @@ -23,12 +23,11 @@ import ( "time" "github.com/cgrates/birpc/context" - "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) // GetResourceProfile returns a resource configuration -func (adms *AdminSv1) GetResourceProfile(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *engine.ResourceProfile) error { +func (adms *AdminSv1) GetResourceProfile(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *utils.ResourceProfile) error { if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } @@ -73,7 +72,7 @@ func (adms *AdminSv1) GetResourceProfileIDs(ctx *context.Context, args *utils.Ar } // GetResourceProfiles returns a list of resource profiles registered for a tenant -func (admS *AdminSv1) GetResourceProfiles(ctx *context.Context, args *utils.ArgsItemIDs, rsPrfs *[]*engine.ResourceProfile) (err error) { +func (admS *AdminSv1) GetResourceProfiles(ctx *context.Context, args *utils.ArgsItemIDs, rsPrfs *[]*utils.ResourceProfile) (err error) { tnt := args.Tenant if tnt == utils.EmptyString { tnt = admS.cfg.GeneralCfg().DefaultTenant @@ -82,9 +81,9 @@ func (admS *AdminSv1) GetResourceProfiles(ctx *context.Context, args *utils.Args if err = admS.GetResourceProfileIDs(ctx, args, &rsPrfIDs); err != nil { return } - *rsPrfs = make([]*engine.ResourceProfile, 0, len(rsPrfIDs)) + *rsPrfs = make([]*utils.ResourceProfile, 0, len(rsPrfIDs)) for _, rsPrfID := range rsPrfIDs { - var rsPrf *engine.ResourceProfile + var rsPrf *utils.ResourceProfile rsPrf, err = admS.dm.GetResourceProfile(ctx, tnt, rsPrfID, true, true, utils.NonTransactional) if err != nil { return utils.APIErrorHandler(err) @@ -114,7 +113,7 @@ func (admS *AdminSv1) GetResourceProfilesCount(ctx *context.Context, args *utils } // SetResourceProfile adds a new resource configuration -func (adms *AdminSv1) SetResourceProfile(ctx *context.Context, arg *engine.ResourceProfileWithAPIOpts, reply *string) (err error) { +func (adms *AdminSv1) SetResourceProfile(ctx *context.Context, arg *utils.ResourceProfileWithAPIOpts, reply *string) (err error) { if missing := utils.MissingStructFields(arg.ResourceProfile, []string{utils.ID}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } @@ -177,42 +176,3 @@ func (adms *AdminSv1) RemoveResourceProfile(ctx *context.Context, arg *utils.Ten *reply = utils.OK return nil } - -func NewResourceSv1(rls *engine.ResourceS) *ResourceSv1 { - return &ResourceSv1{rls: rls} -} - -// Exports RPC from RLs -type ResourceSv1 struct { - ping - rls *engine.ResourceS -} - -// GetResourcesForEvent returns Resources matching a specific event -func (rsv1 *ResourceSv1) GetResourcesForEvent(ctx *context.Context, args *utils.CGREvent, reply *engine.Resources) error { - return rsv1.rls.V1GetResourcesForEvent(ctx, args, reply) -} - -// AuthorizeResources checks if there are limits imposed for event -func (rsv1 *ResourceSv1) AuthorizeResources(ctx *context.Context, args *utils.CGREvent, reply *string) error { - return rsv1.rls.V1AuthorizeResources(ctx, args, reply) -} - -// AllocateResources records usage for an event -func (rsv1 *ResourceSv1) AllocateResources(ctx *context.Context, args *utils.CGREvent, reply *string) error { - return rsv1.rls.V1AllocateResources(ctx, args, reply) -} - -// ReleaseResources releases usage for an event -func (rsv1 *ResourceSv1) ReleaseResources(ctx *context.Context, args *utils.CGREvent, reply *string) error { - return rsv1.rls.V1ReleaseResources(ctx, args, reply) -} - -// GetResource returns a resource configuration -func (rsv1 *ResourceSv1) GetResource(ctx *context.Context, args *utils.TenantIDWithAPIOpts, reply *engine.Resource) error { - return rsv1.rls.V1GetResource(ctx, args, reply) -} - -func (rsv1 *ResourceSv1) GetResourceWithConfig(ctx *context.Context, args *utils.TenantIDWithAPIOpts, reply *engine.ResourceWithConfig) error { - return rsv1.rls.V1GetResourceWithConfig(ctx, args, reply) -} diff --git a/apis/resources_test.go b/apis/resources_test.go index 040f93102..233d59018 100644 --- a/apis/resources_test.go +++ b/apis/resources_test.go @@ -45,11 +45,11 @@ func TestResourcesSetGetRemResourceProfile(t *testing.T) { ID: "RES_1", }, } - var result engine.ResourceProfile + var result utils.ResourceProfile var reply string - resPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + resPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES_1", AllocationMessage: "Approved", @@ -121,7 +121,7 @@ func TestResourcesGetResourceProfileCheckErrors(t *testing.T) { cfg: cfg, dm: dm, } - var rcv engine.ResourceProfile + var rcv utils.ResourceProfile experr := "MANDATORY_IE_MISSING: [ID]" if err := adms.GetResourceProfile(context.Background(), &utils.TenantIDWithAPIOpts{}, &rcv); err == nil || @@ -156,8 +156,8 @@ func TestResourcesSetResourceProfileCheckErrors(t *testing.T) { dm: dm, } - resPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{}, + resPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{}, } var reply string @@ -190,14 +190,14 @@ func TestResourcesSetResourceProfileCheckErrors(t *testing.T) { cancel() dbMock := &engine.DataDBMock{ - GetResourceProfileDrvF: func(*context.Context, string, string) (*engine.ResourceProfile, error) { - resPrf := &engine.ResourceProfile{ + GetResourceProfileDrvF: func(*context.Context, string, string) (*utils.ResourceProfile, error) { + resPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "TEST", } return resPrf, nil }, - SetResourceProfileDrvF: func(*context.Context, *engine.ResourceProfile) error { + SetResourceProfileDrvF: func(*context.Context, *utils.ResourceProfile) error { return nil }, RemoveResourceProfileDrvF: func(*context.Context, string, string) error { @@ -230,8 +230,8 @@ func TestResourcesRemoveResourceProfileCheckErrors(t *testing.T) { dm: dm, } - resPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + resPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ ID: "TestResourcesRemoveResourceProfileCheckErrors", Tenant: "cgrates.org", Limit: 5, @@ -264,7 +264,7 @@ func TestResourcesRemoveResourceProfileCheckErrors(t *testing.T) { cancel() adms.cfg.GeneralCfg().DefaultCaching = utils.MetaNone - var rcv engine.ResourceProfile + var rcv utils.ResourceProfile arg := &utils.TenantIDWithAPIOpts{ TenantID: &utils.TenantID{ @@ -295,14 +295,14 @@ func TestResourcesRemoveResourceProfileCheckErrors(t *testing.T) { } dbMock := &engine.DataDBMock{ - GetResourceProfileDrvF: func(*context.Context, string, string) (*engine.ResourceProfile, error) { - resPrf := &engine.ResourceProfile{ + GetResourceProfileDrvF: func(*context.Context, string, string) (*utils.ResourceProfile, error) { + resPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "TEST", } return resPrf, nil }, - SetResourceProfileDrvF: func(*context.Context, *engine.ResourceProfile) error { + SetResourceProfileDrvF: func(*context.Context, *utils.ResourceProfile) error { return nil }, RemoveResourceProfileDrvF: func(*context.Context, string, string) error { @@ -341,14 +341,14 @@ func TestResourcesGetResourceProfileIDsErrMock(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.GeneralCfg().DefaultCaching = utils.MetaNone dbMock := &engine.DataDBMock{ - GetResourceProfileDrvF: func(*context.Context, string, string) (*engine.ResourceProfile, error) { - resPrf := &engine.ResourceProfile{ + GetResourceProfileDrvF: func(*context.Context, string, string) (*utils.ResourceProfile, error) { + resPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "TEST", } return resPrf, nil }, - SetResourceProfileDrvF: func(*context.Context, *engine.ResourceProfile) error { + SetResourceProfileDrvF: func(*context.Context, *utils.ResourceProfile) error { return nil }, RemoveResourceProfileDrvF: func(*context.Context, string, string) error { @@ -407,14 +407,14 @@ func TestResourcesGetResourceProfilesCountErrMock(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.GeneralCfg().DefaultCaching = utils.MetaNone dbMock := &engine.DataDBMock{ - GetResourceProfileDrvF: func(*context.Context, string, string) (*engine.ResourceProfile, error) { - resPrf := &engine.ResourceProfile{ + GetResourceProfileDrvF: func(*context.Context, string, string) (*utils.ResourceProfile, error) { + resPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "TEST", } return resPrf, nil }, - SetResourceProfileDrvF: func(*context.Context, *engine.ResourceProfile) error { + SetResourceProfileDrvF: func(*context.Context, *utils.ResourceProfile) error { return nil }, RemoveResourceProfileDrvF: func(*context.Context, string, string) error { @@ -462,204 +462,6 @@ func TestResourcesGetResourceProfilesCountErrKeys(t *testing.T) { } } -func TestResourcesNewResourceSv1(t *testing.T) { - engine.Cache.Clear(nil) - cfg := config.NewDefaultCGRConfig() - dataDB := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := engine.NewDataManager(dataDB, cfg, nil) - rls := engine.NewResourceService(dm, cfg, nil, nil) - - exp := &ResourceSv1{ - rls: rls, - } - rcv := NewResourceSv1(rls) - - if !reflect.DeepEqual(rcv, exp) { - t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp, rcv) - } -} - -func TestResourcesSv1Ping(t *testing.T) { - resSv1 := new(ResourceSv1) - var reply string - if err := resSv1.Ping(nil, nil, &reply); err != nil { - t.Error(err) - } else if reply != utils.Pong { - t.Errorf("Unexpected reply error") - } -} - -func TestResourcesGetResource(t *testing.T) { - engine.Cache.Clear(nil) - cfg := config.NewDefaultCGRConfig() - cfg.GeneralCfg().DefaultCaching = utils.MetaNone - data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := engine.NewDataManager(data, cfg, nil) - fltrs := engine.NewFilterS(cfg, nil, dm) - rls := engine.NewResourceService(dm, cfg, fltrs, nil) - adms := &AdminSv1{ - dm: dm, - cfg: cfg, - } - - resPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ - Tenant: "cgrates.org", - ID: "rsID", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Limit: 5, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - }, - } - - var reply string - if err := adms.SetResourceProfile(context.Background(), resPrf, - &reply); err != nil { - t.Error(err) - } - - rsv1 := NewResourceSv1(rls) - args := &utils.CGREvent{ - Event: map[string]any{ - utils.AccountField: "1001", - }, - ID: "EventTest", - APIOpts: map[string]any{ - utils.OptsResourcesUsageID: "RU_Test", - }, - } - - expResources := engine.Resources{ - { - Tenant: "cgrates.org", - ID: "rsID", - Usages: make(map[string]*engine.ResourceUsage), - }, - } - - var rplyResources engine.Resources - if err := rsv1.GetResourcesForEvent(context.Background(), args, &rplyResources); err != nil { - t.Error(err) - } else { - // We compare JSONs because the received Resources have unexported fields - if utils.ToJSON(expResources) != utils.ToJSON(rplyResources) { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", - utils.ToJSON(expResources), utils.ToJSON(rplyResources)) - } - } - - expResource := engine.Resource{ - Tenant: "cgrates.org", - ID: "rsID", - Usages: make(map[string]*engine.ResourceUsage), - } - - var rplyResource engine.Resource - if err := rsv1.GetResource(context.Background(), &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{ - Tenant: "cgrates.org", - ID: "rsID", - }}, &rplyResource); err != nil { - t.Error(err) - } else { - // We compare JSONs because the received Resource has unexported fields - if utils.ToJSON(rplyResource) != utils.ToJSON(expResource) { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", - utils.ToJSON(expResource), utils.ToJSON(rplyResource)) - } - } - - expResourceWithCfg := engine.ResourceWithConfig{ - Resource: &engine.Resource{ - Tenant: "cgrates.org", - ID: "rsID", - Usages: make(map[string]*engine.ResourceUsage), - }, - Config: resPrf.ResourceProfile, - } - - var rplyResourceWithCfg engine.ResourceWithConfig - if err := rsv1.GetResourceWithConfig(context.Background(), &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{ - Tenant: "cgrates.org", - ID: "rsID", - }}, &rplyResourceWithCfg); err != nil { - t.Error(err) - } else { - // We compare JSONs because the received Resource has unexported fields - if utils.ToJSON(expResourceWithCfg) != utils.ToJSON(rplyResourceWithCfg) { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", - utils.ToJSON(expResourceWithCfg), utils.ToJSON(rplyResourceWithCfg)) - } - } - dm.DataDB().Flush(utils.EmptyString) -} - -func TestResourcesAuthorizeAllocateReleaseResource(t *testing.T) { - engine.Cache.Clear(nil) - cfg := config.NewDefaultCGRConfig() - cfg.GeneralCfg().DefaultCaching = utils.MetaNone - data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := engine.NewDataManager(data, cfg, nil) - fltrs := engine.NewFilterS(cfg, nil, dm) - rls := engine.NewResourceService(dm, cfg, fltrs, nil) - adms := &AdminSv1{ - dm: dm, - cfg: cfg, - } - - resPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ - Tenant: "cgrates.org", - ID: "rsID", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Limit: 5, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - }, - } - - var reply string - if err := adms.SetResourceProfile(context.Background(), resPrf, - &reply); err != nil { - t.Error(err) - } - - rsv1 := NewResourceSv1(rls) - args := &utils.CGREvent{ - Event: map[string]any{ - utils.AccountField: "1001", - }, - ID: "EventTest", - APIOpts: map[string]any{ - utils.OptsResourcesUsageID: "RU_Test", - }, - } - - if err := rsv1.AuthorizeResources(context.Background(), args, &reply); err != nil { - t.Error(err) - } else if reply != "Approved" { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", "Approved", reply) - } - - if err := rsv1.AllocateResources(context.Background(), args, &reply); err != nil { - t.Error(err) - } else if reply != "Approved" { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", "Approved", reply) - } - - if err := rsv1.ReleaseResources(context.Background(), args, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.OK, reply) - } -} - func TestResourcesGetResourceProfilesOK(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.GeneralCfg().DefaultCaching = utils.MetaNone @@ -667,8 +469,8 @@ func TestResourcesGetResourceProfilesOK(t *testing.T) { dataDB := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) dm := engine.NewDataManager(dataDB, cfg, connMgr) admS := NewAdminSv1(cfg, dm, connMgr, nil, nil) - args1 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + args1 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "test_ID1", Limit: 10, @@ -690,8 +492,8 @@ func TestResourcesGetResourceProfilesOK(t *testing.T) { t.Error("Unexpected reply returned:", setReply) } - args2 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + args2 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "test_ID2", Limit: 15, @@ -713,8 +515,8 @@ func TestResourcesGetResourceProfilesOK(t *testing.T) { } // this profile will not match - args3 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + args3 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "test2_ID1", Limit: 10, @@ -739,7 +541,7 @@ func TestResourcesGetResourceProfilesOK(t *testing.T) { Tenant: "cgrates.org", ItemsPrefix: "test_ID", } - exp := []*engine.ResourceProfile{ + exp := []*utils.ResourceProfile{ { Tenant: "cgrates.org", ID: "test_ID1", @@ -766,7 +568,7 @@ func TestResourcesGetResourceProfilesOK(t *testing.T) { }, } - var getReply []*engine.ResourceProfile + var getReply []*utils.ResourceProfile if err := admS.GetResourceProfiles(context.Background(), argsGet, &getReply); err != nil { t.Error(err) } else { @@ -787,8 +589,8 @@ func TestResourcesGetResourceProfilesGetIDsErr(t *testing.T) { dataDB := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) dm := engine.NewDataManager(dataDB, cfg, connMgr) admS := NewAdminSv1(cfg, dm, connMgr, nil, nil) - args := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + args := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "test_ID1", Limit: 10, @@ -821,7 +623,7 @@ func TestResourcesGetResourceProfilesGetIDsErr(t *testing.T) { } experr := `SERVER_ERROR: maximum number of items exceeded` - var getReply []*engine.ResourceProfile + var getReply []*utils.ResourceProfile if err := admS.GetResourceProfiles(context.Background(), argsGet, &getReply); err == nil || err.Error() != experr { t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) } @@ -832,7 +634,7 @@ func TestResourcesGetResourceProfilesGetProfileErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.GeneralCfg().DefaultCaching = utils.MetaNone dbMock := &engine.DataDBMock{ - SetResourceProfileDrvF: func(*context.Context, *engine.ResourceProfile) error { + SetResourceProfileDrvF: func(*context.Context, *utils.ResourceProfile) error { return nil }, RemoveResourceProfileDrvF: func(*context.Context, string, string) error { @@ -849,7 +651,7 @@ func TestResourcesGetResourceProfilesGetProfileErr(t *testing.T) { dm: dm, } - var reply []*engine.ResourceProfile + var reply []*utils.ResourceProfile experr := "SERVER_ERROR: NOT_IMPLEMENTED" if err := adms.GetResourceProfiles(context.Background(), @@ -867,14 +669,14 @@ func TestResourcesGetResourceProfileIDsGetOptsErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.GeneralCfg().DefaultCaching = utils.MetaNone dbMock := &engine.DataDBMock{ - GetResourceProfileDrvF: func(*context.Context, string, string) (*engine.ResourceProfile, error) { - rsPrf := &engine.ResourceProfile{ + GetResourceProfileDrvF: func(*context.Context, string, string) (*utils.ResourceProfile, error) { + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "TEST", } return rsPrf, nil }, - SetResourceProfileDrvF: func(*context.Context, *engine.ResourceProfile) error { + SetResourceProfileDrvF: func(*context.Context, *utils.ResourceProfile) error { return nil }, RemoveResourceProfileDrvF: func(*context.Context, string, string) error { @@ -912,14 +714,14 @@ func TestResourcesGetResourceProfileIDsPaginateErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.GeneralCfg().DefaultCaching = utils.MetaNone dbMock := &engine.DataDBMock{ - GetResourceProfileDrvF: func(*context.Context, string, string) (*engine.ResourceProfile, error) { - rsPrf := &engine.ResourceProfile{ + GetResourceProfileDrvF: func(*context.Context, string, string) (*utils.ResourceProfile, error) { + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "TEST", } return rsPrf, nil }, - SetResourceProfileDrvF: func(*context.Context, *engine.ResourceProfile) error { + SetResourceProfileDrvF: func(*context.Context, *utils.ResourceProfile) error { return nil }, RemoveResourceProfileDrvF: func(*context.Context, string, string) error { diff --git a/apis/tpes_it_test.go b/apis/tpes_it_test.go index ecbdebcc7..ad29bd082 100644 --- a/apis/tpes_it_test.go +++ b/apis/tpes_it_test.go @@ -205,8 +205,8 @@ func testTPeSSetAttributeProfile(t *testing.T) { } func testTPeSSetResourceProfile(t *testing.T) { - rsPrf1 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsPrf1 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -228,8 +228,8 @@ func testTPeSSetResourceProfile(t *testing.T) { t.Error("Unexpected reply returned", replystr) } - rsPrf2 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsPrf2 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup2", FilterIDs: []string{"*string:~*req.Account:1002"}, diff --git a/cmd/cgr-loader/cgr-loader_remove_it_test.go b/cmd/cgr-loader/cgr-loader_remove_it_test.go index 06d47469d..2d9701e20 100644 --- a/cmd/cgr-loader/cgr-loader_remove_it_test.go +++ b/cmd/cgr-loader/cgr-loader_remove_it_test.go @@ -155,13 +155,13 @@ func testCgrLdrGetSubsystemsNotLoadedLoad(t *testing.T) { } // resourcesPrf - var replyResPrf *engine.ResourceProfile + var replyResPrf *utils.ResourceProfile if err := cgrLdrBIRPC.Call(context.Background(), utils.AdminSv1GetResourceProfile, &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "RES_ACNT_1001"}}, &replyResPrf); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Errorf("Expected %+q, received %v", utils.ErrNotFound.Error(), err) } - var replyRes *engine.Resource + var replyRes *utils.Resource if err := cgrLdrBIRPC.Call(context.Background(), utils.ResourceSv1GetResource, &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "RES_ACNT_1001"}}, &replyRes); err == nil || err.Error() != utils.ErrNotFound.Error() { @@ -500,7 +500,7 @@ func testCgrLdrGetRateProfileAfterLoad(t *testing.T) { } func testCgrLdrGetResourceProfileAfterLoad(t *testing.T) { - expREsPrf := &engine.ResourceProfile{ + expREsPrf := &utils.ResourceProfile{ Tenant: utils.CGRateSorg, ID: "RES_ACNT_1001", FilterIDs: []string{"FLTR_ACCOUNT_1001"}, @@ -513,7 +513,7 @@ func testCgrLdrGetResourceProfileAfterLoad(t *testing.T) { Limit: 1, ThresholdIDs: []string{}, } - var replyRes *engine.ResourceProfile + var replyRes *utils.ResourceProfile if err := cgrLdrBIRPC.Call(context.Background(), utils.AdminSv1GetResourceProfile, &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "RES_ACNT_1001"}}, &replyRes); err != nil { @@ -524,12 +524,12 @@ func testCgrLdrGetResourceProfileAfterLoad(t *testing.T) { } func testCgrLdrGetResourceAfterLoad(t *testing.T) { - expREsPrf := &engine.Resource{ + expREsPrf := &utils.Resource{ Tenant: "cgrates.org", ID: "RES_ACNT_1001", - Usages: map[string]*engine.ResourceUsage{}, + Usages: map[string]*utils.ResourceUsage{}, } - var replyRes *engine.Resource + var replyRes *utils.Resource if err := cgrLdrBIRPC.Call(context.Background(), utils.ResourceSv1GetResource, &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "RES_ACNT_1001"}}, &replyRes); err != nil { diff --git a/console/resource_profile.go b/console/resource_profile.go index 2de61ecb5..c891bb746 100644 --- a/console/resource_profile.go +++ b/console/resource_profile.go @@ -19,7 +19,6 @@ along with this program. If not, see package console import ( - "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -61,7 +60,7 @@ func (self *CmdGetResourceProfile) PostprocessRpcParams() error { } func (self *CmdGetResourceProfile) RpcResult() any { - var atr engine.ResourceProfile + var atr utils.ResourceProfile return &atr } diff --git a/console/resource_profile_set.go b/console/resource_profile_set.go index 35a74883d..7bdf1015c 100644 --- a/console/resource_profile_set.go +++ b/console/resource_profile_set.go @@ -19,7 +19,6 @@ along with this program. If not, see package console import ( - "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -27,7 +26,7 @@ func init() { c := &CmdSetResourceProfile{ name: "resource_profile_set", rpcMethod: utils.AdminSv1SetResourceProfile, - rpcParams: &engine.ResourceProfileWithAPIOpts{}, + rpcParams: &utils.ResourceProfileWithAPIOpts{}, } commands[c.Name()] = c c.CommandExecuter = &CommandExecuter{c} @@ -37,7 +36,7 @@ func init() { type CmdSetResourceProfile struct { name string rpcMethod string - rpcParams *engine.ResourceProfileWithAPIOpts + rpcParams *utils.ResourceProfileWithAPIOpts *CommandExecuter } @@ -51,8 +50,8 @@ func (self *CmdSetResourceProfile) RpcMethod() string { func (self *CmdSetResourceProfile) RpcParams(reset bool) any { if reset || self.rpcParams == nil { - self.rpcParams = &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: new(engine.ResourceProfile), + self.rpcParams = &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: new(utils.ResourceProfile), APIOpts: make(map[string]any), } } diff --git a/console/resource_profiles.go b/console/resource_profiles.go index 1daef4787..449c80f17 100644 --- a/console/resource_profiles.go +++ b/console/resource_profiles.go @@ -19,7 +19,6 @@ along with this program. If not, see package console import ( - "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -61,6 +60,6 @@ func (self *CmdGetResourceProfiles) PostprocessRpcParams() error { } func (self *CmdGetResourceProfiles) RpcResult() any { - var atr engine.ResourceProfile + var atr utils.ResourceProfile return &atr } diff --git a/console/resources.go b/console/resources.go index 765a0b7a7..4f1d4fe01 100644 --- a/console/resources.go +++ b/console/resources.go @@ -19,7 +19,6 @@ along with this program. If not, see package console import ( - "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -64,6 +63,6 @@ func (self *CmdGetResource) PostprocessRpcParams() error { } func (self *CmdGetResource) RpcResult() any { - var atr engine.Resource + var atr utils.Resource return &atr } diff --git a/console/resources_for_event.go b/console/resources_for_event.go index 4d1d55360..ee5a014ce 100644 --- a/console/resources_for_event.go +++ b/console/resources_for_event.go @@ -19,7 +19,7 @@ along with this program. If not, see package console import ( - "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/resources" "github.com/cgrates/cgrates/utils" ) @@ -61,6 +61,6 @@ func (self *CmdGetResourceForEvent) PostprocessRpcParams() error { } func (self *CmdGetResourceForEvent) RpcResult() any { - var atr engine.Resources + var atr resources.Resources return &atr } diff --git a/engine/caches.go b/engine/caches.go index 06b5d0e2f..bf917571d 100644 --- a/engine/caches.go +++ b/engine/caches.go @@ -46,10 +46,10 @@ func init() { gob.Register(new(ThresholdProfileWithAPIOpts)) gob.Register(new(ThresholdWithAPIOpts)) // Resource - gob.Register(new(Resource)) - gob.Register(new(ResourceProfile)) - gob.Register(new(ResourceProfileWithAPIOpts)) - gob.Register(new(ResourceWithAPIOpts)) + gob.Register(new(utils.Resource)) + gob.Register(new(utils.ResourceProfile)) + gob.Register(new(utils.ResourceProfileWithAPIOpts)) + gob.Register(new(utils.ResourceWithAPIOpts)) // Stats gob.Register(new(StatQueue)) gob.Register(new(StatQueueProfile)) @@ -222,7 +222,10 @@ func (chS *CacheS) GetItemIDs(chID, prfx string) (itmIDs []string) { // Remove is an exported method from TransCache func (chS *CacheS) Remove(ctx *context.Context, chID, itmID string, commit bool, transID string) (err error) { chS.tCache.Remove(chID, itmID, commit, transID) - return chS.ReplicateRemove(ctx, chID, itmID) + if err := chS.ReplicateRemove(ctx, chID, itmID); err != nil { + return err + } + return nil } // RemoveWithoutReplicate is an exported method from TransCache diff --git a/engine/connmanager_test.go b/engine/connmanager_test.go index 870b87d22..46696864e 100644 --- a/engine/connmanager_test.go +++ b/engine/connmanager_test.go @@ -478,6 +478,18 @@ func TestCMCallWithConnIDsInternallyDCed(t *testing.T) { } } +type ccMock struct { + calls map[string]func(ctx *context.Context, args any, reply any) error +} + +func (ccM *ccMock) Call(ctx *context.Context, serviceMethod string, args any, reply any) (err error) { + if call, has := ccM.calls[serviceMethod]; !has { + return rpcclient.ErrUnsupporteServiceMethod + } else { + return call(ctx, args, reply) + } +} + func TestCMCallWithConnIDsErrNotNetwork(t *testing.T) { tmp := Cache defer func() { diff --git a/engine/datadbmock.go b/engine/datadbmock.go index 5271b2c67..5433c6a2b 100644 --- a/engine/datadbmock.go +++ b/engine/datadbmock.go @@ -43,11 +43,12 @@ type DataDBMock struct { RemThresholdProfileDrvF func(ctx *context.Context, tenant, id string) (err error) GetThresholdDrvF func(ctx *context.Context, tenant, id string) (*Threshold, error) RemoveThresholdDrvF func(ctx *context.Context, tnt, id string) error - GetResourceProfileDrvF func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) - SetResourceProfileDrvF func(ctx *context.Context, rp *ResourceProfile) error + GetResourceProfileDrvF func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) + SetResourceProfileDrvF func(ctx *context.Context, rp *utils.ResourceProfile) error RemoveResourceProfileDrvF func(ctx *context.Context, tnt, id string) error RemoveResourceDrvF func(ctx *context.Context, tnt, id string) error - SetResourceDrvF func(ctx *context.Context, r *Resource) error + SetResourceDrvF func(ctx *context.Context, r *utils.Resource) error + GetResourceDrvF func(ctx *context.Context, tenant, id string) (*utils.Resource, error) SetTrendProfileDrvF func(ctx *context.Context, tr *utils.TrendProfile) (err error) GetTrendProfileDrvF func(ctx *context.Context, tenant string, id string) (sq *utils.TrendProfile, err error) RemTrendProfileDrvF func(ctx *context.Context, tenant string, id string) (err error) @@ -76,7 +77,6 @@ type DataDBMock struct { HasDataDrvF func(ctx *context.Context, category, subject, tenant string) (bool, error) RemoveIndexesDrvF func(ctx *context.Context, idxItmType, tntCtx, idxKey string) error GetStatQueueDrvF func(ctx *context.Context, tenant, id string) (sq *StatQueue, err error) - GetResourceDrvF func(ctx *context.Context, tenant, id string) (*Resource, error) } // Storage methods @@ -121,14 +121,14 @@ func (dbM *DataDBMock) HasDataDrv(ctx *context.Context, category, subject, tenan return false, utils.ErrNotImplemented } -func (dbM *DataDBMock) GetResourceProfileDrv(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { +func (dbM *DataDBMock) GetResourceProfileDrv(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { if dbM.GetResourceProfileDrvF != nil { return dbM.GetResourceProfileDrvF(ctx, tnt, id) } return nil, utils.ErrNotImplemented } -func (dbM *DataDBMock) SetResourceProfileDrv(ctx *context.Context, resPrf *ResourceProfile) error { +func (dbM *DataDBMock) SetResourceProfileDrv(ctx *context.Context, resPrf *utils.ResourceProfile) error { if dbM.SetResourceProfileDrvF != nil { return dbM.SetResourceProfileDrvF(ctx, resPrf) } @@ -142,14 +142,14 @@ func (dbM *DataDBMock) RemoveResourceProfileDrv(ctx *context.Context, tnt string return utils.ErrNotImplemented } -func (dbM *DataDBMock) GetResourceDrv(ctx *context.Context, tenant, id string) (*Resource, error) { +func (dbM *DataDBMock) GetResourceDrv(ctx *context.Context, tenant, id string) (*utils.Resource, error) { if dbM.GetResourceDrvF != nil { return dbM.GetResourceDrvF(ctx, tenant, id) } return nil, utils.ErrNotImplemented } -func (dbM *DataDBMock) SetResourceDrv(ctx *context.Context, r *Resource) error { +func (dbM *DataDBMock) SetResourceDrv(ctx *context.Context, r *utils.Resource) error { if dbM.SetResourceDrvF != nil { return dbM.SetResourceDrvF(ctx, r) } diff --git a/engine/datamanager.go b/engine/datamanager.go index d9b430ab2..701452b66 100644 --- a/engine/datamanager.go +++ b/engine/datamanager.go @@ -150,12 +150,12 @@ func (dm *DataManager) CacheDataFromDB(ctx *context.Context, prfx string, ids [] switch prfx { case utils.ResourceProfilesPrefix: tntID := utils.NewTenantID(dataID) - lkID := guardian.Guardian.GuardIDs("", dm.cfg.GeneralCfg().LockingTimeout, resourceProfileLockKey(tntID.Tenant, tntID.ID)) + lkID := guardian.Guardian.GuardIDs("", dm.cfg.GeneralCfg().LockingTimeout, utils.ResourceProfileLockKey(tntID.Tenant, tntID.ID)) _, err = dm.GetResourceProfile(ctx, tntID.Tenant, tntID.ID, false, true, utils.NonTransactional) guardian.Guardian.UnguardIDs(lkID) case utils.ResourcesPrefix: tntID := utils.NewTenantID(dataID) - lkID := guardian.Guardian.GuardIDs("", dm.cfg.GeneralCfg().LockingTimeout, resourceLockKey(tntID.Tenant, tntID.ID)) + lkID := guardian.Guardian.GuardIDs("", dm.cfg.GeneralCfg().LockingTimeout, utils.ResourceLockKey(tntID.Tenant, tntID.ID)) _, err = dm.GetResource(ctx, tntID.Tenant, tntID.ID, false, true, utils.NonTransactional) guardian.Guardian.UnguardIDs(lkID) case utils.StatQueueProfilePrefix: @@ -1428,14 +1428,14 @@ func (dm *DataManager) RemoveRanking(ctx *context.Context, tenant, id string) (e } func (dm *DataManager) GetResource(ctx *context.Context, tenant, id string, cacheRead, cacheWrite bool, - transactionID string) (rs *Resource, err error) { + transactionID string) (rs *utils.Resource, err error) { tntID := utils.ConcatenatedKey(tenant, id) if cacheRead { if x, ok := Cache.Get(utils.CacheResources, tntID); ok { if x == nil { return nil, utils.ErrNotFound } - return x.(*Resource), nil + return x.(*utils.Resource), nil } } if dm == nil { @@ -1477,7 +1477,7 @@ func (dm *DataManager) GetResource(ctx *context.Context, tenant, id string, cach return } -func (dm *DataManager) SetResource(ctx *context.Context, rs *Resource) (err error) { +func (dm *DataManager) SetResource(ctx *context.Context, rs *utils.Resource) (err error) { if dm == nil { return utils.ErrNoDatabaseConn } @@ -1489,7 +1489,7 @@ func (dm *DataManager) SetResource(ctx *context.Context, rs *Resource) (err erro dm.cfg.DataDbCfg().RplFiltered, utils.ResourcesPrefix, rs.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetResource, - &ResourceWithAPIOpts{ + &utils.ResourceWithAPIOpts{ Resource: rs, APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, dm.cfg.DataDbCfg().RplCache, utils.EmptyString)}) @@ -1518,14 +1518,14 @@ func (dm *DataManager) RemoveResource(ctx *context.Context, tenant, id string) ( } func (dm *DataManager) GetResourceProfile(ctx *context.Context, tenant, id string, cacheRead, cacheWrite bool, - transactionID string) (rp *ResourceProfile, err error) { + transactionID string) (rp *utils.ResourceProfile, err error) { tntID := utils.ConcatenatedKey(tenant, id) if cacheRead { if x, ok := Cache.Get(utils.CacheResourceProfiles, tntID); ok { if x == nil { return nil, utils.ErrNotFound } - return x.(*ResourceProfile), nil + return x.(*utils.ResourceProfile), nil } } if dm == nil { @@ -1566,7 +1566,7 @@ func (dm *DataManager) GetResourceProfile(ctx *context.Context, tenant, id strin return } -func (dm *DataManager) SetResourceProfile(ctx *context.Context, rp *ResourceProfile, withIndex bool) (err error) { +func (dm *DataManager) SetResourceProfile(ctx *context.Context, rp *utils.ResourceProfile, withIndex bool) (err error) { if dm == nil { return utils.ErrNoDatabaseConn } @@ -1600,7 +1600,7 @@ func (dm *DataManager) SetResourceProfile(ctx *context.Context, rp *ResourceProf dm.cfg.DataDbCfg().RplFiltered, utils.ResourceProfilesPrefix, rp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetResourceProfile, - &ResourceProfileWithAPIOpts{ + &utils.ResourceProfileWithAPIOpts{ ResourceProfile: rp, APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, dm.cfg.DataDbCfg().RplCache, utils.EmptyString)}); err != nil { @@ -1611,17 +1611,17 @@ func (dm *DataManager) SetResourceProfile(ctx *context.Context, rp *ResourceProf oldRes.UsageTTL != rp.UsageTTL || oldRes.Limit != rp.Limit || oldRes.Stored != rp.Stored && oldRes.Stored { // reset the resource if the profile changed this fields - err = dm.SetResource(ctx, &Resource{ + err = dm.SetResource(ctx, &utils.Resource{ Tenant: rp.Tenant, ID: rp.ID, - Usages: make(map[string]*ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), }) } else if _, errRs := dm.GetResource(ctx, rp.Tenant, rp.ID, // do not try to get the resource if the configuration changed true, false, utils.NonTransactional); errRs == utils.ErrNotFound { // the resource does not exist - err = dm.SetResource(ctx, &Resource{ + err = dm.SetResource(ctx, &utils.Resource{ Tenant: rp.Tenant, ID: rp.ID, - Usages: make(map[string]*ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), }) } return diff --git a/engine/datamanager_test.go b/engine/datamanager_test.go index 24bc8a6ef..46fc346c3 100644 --- a/engine/datamanager_test.go +++ b/engine/datamanager_test.go @@ -2093,7 +2093,7 @@ func TestDMCacheDataFromDBResourceProfilesPrefix(t *testing.T) { cM := NewConnManager(cfg) dm := NewDataManager(data, cfg, cM) - rp := &ResourceProfile{ + rp := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RL2", FilterIDs: []string{"fltr_test"}, @@ -2140,17 +2140,16 @@ func TestDMCacheDataFromDBResourcesPrefix(t *testing.T) { cM := NewConnManager(cfg) dm := NewDataManager(data, cfg, cM) - rs := &Resource{ + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 9, }, }, - tUsage: utils.Float64Pointer(9), } if err := dm.SetResource(context.Background(), rs); err != nil { @@ -4772,10 +4771,10 @@ func TestDMGetResourceSetResourceDrvErr(t *testing.T) { cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.RemoteConnsCfg), utils.ReplicatorSv1, cc) data := &DataDBMock{ - GetResourceDrvF: func(ctx *context.Context, tenant, id string) (*Resource, error) { - return &Resource{}, utils.ErrNotFound + GetResourceDrvF: func(ctx *context.Context, tenant, id string) (*utils.Resource, error) { + return &utils.Resource{}, utils.ErrNotFound }, - SetResourceDrvF: func(ctx *context.Context, r *Resource) error { return utils.ErrNotImplemented }, + SetResourceDrvF: func(ctx *context.Context, r *utils.Resource) error { return utils.ErrNotImplemented }, } dm := NewDataManager(data, cfg, cM) @@ -4851,17 +4850,16 @@ func TestDMGetResourceCacheWriteErr2(t *testing.T) { cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator), utils.CacheSv1, cc) dm := NewDataManager(data, cfg, cM) - rs := &Resource{ + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 9, }, }, - tUsage: utils.Float64Pointer(9), } if err := dm.dataDB.SetResourceDrv(context.Background(), rs); err != nil { @@ -4886,22 +4884,21 @@ func TestDMSetResourceSetResourceDrvErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() data := &DataDBMock{ - SetResourceDrvF: func(ctx *context.Context, r *Resource) error { return utils.ErrNotImplemented }, + SetResourceDrvF: func(ctx *context.Context, r *utils.Resource) error { return utils.ErrNotImplemented }, } cM := NewConnManager(cfg) dm := NewDataManager(data, cfg, cM) - rs := &Resource{ + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 9, }, }, - tUsage: utils.Float64Pointer(9), } if err := dm.SetResource(context.Background(), rs); err != utils.ErrNotImplemented { @@ -5040,10 +5037,10 @@ func TestDMGetResourceProfileSetResourceProfileDrvErr(t *testing.T) { cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.RemoteConnsCfg), utils.ReplicatorSv1, cc) data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { - return &ResourceProfile{}, utils.ErrNotFound + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { + return &utils.ResourceProfile{}, utils.ErrNotFound }, - SetResourceProfileDrvF: func(ctx *context.Context, rp *ResourceProfile) error { return utils.ErrNotImplemented }, + SetResourceProfileDrvF: func(ctx *context.Context, rp *utils.ResourceProfile) error { return utils.ErrNotImplemented }, } dm := NewDataManager(data, cfg, cM) @@ -5119,7 +5116,7 @@ func TestDMGetResourceProfileCacheWriteErr2(t *testing.T) { cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator), utils.CacheSv1, cc) dm := NewDataManager(data, cfg, cM) - rp := &ResourceProfile{ + rp := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RL2", FilterIDs: []string{"fltr_test"}, @@ -5317,7 +5314,7 @@ func TestDMSetResourceProfileNilDm(t *testing.T) { var dm *DataManager - if err := dm.SetResourceProfile(context.Background(), &ResourceProfile{}, false); err != utils.ErrNoDatabaseConn { + if err := dm.SetResourceProfile(context.Background(), &utils.ResourceProfile{}, false); err != utils.ErrNoDatabaseConn { t.Errorf("Expected error <%v>, received error <%v>", utils.ErrNoDatabaseConn, err) } @@ -5333,14 +5330,14 @@ func TestDMSetResourceProfileGetResourceProfileErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { - return &ResourceProfile{}, utils.ErrNotImplemented + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { + return &utils.ResourceProfile{}, utils.ErrNotImplemented }, } cM := NewConnManager(cfg) dm := NewDataManager(data, cfg, cM) - if err := dm.SetResourceProfile(context.Background(), &ResourceProfile{}, false); err != utils.ErrNotImplemented { + if err := dm.SetResourceProfile(context.Background(), &utils.ResourceProfile{}, false); err != utils.ErrNotImplemented { t.Errorf("Expected error <%v>, received error <%v>", utils.ErrNotImplemented, err) } @@ -5355,15 +5352,15 @@ func TestDMSetResourceProfileSetResourceProfileDrvErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { - return &ResourceProfile{}, nil + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { + return &utils.ResourceProfile{}, nil }, - SetResourceProfileDrvF: func(ctx *context.Context, rp *ResourceProfile) error { return utils.ErrNotImplemented }, + SetResourceProfileDrvF: func(ctx *context.Context, rp *utils.ResourceProfile) error { return utils.ErrNotImplemented }, } cM := NewConnManager(cfg) dm := NewDataManager(data, cfg, cM) - if err := dm.SetResourceProfile(context.Background(), &ResourceProfile{}, false); err != utils.ErrNotImplemented { + if err := dm.SetResourceProfile(context.Background(), &utils.ResourceProfile{}, false); err != utils.ErrNotImplemented { t.Errorf("Expected error <%v>, received error <%v>", utils.ErrNotImplemented, err) } @@ -5379,15 +5376,15 @@ func TestDMSetResourceProfileUpdatedIndexesErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { - return &ResourceProfile{}, nil + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { + return &utils.ResourceProfile{}, nil }, - SetResourceProfileDrvF: func(ctx *context.Context, rp *ResourceProfile) error { return nil }, + SetResourceProfileDrvF: func(ctx *context.Context, rp *utils.ResourceProfile) error { return nil }, } cM := NewConnManager(cfg) dm := NewDataManager(data, cfg, cM) - rp := &ResourceProfile{ + rp := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RL1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5437,7 +5434,7 @@ func TestDMSetResourceProfileErr(t *testing.T) { data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) dm := NewDataManager(data, cfg, cM) - if err := dm.SetResourceProfile(context.Background(), &ResourceProfile{}, false); err != utils.ErrNotImplemented { + if err := dm.SetResourceProfile(context.Background(), &utils.ResourceProfile{}, false); err != utils.ErrNotImplemented { t.Errorf("Expected error <%v>, received error <%v>", utils.ErrNotImplemented, err) } @@ -5463,8 +5460,8 @@ func TestDMRemoveResourceProfileGetResourceProfileErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { - return &ResourceProfile{}, utils.ErrNotImplemented + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { + return &utils.ResourceProfile{}, utils.ErrNotImplemented }, } cM := NewConnManager(cfg) @@ -5486,8 +5483,8 @@ func TestDMRemoveResourceProfileRemoveResourceProfileDrvErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { - return &ResourceProfile{}, nil + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { + return &utils.ResourceProfile{}, nil }, RemoveResourceProfileDrvF: func(ctx *context.Context, tnt, id string) error { return utils.ErrNotImplemented }, } @@ -5527,7 +5524,7 @@ func TestDMRemoveResourceProfileRemoveItemFromFilterIndexErr(t *testing.T) { }() Cache.Clear(nil) - rp := &ResourceProfile{ + rp := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RSP1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5544,7 +5541,7 @@ func TestDMRemoveResourceProfileRemoveItemFromFilterIndexErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { return rp, nil }, + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { return rp, nil }, RemoveResourceProfileDrvF: func(ctx *context.Context, tnt, id string) error { return nil }, @@ -5565,7 +5562,7 @@ func TestDMRemoveResourceProfileRemoveIndexFiltersItemErr(t *testing.T) { Cache = tmp }() Cache.Clear(nil) - rp := &ResourceProfile{ + rp := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RSP1", FilterIDs: []string{"fltrID"}, @@ -5582,7 +5579,7 @@ func TestDMRemoveResourceProfileRemoveIndexFiltersItemErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { return rp, nil }, + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { return rp, nil }, RemoveResourceProfileDrvF: func(ctx *context.Context, tnt, id string) error { return nil }, @@ -5605,7 +5602,7 @@ func TestDMRemoveResourceProfileReplicate(t *testing.T) { }() Cache.Clear(nil) - rp := &ResourceProfile{ + rp := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RSP1", FilterIDs: []string{"fltrID"}, @@ -5636,7 +5633,7 @@ func TestDMRemoveResourceProfileReplicate(t *testing.T) { cM := NewConnManager(cfg) cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator), utils.ReplicatorSv1, cc) data := &DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*ResourceProfile, error) { return rp, nil }, + GetResourceProfileDrvF: func(ctx *context.Context, tnt, id string) (*utils.ResourceProfile, error) { return rp, nil }, RemoveResourceProfileDrvF: func(ctx *context.Context, tnt, id string) error { return nil }, @@ -9383,3 +9380,127 @@ func TestDMGetRateProfileNildm(t *testing.T) { t.Errorf("Expected error <%v>, received error <%v>", utils.ErrNoDatabaseConn, err) } } + +func TestDMResourcesUpdateResource(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + dm := NewDataManager(NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, nil) + Cache.Clear(nil) + res := &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + UsageTTL: 0, + Limit: 10, + Stored: true, + } + r := &utils.Resource{ + Tenant: res.Tenant, + ID: res.ID, + Usages: map[string]*utils.ResourceUsage{ + "jkbdfgs": { + Tenant: res.Tenant, + ID: "jkbdfgs", + ExpiryTime: time.Now(), + Units: 5, + }, + }, + TTLIdx: []string{"jkbdfgs"}, + } + expR := &utils.Resource{ + Tenant: res.Tenant, + ID: res.ID, + Usages: make(map[string]*utils.ResourceUsage), + } + if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { + t.Fatal(err) + } + + if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(r, expR) { + t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) + } + + if err := dm.RemoveResource(context.Background(), r.Tenant, r.ID); err != nil { + t.Fatal(err) + } + + if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { + t.Fatal(err) + } + + if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(r, expR) { + t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) + } + + if err := dm.SetResource(context.Background(), r); err != nil { + t.Fatal(err) + } + + res = &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + UsageTTL: 0, + Limit: 5, + Stored: true, + } + if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { + t.Fatal(err) + } + if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(r, expR) { + t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) + } + + if err := dm.SetResource(context.Background(), r); err != nil { + t.Fatal(err) + } + + res = &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + UsageTTL: 10, + Limit: 5, + Stored: true, + } + if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { + t.Fatal(err) + } + if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(r, expR) { + t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) + } + + if err := dm.SetResource(context.Background(), r); err != nil { + t.Fatal(err) + } + + res = &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + UsageTTL: 10, + Limit: 5, + Stored: false, + } + if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { + t.Fatal(err) + } + if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(r, expR) { + t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) + } + + if err := dm.RemoveResourceProfile(context.Background(), res.Tenant, res.ID, true); err != nil { + t.Fatal(err) + } + + if _, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != utils.ErrNotFound { + t.Fatal(err) + } + + dm.DataDB().Flush(utils.EmptyString) +} diff --git a/engine/dynamicdp.go b/engine/dynamicdp.go index d2635ef4a..2ea5c2441 100644 --- a/engine/dynamicdp.go +++ b/engine/dynamicdp.go @@ -108,7 +108,7 @@ func (dDP *DynamicDP) fieldAsInterface(fldPath []string) (val any, err error) { return dp.FieldAsInterface(fldPath[2:]) case utils.MetaResources: // sample of fieldName : ~*resources.ResourceID.Field - var reply ResourceWithConfig + var reply utils.ResourceWithConfig if err := connMgr.Call(dDP.ctx, dDP.resConns, utils.ResourceSv1GetResourceWithConfig, &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: dDP.tenant, ID: fldPath[1]}}, &reply); err != nil { return nil, err diff --git a/engine/dynamicdp_test.go b/engine/dynamicdp_test.go index dfd5725d7..a97206a2f 100644 --- a/engine/dynamicdp_test.go +++ b/engine/dynamicdp_test.go @@ -640,20 +640,19 @@ func TestDynamicDPfieldAsInterfaceMetaResources(t *testing.T) { } cfg := config.NewDefaultCGRConfig() - customRply := &ResourceWithConfig{ - Resource: &Resource{ + customRply := &utils.ResourceWithConfig{ + Resource: &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 9, }, }, - tUsage: utils.Float64Pointer(9), }, - Config: &ResourceProfile{ + Config: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup2", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -670,7 +669,7 @@ func TestDynamicDPfieldAsInterfaceMetaResources(t *testing.T) { cc := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.ResourceSv1GetResourceWithConfig: func(ctx *context.Context, args, reply any) error { - rplCast, canCast := reply.(*ResourceWithConfig) + rplCast, canCast := reply.(*utils.ResourceWithConfig) if !canCast { t.Errorf("Wrong argument type : %T", reply) return nil diff --git a/engine/libindex_health.go b/engine/libindex_health.go index 97f26ccc7..7a8bbbe82 100644 --- a/engine/libindex_health.go +++ b/engine/libindex_health.go @@ -65,7 +65,7 @@ type ReverseFilterIHReply struct { func getFilters(ctx *context.Context, dm *DataManager, indxType, tnt, id string) (filterIDs []string, err error) { // add contexts switch indxType { case utils.CacheResourceFilterIndexes: - var rs *ResourceProfile + var rs *utils.ResourceProfile if rs, err = dm.GetResourceProfile(ctx, tnt, id, true, false, utils.NonTransactional); err != nil { return } diff --git a/engine/libindex_test.go b/engine/libindex_test.go index 69aa3777a..3d10cf935 100644 --- a/engine/libindex_test.go +++ b/engine/libindex_test.go @@ -1115,7 +1115,7 @@ func TestUpdateFilterIndexResourceIndex(t *testing.T) { if err := dm.SetFilter(context.Background(), oldFlt, true); err != nil { t.Error(err) } - resProf := &ResourceProfile{ + resProf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RL1", FilterIDs: []string{"fltr_test"}, diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 328c865f4..ffadaa3ad 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -259,8 +259,8 @@ func APItoModelResource(rl *utils.TPResourceProfile) (mdls ResourceMdls) { return } -func APItoResource(tpRL *utils.TPResourceProfile, timezone string) (rp *ResourceProfile, err error) { - rp = &ResourceProfile{ +func APItoResource(tpRL *utils.TPResourceProfile, timezone string) (rp *utils.ResourceProfile, err error) { + rp = &utils.ResourceProfile{ Tenant: tpRL.Tenant, ID: tpRL.ID, Blocker: tpRL.Blocker, @@ -290,7 +290,7 @@ func APItoResource(tpRL *utils.TPResourceProfile, timezone string) (rp *Resource return rp, nil } -func ResourceProfileToAPI(rp *ResourceProfile) (tpRL *utils.TPResourceProfile) { +func ResourceProfileToAPI(rp *utils.ResourceProfile) (tpRL *utils.TPResourceProfile) { tpRL = &utils.TPResourceProfile{ Tenant: rp.Tenant, ID: rp.ID, diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 31de32f26..d07974b72 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -98,7 +98,7 @@ func TestAPItoResource(t *testing.T) { ThresholdIDs: []string{"TRes1"}, AllocationMessage: "asd", } - eRL := &ResourceProfile{ + eRL := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: tpRL.ID, Stored: tpRL.Stored, @@ -133,7 +133,7 @@ func TestResourceProfileToAPI(t *testing.T) { ThresholdIDs: []string{"TRes1"}, AllocationMessage: "asd", } - rp := &ResourceProfile{ + rp := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", Weights: utils.DynamicWeights{ @@ -3899,7 +3899,7 @@ func TestStatMdlsCSVHeader(t *testing.T) { } func TestModelHelpersResourceProfileToAPICase2(t *testing.T) { - testStruct := &ResourceProfile{ + testStruct := &utils.ResourceProfile{ Tenant: "", ID: "", FilterIDs: []string{"test_filter_id", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z|2014-07-15T14:25:00Z"}, diff --git a/engine/storage_csv.go b/engine/storage_csv.go index f73aa9339..c0179852c 100644 --- a/engine/storage_csv.go +++ b/engine/storage_csv.go @@ -146,7 +146,7 @@ func NewGoogleCSVStorage(sep rune, spreadsheetID string) (*CSVStorage, error) { return []string{} } c := NewCSVStorage(sep, - getIfExist(utils.Resources), + getIfExist(utils.ResourcesStr), getIfExist(utils.Stats), getIfExist(utils.Rankings), getIfExist(utils.Trends), diff --git a/engine/storage_interface.go b/engine/storage_interface.go index e44724e8e..9d89f01d1 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -40,11 +40,11 @@ type Storage interface { type DataDB interface { Storage HasDataDrv(*context.Context, string, string, string) (bool, error) - GetResourceProfileDrv(*context.Context, string, string) (*ResourceProfile, error) - SetResourceProfileDrv(*context.Context, *ResourceProfile) error + GetResourceProfileDrv(*context.Context, string, string) (*utils.ResourceProfile, error) + SetResourceProfileDrv(*context.Context, *utils.ResourceProfile) error RemoveResourceProfileDrv(*context.Context, string, string) error - GetResourceDrv(*context.Context, string, string) (*Resource, error) - SetResourceDrv(*context.Context, *Resource) error + GetResourceDrv(*context.Context, string, string) (*utils.Resource, error) + SetResourceDrv(*context.Context, *utils.Resource) error RemoveResourceDrv(*context.Context, string, string) error GetLoadHistory(int, bool, string) ([]*utils.LoadInstance, error) AddLoadHistory(*utils.LoadInstance, int, string) error diff --git a/engine/storage_internal_datadb.go b/engine/storage_internal_datadb.go index a263d1bec..84c6e72d9 100644 --- a/engine/storage_internal_datadb.go +++ b/engine/storage_internal_datadb.go @@ -190,14 +190,14 @@ func (iDB *InternalDB) HasDataDrv(_ *context.Context, category, subject, tenant return false, errors.New("Unsupported HasData category") } -func (iDB *InternalDB) GetResourceProfileDrv(_ *context.Context, tenant, id string) (rp *ResourceProfile, err error) { +func (iDB *InternalDB) GetResourceProfileDrv(_ *context.Context, tenant, id string) (rp *utils.ResourceProfile, err error) { if x, ok := iDB.db.Get(utils.CacheResourceProfiles, utils.ConcatenatedKey(tenant, id)); ok && x != nil { - return x.(*ResourceProfile), nil + return x.(*utils.ResourceProfile), nil } return nil, utils.ErrNotFound } -func (iDB *InternalDB) SetResourceProfileDrv(_ *context.Context, rp *ResourceProfile) (err error) { +func (iDB *InternalDB) SetResourceProfileDrv(_ *context.Context, rp *utils.ResourceProfile) (err error) { iDB.db.Set(utils.CacheResourceProfiles, rp.TenantID(), rp, nil, true, utils.NonTransactional) return @@ -209,14 +209,14 @@ func (iDB *InternalDB) RemoveResourceProfileDrv(_ *context.Context, tenant, id s return } -func (iDB *InternalDB) GetResourceDrv(_ *context.Context, tenant, id string) (r *Resource, err error) { +func (iDB *InternalDB) GetResourceDrv(_ *context.Context, tenant, id string) (r *utils.Resource, err error) { if x, ok := iDB.db.Get(utils.CacheResources, utils.ConcatenatedKey(tenant, id)); ok && x != nil { - return x.(*Resource), nil + return x.(*utils.Resource), nil } return nil, utils.ErrNotFound } -func (iDB *InternalDB) SetResourceDrv(_ *context.Context, r *Resource) (err error) { +func (iDB *InternalDB) SetResourceDrv(_ *context.Context, r *utils.Resource) (err error) { iDB.db.Set(utils.CacheResources, r.TenantID(), r, nil, true, utils.NonTransactional) return diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index 2f31af646..23bc6fe34 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -673,8 +673,8 @@ func (ms *MongoStorage) AddLoadHistory(ldInst *utils.LoadInstance, return err } -func (ms *MongoStorage) GetResourceProfileDrv(ctx *context.Context, tenant, id string) (*ResourceProfile, error) { - rsProfile := new(ResourceProfile) +func (ms *MongoStorage) GetResourceProfileDrv(ctx *context.Context, tenant, id string) (*utils.ResourceProfile, error) { + rsProfile := new(utils.ResourceProfile) err := ms.query(ctx, func(sctx mongo.SessionContext) error { sr := ms.getCol(ColRsP).FindOne(sctx, bson.M{"tenant": tenant, "id": id}) decodeErr := sr.Decode(rsProfile) @@ -686,7 +686,7 @@ func (ms *MongoStorage) GetResourceProfileDrv(ctx *context.Context, tenant, id s return rsProfile, err } -func (ms *MongoStorage) SetResourceProfileDrv(ctx *context.Context, rp *ResourceProfile) error { +func (ms *MongoStorage) SetResourceProfileDrv(ctx *context.Context, rp *utils.ResourceProfile) error { return ms.query(ctx, func(sctx mongo.SessionContext) error { _, err := ms.getCol(ColRsP).UpdateOne(sctx, bson.M{"tenant": rp.Tenant, "id": rp.ID}, bson.M{"$set": rp}, @@ -706,8 +706,8 @@ func (ms *MongoStorage) RemoveResourceProfileDrv(ctx *context.Context, tenant, i }) } -func (ms *MongoStorage) GetResourceDrv(ctx *context.Context, tenant, id string) (*Resource, error) { - resource := new(Resource) +func (ms *MongoStorage) GetResourceDrv(ctx *context.Context, tenant, id string) (*utils.Resource, error) { + resource := new(utils.Resource) err := ms.query(ctx, func(sctx mongo.SessionContext) error { sr := ms.getCol(ColRes).FindOne(sctx, bson.M{"tenant": tenant, "id": id}) decodeErr := sr.Decode(resource) @@ -719,7 +719,7 @@ func (ms *MongoStorage) GetResourceDrv(ctx *context.Context, tenant, id string) return resource, err } -func (ms *MongoStorage) SetResourceDrv(ctx *context.Context, r *Resource) error { +func (ms *MongoStorage) SetResourceDrv(ctx *context.Context, r *utils.Resource) error { return ms.query(ctx, func(sctx mongo.SessionContext) error { _, err := ms.getCol(ColRes).UpdateOne(sctx, bson.M{"tenant": r.Tenant, "id": r.ID}, bson.M{"$set": r}, diff --git a/engine/storage_redis.go b/engine/storage_redis.go index c974f7bd5..dfe427bdd 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -372,7 +372,7 @@ func (rs *RedisStorage) AddLoadHistory(ldInst *utils.LoadInstance, loadHistSize return } -func (rs *RedisStorage) GetResourceProfileDrv(ctx *context.Context, tenant, id string) (rsp *ResourceProfile, err error) { +func (rs *RedisStorage) GetResourceProfileDrv(ctx *context.Context, tenant, id string) (rsp *utils.ResourceProfile, err error) { var values []byte if err = rs.Cmd(&values, redisGET, utils.ResourceProfilesPrefix+utils.ConcatenatedKey(tenant, id)); err != nil { return @@ -384,7 +384,7 @@ func (rs *RedisStorage) GetResourceProfileDrv(ctx *context.Context, tenant, id s return } -func (rs *RedisStorage) SetResourceProfileDrv(ctx *context.Context, rsp *ResourceProfile) (err error) { +func (rs *RedisStorage) SetResourceProfileDrv(ctx *context.Context, rsp *utils.ResourceProfile) (err error) { var result []byte if result, err = rs.ms.Marshal(rsp); err != nil { return @@ -396,7 +396,7 @@ func (rs *RedisStorage) RemoveResourceProfileDrv(ctx *context.Context, tenant, i return rs.Cmd(nil, redisDEL, utils.ResourceProfilesPrefix+utils.ConcatenatedKey(tenant, id)) } -func (rs *RedisStorage) GetResourceDrv(ctx *context.Context, tenant, id string) (r *Resource, err error) { +func (rs *RedisStorage) GetResourceDrv(ctx *context.Context, tenant, id string) (r *utils.Resource, err error) { var values []byte if err = rs.Cmd(&values, redisGET, utils.ResourcesPrefix+utils.ConcatenatedKey(tenant, id)); err != nil { return @@ -408,7 +408,7 @@ func (rs *RedisStorage) GetResourceDrv(ctx *context.Context, tenant, id string) return } -func (rs *RedisStorage) SetResourceDrv(ctx *context.Context, r *Resource) (err error) { +func (rs *RedisStorage) SetResourceDrv(ctx *context.Context, r *utils.Resource) (err error) { var result []byte if result, err = rs.ms.Marshal(r); err != nil { return diff --git a/engine/tpreader.go b/engine/tpreader.go index 0301f62f1..edf3609fd 100644 --- a/engine/tpreader.go +++ b/engine/tpreader.go @@ -390,7 +390,7 @@ func (tpr *TpReader) WriteToDatabase(verbose, disableReverse bool) (err error) { log.Print("ResourceProfiles:") } for _, tpRsp := range tpr.resProfiles { - var rsp *ResourceProfile + var rsp *utils.ResourceProfile if rsp, err = APItoResource(tpRsp, tpr.timezone); err != nil { return } diff --git a/engine/version.go b/engine/version.go index f4f3546da..7912e372f 100644 --- a/engine/version.go +++ b/engine/version.go @@ -132,7 +132,7 @@ func CurrentDataDBVersions() Versions { utils.Routes: 2, utils.Attributes: 7, utils.RQF: 5, - utils.Resource: 1, + utils.ResourceStr: 1, utils.Subscribers: 1, utils.Chargers: 2, utils.LoadIDsVrs: 1, diff --git a/engine/version_test.go b/engine/version_test.go index 9568ae827..668f1c6ab 100644 --- a/engine/version_test.go +++ b/engine/version_test.go @@ -52,7 +52,7 @@ func TestCurrentDBVersions(t *testing.T) { expVersDataDB := Versions{ utils.Stats: 4, utils.AccountsStr: 3, utils.Actions: 2, utils.Thresholds: 4, utils.Routes: 2, utils.Attributes: 7, - utils.RQF: 5, utils.Resource: 1, + utils.RQF: 5, utils.ResourceStr: 1, utils.Subscribers: 1, utils.Chargers: 2, utils.LoadIDsVrs: 1, utils.RateProfiles: 1, @@ -114,7 +114,7 @@ func TestCurrentAllDBVersions(t *testing.T) { utils.Routes: 2, utils.Attributes: 7, utils.RQF: 5, - utils.Resource: 1, + utils.ResourceStr: 1, utils.Subscribers: 1, utils.Chargers: 2, utils.LoadIDsVrs: 1, diff --git a/engine/z_filterindexer_it_test.go b/engine/z_filterindexer_it_test.go index 5680ce675..ed0de5f61 100644 --- a/engine/z_filterindexer_it_test.go +++ b/engine/z_filterindexer_it_test.go @@ -1143,14 +1143,14 @@ func testITResourceProfileIndexes(t *testing.T) { t.Error(err) } - resPref1 := &ResourceProfile{ + resPref1 := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES_PRF1", FilterIDs: []string{"FIRST", "RES_FLTR1", "*string:~*req.Account:DAN"}, Limit: 23, Stored: true, } - resPref2 := &ResourceProfile{ + resPref2 := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES_PRF2", FilterIDs: []string{"RES_FLTR1"}, diff --git a/engine/z_libindex_health_test.go b/engine/z_libindex_health_test.go index a26126bfb..eaaaac11b 100644 --- a/engine/z_libindex_health_test.go +++ b/engine/z_libindex_health_test.go @@ -394,7 +394,7 @@ func TestHealthIndexResources(t *testing.T) { dm := NewDataManager(db, cfg, nil) // we will set this resource but without indexing - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "tenant.custom", ID: "RES_GRP1", FilterIDs: []string{ @@ -472,7 +472,7 @@ func TestHealthIndexResources(t *testing.T) { } //we will use an inexisting Filter(not inline) for the same ResourceProfile - rsPrf = &ResourceProfile{ + rsPrf = &utils.ResourceProfile{ Tenant: "tenant.custom", ID: "RES_GRP1", FilterIDs: []string{ diff --git a/engine/z_onstor_it_test.go b/engine/z_onstor_it_test.go index 761716420..32912498e 100644 --- a/engine/z_onstor_it_test.go +++ b/engine/z_onstor_it_test.go @@ -115,7 +115,7 @@ func testOnStorITIsDBEmpty(t *testing.T) { } func testOnStorITResourceProfile(t *testing.T) { - rL := &ResourceProfile{ + rL := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RL_TEST2", Weights: utils.DynamicWeights{ @@ -173,10 +173,10 @@ func testOnStorITResourceProfile(t *testing.T) { } func testOnStorITResource(t *testing.T) { - res := &Resource{ + res := &utils.Resource{ Tenant: "cgrates.org", ID: "RL1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { ID: "RU1", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 0, time.UTC), diff --git a/engine/z_versions_it_test.go b/engine/z_versions_it_test.go index 81fac442e..1994c32c0 100644 --- a/engine/z_versions_it_test.go +++ b/engine/z_versions_it_test.go @@ -304,7 +304,7 @@ func testUpdateVersionsRQF(t *testing.T) { func testUpdateVersionsResource(t *testing.T) { newVersions := CurrentDataDBVersions() - newVersions[utils.Resource] = 0 + newVersions[utils.ResourceStr] = 0 if err := dm3.DataDB().SetVersions(newVersions, true); err != nil { t.Fatal(err) } diff --git a/flaky_test.sh b/flaky_test.sh index 598d9fbb7..05131a39a 100755 --- a/flaky_test.sh +++ b/flaky_test.sh @@ -8,7 +8,7 @@ # Example: # ./flaky_tests.sh -dbtype=*mysql -rpc=*gob -packages=("agents" "apis" "chargers" "cmd/cgr-console" "cmd/cgr-loader" "efs" "engine" "ers" "general_tests" "loaders" "rankings" "registrarc" "sessions" "trends") +packages=("agents" "apis" "attributes" "chargers" "cmd/cgr-console" "cmd/cgr-loader" "efs" "engine" "ers" "general_tests" "loaders" "rankings" "registrarc" "resources" "routes" "sessions" "trends") dbtypes=("*internal" "*mysql" "*mongo" "*postgres") # Tests that are independent of the dbtype flag and run only once diff --git a/general_tests/attributes_it_test.go b/general_tests/attributes_it_test.go index 299c2c2ce..073c0157c 100644 --- a/general_tests/attributes_it_test.go +++ b/general_tests/attributes_it_test.go @@ -533,7 +533,7 @@ func testAttributeSProcessEventWithStatFull(t *testing.T) { func testAttributeSProcessEventWithResource(t *testing.T) { //create a resourceProfile - rlsConfig := &engine.ResourceProfile{ + rlsConfig := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResTest", UsageTTL: time.Minute, @@ -548,13 +548,13 @@ func testAttributeSProcessEventWithResource(t *testing.T) { } var result string - if err := attrRPC.Call(context.Background(), utils.AdminSv1SetResourceProfile, &engine.ResourceProfileWithAPIOpts{ResourceProfile: rlsConfig}, &result); err != nil { + if err := attrRPC.Call(context.Background(), utils.AdminSv1SetResourceProfile, &utils.ResourceProfileWithAPIOpts{ResourceProfile: rlsConfig}, &result); err != nil { t.Error(err) } else if result != utils.OK { t.Error("Unexpected reply returned", result) } - var reply *engine.ResourceProfile + var reply *utils.ResourceProfile if err := attrRPC.Call(context.Background(), utils.AdminSv1GetResourceProfile, &utils.TenantID{Tenant: "cgrates.org", ID: rlsConfig.ID}, &reply); err != nil { t.Error(err) diff --git a/general_tests/doubleremove_it_test.go b/general_tests/doubleremove_it_test.go index 29e1c709e..10352cc2f 100644 --- a/general_tests/doubleremove_it_test.go +++ b/general_tests/doubleremove_it_test.go @@ -445,15 +445,15 @@ func testdoubleRemoveChargerProfile(t *testing.T) { func testdoubleRemoveResourceProfile(t *testing.T) { // check - var reply *engine.ResourceProfile + var reply *utils.ResourceProfile if err := doubleRemoveRPC.Call(context.Background(), utils.AdminSv1GetResourceProfile, &utils.TenantID{Tenant: doubleRemoveTenant, ID: "RESOURCE_PROFILE"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Error(err) } // set - resPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + resPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: doubleRemoveTenant, ID: "RESOURCE_PROFILE", FilterIDs: []string{"*string:~*req.Account:1001"}, diff --git a/general_tests/export_it_test.go b/general_tests/export_it_test.go index afd584426..c7099b2c4 100644 --- a/general_tests/export_it_test.go +++ b/general_tests/export_it_test.go @@ -327,7 +327,7 @@ func testExpVerifyThresholds(t *testing.T) { } func testExpVerifyResources(t *testing.T) { - rPrf := &engine.ResourceProfile{ + rPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES_ACNT_1001", FilterIDs: []string{"FLTR_ACCOUNT_1001"}, @@ -344,7 +344,7 @@ func testExpVerifyResources(t *testing.T) { if *utils.Encoding == utils.MetaGOB { rPrf.ThresholdIDs = nil } - var reply *engine.ResourceProfile + var reply *utils.ResourceProfile if err := expRpc.Call(context.Background(), utils.AdminSv1GetResourceProfile, &utils.TenantID{Tenant: "cgrates.org", ID: "RES_ACNT_1001"}, &reply); err != nil { t.Error(err) diff --git a/general_tests/filtered_replication_it_test.go b/general_tests/filtered_replication_it_test.go index d67d77ba7..e9dbfbc01 100644 --- a/general_tests/filtered_replication_it_test.go +++ b/general_tests/filtered_replication_it_test.go @@ -740,8 +740,8 @@ func testFltrRplThresholdProfile(t *testing.T) { // func testFltrRplResourceProfile(t *testing.T) { // resID := "RES1" -// resPrf := &engine.ResourceProfileWithAPIOpts{ -// ResourceProfile: &engine.ResourceProfile{ +// resPrf := &utils.ResourceProfileWithAPIOpts{ +// ResourceProfile: &utils.ResourceProfile{ // Tenant: "cgrates.org", // ID: resID, // FilterIDs: []string{"*string:~*req.Account:dan"}, @@ -759,7 +759,7 @@ func testFltrRplThresholdProfile(t *testing.T) { // Usages: make(map[string]*engine.ResourceUsage), // } // var result string -// var replyPrfl *engine.ResourceProfile +// var replyPrfl *utils.ResourceProfile // var rplyIDs []string // var replyRs engine.Resource diff --git a/general_tests/filters_it_test.go b/general_tests/filters_it_test.go index 9e9cba95e..c4d630c69 100644 --- a/general_tests/filters_it_test.go +++ b/general_tests/filters_it_test.go @@ -432,7 +432,7 @@ func testV1FltrGetThresholdForEvent2(t *testing.T) { func testV1FltrPopulateResources(t *testing.T) { //create a resourceProfile - rlsConfig := &engine.ResourceProfile{ + rlsConfig := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResTest", UsageTTL: time.Minute, @@ -448,13 +448,13 @@ func testV1FltrPopulateResources(t *testing.T) { } var result string - if err := fltrRpc.Call(context.Background(), utils.AdminSv1SetResourceProfile, &engine.ResourceProfileWithAPIOpts{ResourceProfile: rlsConfig}, &result); err != nil { + if err := fltrRpc.Call(context.Background(), utils.AdminSv1SetResourceProfile, &utils.ResourceProfileWithAPIOpts{ResourceProfile: rlsConfig}, &result); err != nil { t.Error(err) } else if result != utils.OK { t.Error("Unexpected reply returned", result) } - var reply *engine.ResourceProfile + var reply *utils.ResourceProfile if err := fltrRpc.Call(context.Background(), utils.AdminSv1GetResourceProfile, &utils.TenantIDWithAPIOpts{ TenantID: &utils.TenantID{ @@ -593,7 +593,7 @@ func testV1FltrPopulateResources(t *testing.T) { func testV1FltrPopulateResourcesAvailableUnits(t *testing.T) { //create a resourceProfile - rlsConfig := &engine.ResourceProfile{ + rlsConfig := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES_TEST", UsageTTL: time.Minute, @@ -609,13 +609,13 @@ func testV1FltrPopulateResourcesAvailableUnits(t *testing.T) { } var result string - if err := fltrRpc.Call(context.Background(), utils.AdminSv1SetResourceProfile, &engine.ResourceProfileWithAPIOpts{ResourceProfile: rlsConfig}, &result); err != nil { + if err := fltrRpc.Call(context.Background(), utils.AdminSv1SetResourceProfile, &utils.ResourceProfileWithAPIOpts{ResourceProfile: rlsConfig}, &result); err != nil { t.Error(err) } else if result != utils.OK { t.Error("Unexpected reply returned", result) } - var reply *engine.ResourceProfile + var reply *utils.ResourceProfile if err := fltrRpc.Call(context.Background(), utils.AdminSv1GetResourceProfile, &utils.TenantIDWithAPIOpts{ TenantID: &utils.TenantID{ diff --git a/general_tests/resourcesv1_it_test.go b/general_tests/resourcesv1_it_test.go index 0a204daaa..a428cda82 100644 --- a/general_tests/resourcesv1_it_test.go +++ b/general_tests/resourcesv1_it_test.go @@ -28,6 +28,7 @@ import ( "github.com/cgrates/birpc/context" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/resources" "github.com/cgrates/cgrates/utils" ) @@ -97,8 +98,8 @@ func testV1RsRpcConn(t *testing.T) { } func testV1RsSetProfile(t *testing.T) { - rls := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rls := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES_GR_TEST", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -163,7 +164,7 @@ func testV1RsAllocate(t *testing.T) { } func testV1RsAuthorize(t *testing.T) { - var reply *engine.Resources + var reply *resources.Resources args := &utils.CGREvent{ Tenant: "cgrates.org", ID: utils.UUIDSha1Prefix(), @@ -189,11 +190,11 @@ func testV1RsAuthorize(t *testing.T) { if len(*reply) != 1 { t.Errorf("Expecting: %+v, received: %+v", 1, len(*reply)) } - if (*reply)[0].ID != "RES_GR_TEST" { - t.Errorf("Expecting: %+v, received: %+v", "RES_GR_TEST", (*reply)[0].ID) + if (*reply)[0].Resource.ID != "RES_GR_TEST" { + t.Errorf("Expecting: %+v, received: %+v", "RES_GR_TEST", (*reply)[0].Resource.ID) } - if len((*reply)[0].Usages) != 2 { - t.Errorf("Expecting: %+v, received: %+v", 2, len((*reply)[0].Usages)) + if len((*reply)[0].Resource.Usages) != 2 { + t.Errorf("Expecting: %+v, received: %+v", 2, len((*reply)[0].Resource.Usages)) } var reply2 string diff --git a/general_tests/route_it_test.go b/general_tests/route_it_test.go index bc4c69c22..5cc97df48 100644 --- a/general_tests/route_it_test.go +++ b/general_tests/route_it_test.go @@ -295,8 +295,8 @@ func testV1SplSAddNewSplPrf(t *testing.T) { func testV1SplSAddNewResPrf(t *testing.T) { var result string //add ResourceSupplier1 - rPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResourceSupplier1", FilterIDs: []string{"*string:~*req.Supplier:route1", "*string:~*req.ResID:ResourceSupplier1"}, @@ -318,8 +318,8 @@ func testV1SplSAddNewResPrf(t *testing.T) { t.Error("Unexpected reply returned", result) } //add Resource2Supplier1 - rPrf2 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rPrf2 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "Resource2Supplier1", FilterIDs: []string{"*string:~*req.Supplier:route1", "*string:~*req.ResID:Resource2Supplier1"}, @@ -341,8 +341,8 @@ func testV1SplSAddNewResPrf(t *testing.T) { t.Error("Unexpected reply returned", result) } //add ResourceSupplier2 - rPrf3 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rPrf3 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResourceSupplier2", FilterIDs: []string{"*string:~*req.Supplier:route2", "*string:~*req.ResID:ResourceSupplier2"}, @@ -364,8 +364,8 @@ func testV1SplSAddNewResPrf(t *testing.T) { t.Error("Unexpected reply returned", result) } //add ResourceSupplier2 - rPrf4 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rPrf4 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResourceSupplier3", FilterIDs: []string{"*string:~*req.Supplier:route3", "*string:~*req.ResID:ResourceSupplier3"}, diff --git a/general_tests/routes_cases_it_test.go b/general_tests/routes_cases_it_test.go index 542c27f9d..2c909bad7 100644 --- a/general_tests/routes_cases_it_test.go +++ b/general_tests/routes_cases_it_test.go @@ -1353,15 +1353,15 @@ func testV1RtsCasesSortingRoutesReasNotAllRoutes(t *testing.T) { { RouteID: "vendor1", SortingData: map[string]any{ - utils.ResourceUsage: 6.0, - utils.Weight: 0., + utils.ResourceUsageStr: 6.0, + utils.Weight: 0., }, }, { RouteID: "vendor2", SortingData: map[string]any{ - utils.ResourceUsage: 7.0, - utils.Weight: 0., + utils.ResourceUsageStr: 7.0, + utils.Weight: 0., }, }, }, @@ -1412,22 +1412,22 @@ func testV1RtsCasesSortingRoutesReasAllRoutes(t *testing.T) { { RouteID: "vendor3", SortingData: map[string]any{ - utils.ResourceUsage: 7.0, - utils.Weight: 10., + utils.ResourceUsageStr: 7.0, + utils.Weight: 10., }, }, { RouteID: "vendor2", SortingData: map[string]any{ - utils.ResourceUsage: 7.0, - utils.Weight: 0., + utils.ResourceUsageStr: 7.0, + utils.Weight: 0., }, }, { RouteID: "vendor1", SortingData: map[string]any{ - utils.ResourceUsage: 9.0, - utils.Weight: 0., + utils.ResourceUsageStr: 9.0, + utils.Weight: 0., }, }, }, diff --git a/general_tests/set_rmv_prfl_dlay_it_test.go b/general_tests/set_rmv_prfl_dlay_it_test.go index 7eb600c93..e9bad7316 100644 --- a/general_tests/set_rmv_prfl_dlay_it_test.go +++ b/general_tests/set_rmv_prfl_dlay_it_test.go @@ -123,8 +123,8 @@ func TestSetRemoveProfilesWithCachingDelay(t *testing.T) { t.Run("SetResourceProfile", func(t *testing.T) { - eRscPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + eRscPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RSC_1", }, @@ -307,8 +307,8 @@ func TestSetRemoveProfilesWithCachingDelay(t *testing.T) { t.Run("ReplicatorSv1SetResourceProfile", func(t *testing.T) { - eRscPrf := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + eRscPrf := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RSC_2", }, diff --git a/integration_test.sh b/integration_test.sh index 9efe3b8a9..3d41659c6 100755 --- a/integration_test.sh +++ b/integration_test.sh @@ -8,7 +8,7 @@ # Example: # ./integration_test.sh -dbtype=*mysql -rpc=*gob -packages=("agents" "apis" "chargers" "cmd/cgr-console" "cmd/cgr-loader" "efs" "engine" "ers" "general_tests" "loaders" "rankings" "registrarc" "sessions" "trends") +packages=("agents" "apis" "attributes" "chargers" "cmd/cgr-console" "cmd/cgr-loader" "efs" "engine" "ers" "general_tests" "loaders" "rankings" "registrarc" "resources" "routes" "sessions" "trends") dbtypes=("*internal" "*mysql" "*mongo" "*postgres") # Tests that are independent of the dbtype flag and run only once diff --git a/loaders/libloader.go b/loaders/libloader.go index 3da681e53..04da0aeeb 100644 --- a/loaders/libloader.go +++ b/loaders/libloader.go @@ -268,7 +268,7 @@ func newProfileFunc(lType string) func() profile { } case utils.MetaResources: return func() profile { - return new(engine.ResourceProfile) + return new(utils.ResourceProfile) } case utils.MetaFilters: return func() profile { diff --git a/loaders/loader.go b/loaders/loader.go index 665276813..db0e5e392 100644 --- a/loaders/loader.go +++ b/loaders/loader.go @@ -82,7 +82,7 @@ func setToDB(ctx *context.Context, dm *engine.DataManager, lType string, data pr case utils.MetaAttributes: return dm.SetAttributeProfile(ctx, data.(*utils.AttributeProfile), withIndex) case utils.MetaResources: - return dm.SetResourceProfile(ctx, data.(*engine.ResourceProfile), withIndex) + return dm.SetResourceProfile(ctx, data.(*utils.ResourceProfile), withIndex) case utils.MetaFilters: fltr := data.(*engine.Filter) fltr.Compress() diff --git a/loaders/loader_test.go b/loaders/loader_test.go index 1c99bcc66..6773bb71e 100644 --- a/loaders/loader_test.go +++ b/loaders/loader_test.go @@ -206,7 +206,7 @@ func TestSetToDB(t *testing.T) { t.Errorf("Expected: %v, received: %v", utils.ToJSON(v1), utils.ToJSON(prf)) } - v2 := &engine.ResourceProfile{Tenant: "cgrates.org", ID: "ID"} + v2 := &utils.ResourceProfile{Tenant: "cgrates.org", ID: "ID"} if err := setToDB(context.Background(), dm, utils.MetaResources, v2, true, false); err != nil { t.Fatal(err) } @@ -435,7 +435,7 @@ func TestLoaderProcessCallCahe(t *testing.T) { } } { - v := &engine.ResourceProfile{Tenant: "cgrates.org", ID: "ID"} + v := &utils.ResourceProfile{Tenant: "cgrates.org", ID: "ID"} if err := ld.process(context.Background(), v, utils.MetaResources, utils.MetaStore, map[string]any{utils.MetaCache: utils.MetaReload}, true, false); err != nil { t.Error(err) diff --git a/migrator/resource.go b/migrator/resource.go index eaf06931d..983aedfa1 100644 --- a/migrator/resource.go +++ b/migrator/resource.go @@ -51,7 +51,7 @@ func (m *Migrator) migrateCurrentResource() (err error) { if err := m.dmIN.DataManager().RemoveResourceProfile(context.TODO(), tntID[0], tntID[1], false); err != nil { return err } - m.stats[utils.Resource]++ + m.stats[utils.ResourceStr]++ } return } @@ -59,18 +59,18 @@ func (m *Migrator) migrateCurrentResource() (err error) { func (m *Migrator) migrateResources() (err error) { var vrs engine.Versions current := engine.CurrentDataDBVersions() - if vrs, err = m.getVersions(utils.Resource); err != nil { + if vrs, err = m.getVersions(utils.ResourceStr); err != nil { return } migrated := true for { - version := vrs[utils.Resource] + version := vrs[utils.ResourceStr] for { switch version { default: return fmt.Errorf("Unsupported version %v", version) - case current[utils.Resource]: + case current[utils.ResourceStr]: migrated = false if m.sameDataDB { break @@ -79,7 +79,7 @@ func (m *Migrator) migrateResources() (err error) { return } } - if version == current[utils.Resource] || err == utils.ErrNoMoreData { + if version == current[utils.ResourceStr] || err == utils.ErrNoMoreData { break } } @@ -91,10 +91,10 @@ func (m *Migrator) migrateResources() (err error) { // return // } // } - m.stats[utils.Resource]++ + m.stats[utils.ResourceStr]++ } // All done, update version wtih current one - if err = m.setVersions(utils.Resource); err != nil { + if err = m.setVersions(utils.ResourceStr); err != nil { return } return m.ensureIndexesDataDB(engine.ColRsP) diff --git a/migrator/resource_it_test.go b/migrator/resource_it_test.go index fab2f78a8..75c80cb9b 100644 --- a/migrator/resource_it_test.go +++ b/migrator/resource_it_test.go @@ -180,7 +180,7 @@ func testResITFlush(t *testing.T) { } func testResITMigrateAndMove(t *testing.T) { - resPrfl := &engine.ResourceProfile{ + resPrfl := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -223,8 +223,8 @@ func testResITMigrateAndMove(t *testing.T) { result, err = resMigrator.dmIN.DataManager().GetResourceProfile(context.TODO(), "cgrates.org", "RES1", false, false, utils.NonTransactional) if err != utils.ErrNotFound { t.Error(err) - } else if resMigrator.stats[utils.Resource] != 1 { - t.Errorf("Expected 1, received: %v", resMigrator.stats[utils.Resource]) + } else if resMigrator.stats[utils.ResourceStr] != 1 { + t.Errorf("Expected 1, received: %v", resMigrator.stats[utils.ResourceStr]) } } } diff --git a/engine/resources.go b/resources/resources.go similarity index 62% rename from engine/resources.go rename to resources/resources.go index df6ed46cd..5ee34ddd4 100644 --- a/engine/resources.go +++ b/resources/resources.go @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -package engine +package resources import ( "cmp" @@ -28,56 +28,31 @@ import ( "github.com/cgrates/birpc/context" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" "github.com/cgrates/guardian" ) -// ResourceProfile represents the user configuration for the resource -type ResourceProfile struct { - Tenant string - ID string // identifier of this resource - FilterIDs []string - UsageTTL time.Duration // auto-expire the usage after this duration - Limit float64 // limixt value - AllocationMessage string // message returned by the winning resource on allocation - Blocker bool // blocker flag to stop processing on filters matched - Stored bool - Weights utils.DynamicWeights // Weight to sort the resources - ThresholdIDs []string // Thresholds to check after changing Limit +// resourceProfile represents the user configuration for the resource +type resourceProfile struct { + ResourceProfile *utils.ResourceProfile + lkID string // holds the reference towards guardian lock key - lkID string // holds the reference towards guardian lock key - -} - -// ResourceProfileWithAPIOpts is used in replicatorV1 for dispatcher -type ResourceProfileWithAPIOpts struct { - *ResourceProfile - APIOpts map[string]any -} - -// TenantID returns unique identifier of the ResourceProfile in a multi-tenant environment -func (rp *ResourceProfile) TenantID() string { - return utils.ConcatenatedKey(rp.Tenant, rp.ID) -} - -// resourceProfileLockKey returns the ID used to lock a resourceProfile with guardian -func resourceProfileLockKey(tnt, id string) string { - return utils.ConcatenatedKey(utils.CacheResourceProfiles, tnt, id) } // lock will lock the resourceProfile using guardian and store the lock within r.lkID // if lkID is passed as argument, the lock is considered as executed -func (rp *ResourceProfile) lock(lkID string) { +func (rp *resourceProfile) lock(lkID string) { if lkID == utils.EmptyString { lkID = guardian.Guardian.GuardIDs("", config.CgrConfig().GeneralCfg().LockingTimeout, - resourceProfileLockKey(rp.Tenant, rp.ID)) + utils.ResourceProfileLockKey(rp.ResourceProfile.Tenant, rp.ResourceProfile.ID)) } rp.lkID = lkID } // unlock will unlock the resourceProfile and clear rp.lkID -func (rp *ResourceProfile) unlock() { +func (rp *resourceProfile) unlock() { if rp.lkID == utils.EmptyString { return } @@ -86,67 +61,34 @@ func (rp *ResourceProfile) unlock() { } // isLocked returns the locks status of this resourceProfile -func (rp *ResourceProfile) isLocked() bool { +func (rp *resourceProfile) isLocked() bool { return rp.lkID != utils.EmptyString } -// ResourceUsage represents an usage counted -type ResourceUsage struct { - Tenant string - ID string // Unique identifier of this ResourceUsage, Eg: FreeSWITCH UUID - ExpiryTime time.Time - Units float64 // Number of units used -} - -// TenantID returns the concatenated key between tenant and ID -func (ru *ResourceUsage) TenantID() string { - return utils.ConcatenatedKey(ru.Tenant, ru.ID) -} - -// isActive checks ExpiryTime at some time -func (ru *ResourceUsage) isActive(atTime time.Time) bool { - return ru.ExpiryTime.IsZero() || ru.ExpiryTime.Sub(atTime) > 0 -} - -// Clone duplicates ru -func (ru *ResourceUsage) Clone() (cln *ResourceUsage) { - cln = new(ResourceUsage) - *cln = *ru - return -} - -// Resource represents a resource in the system +// resource represents a resource in the system // not thread safe, needs locking at process level -type Resource struct { - Tenant string - ID string - Usages map[string]*ResourceUsage - TTLIdx []string // holds ordered list of ResourceIDs based on their TTL, empty if feature is disableda - lkID string // ID of the lock used when matching the resource - ttl *time.Duration // time to leave for this resource, picked up on each Resource initialization out of config - tUsage *float64 // sum of all usages - dirty *bool // the usages were modified, needs save, *bool so we only save if enabled in config - rPrf *ResourceProfile // for ordering purposes -} - -// resourceLockKey returns the ID used to lock a resource with guardian -func resourceLockKey(tnt, id string) string { - return utils.ConcatenatedKey(utils.CacheResources, tnt, id) +type resource struct { + Resource *utils.Resource + lkID string // ID of the lock used when matching the resource + ttl *time.Duration // time to leave for this resource, picked up on each Resource initialization out of config + tUsage *float64 // sum of all usages + dirty *bool // the usages were modified, needs save, *bool so we only save if enabled in config + rPrf *resourceProfile // for ordering purposes } // lock will lock the resource using guardian and store the lock within r.lkID // if lkID is passed as argument, the lock is considered as executed -func (r *Resource) lock(lkID string) { +func (r *resource) lock(lkID string) { if lkID == utils.EmptyString { lkID = guardian.Guardian.GuardIDs("", config.CgrConfig().GeneralCfg().LockingTimeout, - resourceLockKey(r.Tenant, r.ID)) + utils.ResourceLockKey(r.Resource.Tenant, r.Resource.ID)) } r.lkID = lkID } // unlock will unlock the resource and clear r.lkID -func (r *Resource) unlock() { +func (r *resource) unlock() { if r.lkID == utils.EmptyString { return } @@ -155,26 +97,15 @@ func (r *Resource) unlock() { } // isLocked returns the locks status of this resource -func (r *Resource) isLocked() bool { +func (r *resource) isLocked() bool { return r.lkID != utils.EmptyString } -// ResourceWithAPIOpts is used in replicatorV1 for dispatcher -type ResourceWithAPIOpts struct { - *Resource - APIOpts map[string]any -} - -// TenantID returns the unique ID in a multi-tenant environment -func (r *Resource) TenantID() string { - return utils.ConcatenatedKey(r.Tenant, r.ID) -} - // removeExpiredUnits removes units which are expired from the resource -func (r *Resource) removeExpiredUnits() { +func (r *resource) removeExpiredUnits() { var firstActive int - for _, rID := range r.TTLIdx { - if r, has := r.Usages[rID]; has && r.isActive(time.Now()) { + for _, rID := range r.Resource.TTLIdx { + if r, has := r.Resource.Usages[rID]; has && r.IsActive(time.Now()) { break } firstActive++ @@ -182,50 +113,28 @@ func (r *Resource) removeExpiredUnits() { if firstActive == 0 { return } - for _, rID := range r.TTLIdx[:firstActive] { - ru, has := r.Usages[rID] + for _, rID := range r.Resource.TTLIdx[:firstActive] { + ru, has := r.Resource.Usages[rID] if !has { continue } - delete(r.Usages, rID) + delete(r.Resource.Usages, rID) if r.tUsage != nil { // total usage was not yet calculated so we do not need to update it *r.tUsage -= ru.Units if *r.tUsage < 0 { // something went wrong utils.Logger.Warning( - fmt.Sprintf("resetting total usage for resourceID: %s, usage smaller than 0: %f", r.ID, *r.tUsage)) + fmt.Sprintf("resetting total usage for resourceID: %s, usage smaller than 0: %f", r.Resource.ID, *r.tUsage)) r.tUsage = nil } } } - r.TTLIdx = r.TTLIdx[firstActive:] + r.Resource.TTLIdx = r.Resource.TTLIdx[firstActive:] r.tUsage = nil } -// TotalUsage returns the sum of all usage units -// Exported to be used in FilterS -func (r *Resource) TotalUsage() (tU float64) { - if r.tUsage == nil { - var tu float64 - for _, ru := range r.Usages { - tu += ru.Units - } - r.tUsage = &tu - } - if r.tUsage != nil { - tU = *r.tUsage - } - return -} - -// Available returns the available number of units -// Exported method to be used by filterS -func (r *ResourceWithConfig) Available() float64 { - return r.Config.Limit - r.TotalUsage() -} - // recordUsage records a new usage -func (r *Resource) recordUsage(ru *ResourceUsage) (err error) { - if _, hasID := r.Usages[ru.ID]; hasID { +func (r *resource) recordUsage(ru *utils.ResourceUsage) (err error) { + if _, hasID := r.Resource.Usages[ru.ID]; hasID { return fmt.Errorf("duplicate resource usage with id: %s", ru.TenantID()) } if r.ttl != nil && *r.ttl != -1 { @@ -235,26 +144,26 @@ func (r *Resource) recordUsage(ru *ResourceUsage) (err error) { ru = ru.Clone() // don't influence the initial ru ru.ExpiryTime = time.Now().Add(*r.ttl) } - r.Usages[ru.ID] = ru + r.Resource.Usages[ru.ID] = ru if r.tUsage != nil { *r.tUsage += ru.Units } if !ru.ExpiryTime.IsZero() { - r.TTLIdx = append(r.TTLIdx, ru.ID) + r.Resource.TTLIdx = append(r.Resource.TTLIdx, ru.ID) } return } // clearUsage clears the usage for an ID -func (r *Resource) clearUsage(ruID string) (err error) { - ru, hasIt := r.Usages[ruID] +func (r *resource) clearUsage(ruID string) (err error) { + ru, hasIt := r.Resource.Usages[ruID] if !hasIt { return fmt.Errorf("cannot find usage record with id: %s", ruID) } if !ru.ExpiryTime.IsZero() { - for i, ruIDIdx := range r.TTLIdx { + for i, ruIDIdx := range r.Resource.TTLIdx { if ruIDIdx == ruID { - r.TTLIdx = append(r.TTLIdx[:i], r.TTLIdx[i+1:]...) + r.Resource.TTLIdx = append(r.Resource.TTLIdx[:i], r.Resource.TTLIdx[i+1:]...) break } } @@ -262,12 +171,12 @@ func (r *Resource) clearUsage(ruID string) (err error) { if r.tUsage != nil { *r.tUsage -= ru.Units } - delete(r.Usages, ruID) + delete(r.Resource.Usages, ruID) return } // Resources is a collection of Resource objects. -type Resources []*Resource +type Resources []*resource // unlock will unlock resources part of this slice func (rs Resources) unlock() { @@ -283,13 +192,13 @@ func (rs Resources) unlock() { func (rs Resources) resIDsMp() (mp utils.StringSet) { mp = make(utils.StringSet) for _, r := range rs { - mp.Add(r.ID) + mp.Add(r.Resource.ID) } return mp } // recordUsage will record the usage in all the resource limits, failing back on errors -func (rs Resources) recordUsage(ru *ResourceUsage) (err error) { +func (rs Resources) recordUsage(ru *utils.ResourceUsage) (err error) { var nonReservedIdx int // index of first resource not reserved for _, r := range rs { if err = r.recordUsage(ru); err != nil { @@ -323,23 +232,23 @@ func (rs Resources) clearUsage(ruTntID string) (err error) { // allocateResource attempts allocating resources for a *ResourceUsage // simulates on dryRun // returns utils.ErrResourceUnavailable if allocation is not possible -func (rs Resources) allocateResource(ru *ResourceUsage, dryRun bool) (alcMessage string, err error) { +func (rs Resources) allocateResource(ru *utils.ResourceUsage, dryRun bool) (alcMessage string, err error) { if len(rs) == 0 { return "", utils.ErrResourceUnavailable } // Simulate resource usage for _, r := range rs { r.removeExpiredUnits() - if _, hasID := r.Usages[ru.ID]; hasID && !dryRun { // update + if _, hasID := r.Resource.Usages[ru.ID]; hasID && !dryRun { // update r.clearUsage(ru.ID) // clearUsage returns error only when ru.ID does not exist in the Usages map } if r.rPrf == nil { - err = fmt.Errorf("empty configuration for resourceID: %s", r.TenantID()) + err = fmt.Errorf("empty configuration for resourceID: %s", r.Resource.TenantID()) return } if alcMessage == utils.EmptyString && - (r.rPrf.Limit >= r.TotalUsage()+ru.Units || r.rPrf.Limit == -1) { - alcMessage = utils.FirstNonEmpty(r.rPrf.AllocationMessage, r.rPrf.ID) + (r.rPrf.ResourceProfile.Limit >= r.Resource.TotalUsage()+ru.Units || r.rPrf.ResourceProfile.Limit == -1) { + alcMessage = utils.FirstNonEmpty(r.rPrf.ResourceProfile.AllocationMessage, r.rPrf.ResourceProfile.ID) } } if alcMessage == "" { @@ -354,8 +263,8 @@ func (rs Resources) allocateResource(ru *ResourceUsage, dryRun bool) (alcMessage } // NewResourceService returns a new ResourceService -func NewResourceService(dm *DataManager, cgrcfg *config.CGRConfig, - filterS *FilterS, connMgr *ConnManager) *ResourceS { +func NewResourceService(dm *engine.DataManager, cgrcfg *config.CGRConfig, + filterS *engine.FilterS, connMgr *engine.ConnManager) *ResourceS { return &ResourceS{dm: dm, storedResources: make(utils.StringSet), cfg: cgrcfg, @@ -369,14 +278,14 @@ func NewResourceService(dm *DataManager, cgrcfg *config.CGRConfig, // ResourceS is the service handling resources type ResourceS struct { - dm *DataManager // So we can load the data in cache and index it - fltrS *FilterS + dm *engine.DataManager // So we can load the data in cache and index it + fltrS *engine.FilterS storedResources utils.StringSet // keep a record of resources which need saving, map[resID]bool srMux sync.RWMutex // protects storedResources cfg *config.CGRConfig stopBackup chan struct{} // control storing process loopStopped chan struct{} - connMgr *ConnManager + connMgr *engine.ConnManager } // Reload stops the backupLoop and restarts it @@ -429,12 +338,12 @@ func (rS *ResourceS) storeResources(ctx *context.Context) { if rID == "" { break // no more keys, backup completed } - rIf, ok := Cache.Get(utils.CacheResources, rID) + rIf, ok := engine.Cache.Get(utils.CacheResources, rID) if !ok || rIf == nil { utils.Logger.Warning(fmt.Sprintf("<%s> failed retrieving from cache resource with ID: %s", utils.ResourceS, rID)) continue } - r := rIf.(*Resource) + r := rIf.(*resource) r.lock(utils.EmptyString) if err := rS.storeResource(ctx, r); err != nil { failedRIDs = append(failedRIDs, rID) // record failure so we can schedule it for next backup @@ -451,19 +360,19 @@ func (rS *ResourceS) storeResources(ctx *context.Context) { } // StoreResource stores the resource in DB and corrects dirty flag -func (rS *ResourceS) storeResource(ctx *context.Context, r *Resource) (err error) { +func (rS *ResourceS) storeResource(ctx *context.Context, r *resource) (err error) { if r.dirty == nil || !*r.dirty { return } - if err = rS.dm.SetResource(ctx, r); err != nil { + if err = rS.dm.SetResource(ctx, r.Resource); err != nil { utils.Logger.Warning( fmt.Sprintf(" failed saving Resource with ID: %s, error: %s", - r.ID, err.Error())) + r.Resource.ID, err.Error())) return } //since we no longer handle cache in DataManager do here a manual caching - if tntID := r.TenantID(); Cache.HasItem(utils.CacheResources, tntID) { // only cache if previously there - if err = Cache.Set(ctx, utils.CacheResources, tntID, r, nil, + if tntID := r.Resource.TenantID(); engine.Cache.HasItem(utils.CacheResources, tntID) { // only cache if previously there + if err = engine.Cache.Set(ctx, utils.CacheResources, tntID, r.Resource, nil, true, utils.NonTransactional); err != nil { utils.Logger.Warning( fmt.Sprintf(" failed caching Resource with ID: %s, error: %s", @@ -488,7 +397,7 @@ func (rS *ResourceS) storeMatchedResources(ctx *context.Context, mtcRLs Resource if r.dirty != nil { *r.dirty = true // mark it to be saved if rS.cfg.ResourceSCfg().StoreInterval > 0 { - rS.storedResources.Add(r.TenantID()) + rS.storedResources.Add(r.Resource.TenantID()) continue } if err = rS.storeResource(ctx, r); err != nil { @@ -512,26 +421,26 @@ func (rS *ResourceS) processThresholds(ctx *context.Context, rs Resources, opts var withErrs bool for _, r := range rs { - if len(r.rPrf.ThresholdIDs) == 1 && - r.rPrf.ThresholdIDs[0] == utils.MetaNone { + if len(r.rPrf.ResourceProfile.ThresholdIDs) == 1 && + r.rPrf.ResourceProfile.ThresholdIDs[0] == utils.MetaNone { continue } - opts[utils.OptsThresholdsProfileIDs] = r.rPrf.ThresholdIDs + opts[utils.OptsThresholdsProfileIDs] = r.rPrf.ResourceProfile.ThresholdIDs thEv := &utils.CGREvent{ - Tenant: r.Tenant, + Tenant: r.Resource.Tenant, ID: utils.GenUUID(), Event: map[string]any{ utils.EventType: utils.ResourceUpdate, - utils.ResourceID: r.ID, - utils.Usage: r.TotalUsage(), + utils.ResourceID: r.Resource.ID, + utils.Usage: r.Resource.TotalUsage(), }, APIOpts: opts, } var tIDs []string if err := rS.connMgr.Call(ctx, rS.cfg.ResourceSCfg().ThresholdSConns, utils.ThresholdSv1ProcessEvent, thEv, &tIDs); err != nil && - (len(r.rPrf.ThresholdIDs) != 0 || err.Error() != utils.ErrNotFound.Error()) { + (len(r.rPrf.ResourceProfile.ThresholdIDs) != 0 || err.Error() != utils.ErrNotFound.Error()) { utils.Logger.Warning( fmt.Sprintf("<%s> error: %s processing event %+v with %s.", utils.ResourceS, err.Error(), thEv, utils.ThresholdS)) @@ -552,22 +461,25 @@ func (rS *ResourceS) matchingResourcesForEvent(ctx *context.Context, tnt string, utils.MetaReq: ev.Event, utils.MetaOpts: ev.APIOpts, } - if x, ok := Cache.Get(utils.CacheEventResources, evUUID); ok { // The ResourceIDs were cached as utils.StringSet{"resID":bool} + if x, ok := engine.Cache.Get(utils.CacheEventResources, evUUID); ok { // The ResourceIDs were cached as utils.StringSet{"resID":bool} if x == nil { return nil, utils.ErrNotFound } rIDs = x.(utils.StringSet) defer func() { // make sure we uncache if we find errors if err != nil { - if errCh := Cache.Remove(ctx, utils.CacheEventResources, evUUID, - cacheCommit(utils.NonTransactional), utils.NonTransactional); errCh != nil { + // TODO: Consider using RemoveWithoutReplicate instead, as + // partitions with Replicate=true call ReplicateRemove in + // onEvict by default. + if errCh := engine.Cache.Remove(ctx, utils.CacheEventResources, evUUID, + true, utils.NonTransactional); errCh != nil { err = errCh } } }() } else { // select the resourceIDs out of dataDB - rIDs, err = MatchingItemIDsForEvent(ctx, evNm, + rIDs, err = engine.MatchingItemIDsForEvent(ctx, evNm, rS.cfg.ResourceSCfg().StringIndexedFields, rS.cfg.ResourceSCfg().PrefixIndexedFields, rS.cfg.ResourceSCfg().SuffixIndexedFields, @@ -579,7 +491,7 @@ func (rS *ResourceS) matchingResourcesForEvent(ctx *context.Context, tnt string, ) if err != nil { if err == utils.ErrNotFound { - if errCh := Cache.Set(ctx, utils.CacheEventResources, evUUID, nil, nil, true, ""); errCh != nil { // cache negative match + if errCh := engine.Cache.Set(ctx, utils.CacheEventResources, evUUID, nil, nil, true, ""); errCh != nil { // cache negative match return nil, errCh } } @@ -591,9 +503,9 @@ func (rS *ResourceS) matchingResourcesForEvent(ctx *context.Context, tnt string, for resName := range rIDs { lkPrflID := guardian.Guardian.GuardIDs("", config.CgrConfig().GeneralCfg().LockingTimeout, - resourceProfileLockKey(tnt, resName)) - var rPrf *ResourceProfile - if rPrf, err = rS.dm.GetResourceProfile(ctx, tnt, resName, + utils.ResourceProfileLockKey(tnt, resName)) + var rp *utils.ResourceProfile + if rp, err = rS.dm.GetResourceProfile(ctx, tnt, resName, true, true, utils.NonTransactional); err != nil { guardian.Guardian.UnguardIDs(lkPrflID) if err == utils.ErrNotFound { @@ -602,9 +514,12 @@ func (rS *ResourceS) matchingResourcesForEvent(ctx *context.Context, tnt string, rs.unlock() return } + rPrf := &resourceProfile{ + ResourceProfile: rp, + } rPrf.lock(lkPrflID) var pass bool - if pass, err = rS.fltrS.Pass(ctx, tnt, rPrf.FilterIDs, + if pass, err = rS.fltrS.Pass(ctx, tnt, rPrf.ResourceProfile.FilterIDs, evNm); err != nil { rPrf.unlock() rs.unlock() @@ -615,31 +530,34 @@ func (rS *ResourceS) matchingResourcesForEvent(ctx *context.Context, tnt string, } lkID := guardian.Guardian.GuardIDs(utils.EmptyString, config.CgrConfig().GeneralCfg().LockingTimeout, - resourceLockKey(rPrf.Tenant, rPrf.ID)) - var r *Resource - if r, err = rS.dm.GetResource(ctx, rPrf.Tenant, rPrf.ID, true, true, ""); err != nil { + utils.ResourceLockKey(rPrf.ResourceProfile.Tenant, rPrf.ResourceProfile.ID)) + var res *utils.Resource + if res, err = rS.dm.GetResource(ctx, rPrf.ResourceProfile.Tenant, rPrf.ResourceProfile.ID, true, true, ""); err != nil { guardian.Guardian.UnguardIDs(lkID) rPrf.unlock() rs.unlock() return nil, err } + r := &resource{ + Resource: res, + } r.lock(lkID) // pass the lock into resource so we have it as reference - if rPrf.Stored && r.dirty == nil { + if rPrf.ResourceProfile.Stored && r.dirty == nil { r.dirty = utils.BoolPointer(false) } if usageTTL != nil { if *usageTTL != 0 { r.ttl = usageTTL } - } else if rPrf.UsageTTL >= 0 { - r.ttl = utils.DurationPointer(rPrf.UsageTTL) + } else if rPrf.ResourceProfile.UsageTTL >= 0 { + r.ttl = utils.DurationPointer(rPrf.ResourceProfile.UsageTTL) } r.rPrf = rPrf - weight, err := WeightFromDynamics(ctx, rPrf.Weights, rS.fltrS, tnt, evNm) + weight, err := engine.WeightFromDynamics(ctx, rPrf.ResourceProfile.Weights, rS.fltrS, tnt, evNm) if err != nil { return nil, err } - weights[r.ID] = weight + weights[r.Resource.ID] = weight rs = append(rs, r) } @@ -648,18 +566,18 @@ func (rS *ResourceS) matchingResourcesForEvent(ctx *context.Context, tnt string, } // Sort by weight (higher values first). - slices.SortFunc(rs, func(a, b *Resource) int { - return cmp.Compare(weights[b.ID], weights[a.ID]) + slices.SortFunc(rs, func(a, b *resource) int { + return cmp.Compare(weights[b.Resource.ID], weights[a.Resource.ID]) }) for i, r := range rs { - if r.rPrf.Blocker && i != len(rs)-1 { // blocker will stop processing and we are not at last index + if r.rPrf.ResourceProfile.Blocker && i != len(rs)-1 { // blocker will stop processing and we are not at last index Resources(rs[i+1:]).unlock() rs = rs[:i+1] break } } - if err = Cache.Set(ctx, utils.CacheEventResources, evUUID, rs.resIDsMp(), nil, true, ""); err != nil { + if err = engine.Cache.Set(ctx, utils.CacheEventResources, evUUID, rs.resIDsMp(), nil, true, ""); err != nil { rs.unlock() } return @@ -675,13 +593,13 @@ func (rS *ResourceS) V1GetResourcesForEvent(ctx *context.Context, args *utils.CG } var usageID string - if usageID, err = GetStringOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageID, + if usageID, err = engine.GetStringOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageID, utils.OptsResourcesUsageID); err != nil { return } var ttl time.Duration - if ttl, err = GetDurationOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageTTL, + if ttl, err = engine.GetDurationOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageTTL, utils.OptsResourcesUsageTTL); err != nil { return } @@ -701,14 +619,14 @@ func (rS *ResourceS) V1GetResourcesForEvent(ctx *context.Context, args *utils.CG refID := guardian.Guardian.GuardIDs("", config.CgrConfig().GeneralCfg().LockingTimeout, cacheKey) // RPC caching needs to be atomic defer guardian.Guardian.UnguardIDs(refID) - if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has { + if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has { cachedResp := itm.(*utils.CachedRPCResponse) if cachedResp.Error == nil { *reply = *cachedResp.Result.(*Resources) } return cachedResp.Error } - defer Cache.Set(ctx, utils.CacheRPCResponses, cacheKey, + defer engine.Cache.Set(ctx, utils.CacheRPCResponses, cacheKey, &utils.CachedRPCResponse{Result: reply, Error: err}, nil, true, utils.NonTransactional) } @@ -733,19 +651,19 @@ func (rS *ResourceS) V1AuthorizeResources(ctx *context.Context, args *utils.CGRE } var usageID string - if usageID, err = GetStringOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageID, + if usageID, err = engine.GetStringOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageID, utils.OptsResourcesUsageID); err != nil { return } var units float64 - if units, err = GetFloat64Opts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.Units, + if units, err = engine.GetFloat64Opts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.Units, utils.OptsResourcesUnits); err != nil { return } var ttl time.Duration - if ttl, err = GetDurationOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageTTL, + if ttl, err = engine.GetDurationOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageTTL, utils.OptsResourcesUsageTTL); err != nil { return } @@ -766,14 +684,14 @@ func (rS *ResourceS) V1AuthorizeResources(ctx *context.Context, args *utils.CGRE refID := guardian.Guardian.GuardIDs("", config.CgrConfig().GeneralCfg().LockingTimeout, cacheKey) // RPC caching needs to be atomic defer guardian.Guardian.UnguardIDs(refID) - if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has { + if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has { cachedResp := itm.(*utils.CachedRPCResponse) if cachedResp.Error == nil { *reply = *cachedResp.Result.(*string) } return cachedResp.Error } - defer Cache.Set(ctx, utils.CacheRPCResponses, cacheKey, + defer engine.Cache.Set(ctx, utils.CacheRPCResponses, cacheKey, &utils.CachedRPCResponse{Result: reply, Error: err}, nil, true, utils.NonTransactional) } @@ -786,7 +704,7 @@ func (rS *ResourceS) V1AuthorizeResources(ctx *context.Context, args *utils.CGRE defer mtcRLs.unlock() var alcMessage string - if alcMessage, err = mtcRLs.allocateResource(&ResourceUsage{ + if alcMessage, err = mtcRLs.allocateResource(&utils.ResourceUsage{ Tenant: tnt, ID: usageID, Units: units}, true); err != nil { @@ -809,19 +727,19 @@ func (rS *ResourceS) V1AllocateResources(ctx *context.Context, args *utils.CGREv } var usageID string - if usageID, err = GetStringOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageID, + if usageID, err = engine.GetStringOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageID, utils.OptsResourcesUsageID); err != nil { return } var units float64 - if units, err = GetFloat64Opts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.Units, + if units, err = engine.GetFloat64Opts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.Units, utils.OptsResourcesUnits); err != nil { return } var ttl time.Duration - if ttl, err = GetDurationOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageTTL, + if ttl, err = engine.GetDurationOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageTTL, utils.OptsResourcesUsageTTL); err != nil { return } @@ -842,14 +760,14 @@ func (rS *ResourceS) V1AllocateResources(ctx *context.Context, args *utils.CGREv refID := guardian.Guardian.GuardIDs("", config.CgrConfig().GeneralCfg().LockingTimeout, cacheKey) // RPC caching needs to be atomic defer guardian.Guardian.UnguardIDs(refID) - if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has { + if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has { cachedResp := itm.(*utils.CachedRPCResponse) if cachedResp.Error == nil { *reply = *cachedResp.Result.(*string) } return cachedResp.Error } - defer Cache.Set(ctx, utils.CacheRPCResponses, cacheKey, + defer engine.Cache.Set(ctx, utils.CacheRPCResponses, cacheKey, &utils.CachedRPCResponse{Result: reply, Error: err}, nil, true, utils.NonTransactional) } @@ -863,7 +781,7 @@ func (rS *ResourceS) V1AllocateResources(ctx *context.Context, args *utils.CGREv defer mtcRLs.unlock() var alcMsg string - if alcMsg, err = mtcRLs.allocateResource(&ResourceUsage{Tenant: tnt, ID: usageID, + if alcMsg, err = mtcRLs.allocateResource(&utils.ResourceUsage{Tenant: tnt, ID: usageID, Units: units}, false); err != nil { return } @@ -889,13 +807,13 @@ func (rS *ResourceS) V1ReleaseResources(ctx *context.Context, args *utils.CGREve } var usageID string - if usageID, err = GetStringOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageID, + if usageID, err = engine.GetStringOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageID, utils.OptsResourcesUsageID); err != nil { return } var ttl time.Duration - if ttl, err = GetDurationOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageTTL, + if ttl, err = engine.GetDurationOpts(ctx, args.Tenant, args.AsDataProvider(), nil, rS.fltrS, rS.cfg.ResourceSCfg().Opts.UsageTTL, utils.OptsResourcesUsageTTL); err != nil { return } @@ -916,14 +834,14 @@ func (rS *ResourceS) V1ReleaseResources(ctx *context.Context, args *utils.CGREve refID := guardian.Guardian.GuardIDs("", config.CgrConfig().GeneralCfg().LockingTimeout, cacheKey) // RPC caching needs to be atomic defer guardian.Guardian.UnguardIDs(refID) - if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has { + if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has { cachedResp := itm.(*utils.CachedRPCResponse) if cachedResp.Error == nil { *reply = *cachedResp.Result.(*string) } return cachedResp.Error } - defer Cache.Set(ctx, utils.CacheRPCResponses, cacheKey, + defer engine.Cache.Set(ctx, utils.CacheRPCResponses, cacheKey, &utils.CachedRPCResponse{Result: reply, Error: err}, nil, true, utils.NonTransactional) } @@ -953,7 +871,7 @@ func (rS *ResourceS) V1ReleaseResources(ctx *context.Context, args *utils.CGREve } // V1GetResource returns a resource configuration -func (rS *ResourceS) V1GetResource(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *Resource) error { +func (rS *ResourceS) V1GetResource(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *utils.Resource) error { if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } @@ -965,7 +883,7 @@ func (rS *ResourceS) V1GetResource(ctx *context.Context, arg *utils.TenantIDWith // make sure resource is locked at process level lkID := guardian.Guardian.GuardIDs(utils.EmptyString, config.CgrConfig().GeneralCfg().LockingTimeout, - resourceLockKey(tnt, arg.ID)) + utils.ResourceLockKey(tnt, arg.ID)) defer guardian.Guardian.UnguardIDs(lkID) res, err := rS.dm.GetResource(ctx, tnt, arg.ID, true, true, utils.NonTransactional) @@ -976,12 +894,7 @@ func (rS *ResourceS) V1GetResource(ctx *context.Context, arg *utils.TenantIDWith return nil } -type ResourceWithConfig struct { - *Resource - Config *ResourceProfile -} - -func (rS *ResourceS) V1GetResourceWithConfig(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *ResourceWithConfig) (err error) { +func (rS *ResourceS) V1GetResourceWithConfig(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *utils.ResourceWithConfig) (err error) { if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } @@ -993,10 +906,10 @@ func (rS *ResourceS) V1GetResourceWithConfig(ctx *context.Context, arg *utils.Te // make sure resource is locked at process level lkID := guardian.Guardian.GuardIDs(utils.EmptyString, config.CgrConfig().GeneralCfg().LockingTimeout, - resourceLockKey(tnt, arg.ID)) + utils.ResourceLockKey(tnt, arg.ID)) defer guardian.Guardian.UnguardIDs(lkID) - var res *Resource + var res *utils.Resource res, err = rS.dm.GetResource(ctx, tnt, arg.ID, true, true, utils.NonTransactional) if err != nil { return @@ -1005,140 +918,19 @@ func (rS *ResourceS) V1GetResourceWithConfig(ctx *context.Context, arg *utils.Te // make sure resourceProfile is locked at process level lkPrflID := guardian.Guardian.GuardIDs(utils.EmptyString, config.CgrConfig().GeneralCfg().LockingTimeout, - resourceProfileLockKey(tnt, arg.ID)) + utils.ResourceProfileLockKey(tnt, arg.ID)) defer guardian.Guardian.UnguardIDs(lkPrflID) - if res.rPrf == nil { - var cfg *ResourceProfile - cfg, err = rS.dm.GetResourceProfile(ctx, tnt, arg.ID, true, true, utils.NonTransactional) - if err != nil { - return - } - res.rPrf = cfg - } - - *reply = ResourceWithConfig{ - Resource: res, - Config: res.rPrf, - } - - return -} - -func (rp *ResourceProfile) Set(path []string, val any, _ bool) (err error) { - if len(path) != 1 { - return utils.ErrWrongPath - } - switch path[0] { - default: - return utils.ErrWrongPath - case utils.Tenant: - rp.Tenant = utils.IfaceAsString(val) - case utils.ID: - rp.ID = utils.IfaceAsString(val) - case utils.FilterIDs: - var valA []string - valA, err = utils.IfaceAsStringSlice(val) - rp.FilterIDs = append(rp.FilterIDs, valA...) - case utils.UsageTTL: - rp.UsageTTL, err = utils.IfaceAsDuration(val) - case utils.Limit: - if val != utils.EmptyString { - rp.Limit, err = utils.IfaceAsFloat64(val) - } - case utils.AllocationMessage: - rp.AllocationMessage = utils.IfaceAsString(val) - case utils.Blocker: - rp.Blocker, err = utils.IfaceAsBool(val) - case utils.Stored: - rp.Stored, err = utils.IfaceAsBool(val) - case utils.Weights: - if val != utils.EmptyString { - rp.Weights, err = utils.NewDynamicWeightsFromString(utils.IfaceAsString(val), utils.InfieldSep, utils.ANDSep) - } - case utils.ThresholdIDs: - var valA []string - valA, err = utils.IfaceAsStringSlice(val) - rp.ThresholdIDs = append(rp.ThresholdIDs, valA...) - } - return -} - -func (rp *ResourceProfile) Merge(v2 any) { - vi := v2.(*ResourceProfile) - if len(vi.Tenant) != 0 { - rp.Tenant = vi.Tenant - } - if len(vi.ID) != 0 { - rp.ID = vi.ID - } - rp.FilterIDs = append(rp.FilterIDs, vi.FilterIDs...) - rp.ThresholdIDs = append(rp.ThresholdIDs, vi.ThresholdIDs...) - if len(vi.AllocationMessage) != 0 { - rp.AllocationMessage = vi.AllocationMessage - } - if vi.UsageTTL != 0 { - rp.UsageTTL = vi.UsageTTL - } - if vi.Limit != 0 { - rp.Limit = vi.Limit - } - if vi.Blocker { - rp.Blocker = vi.Blocker - } - if vi.Stored { - rp.Stored = vi.Stored - } - rp.Weights = append(rp.Weights, vi.Weights...) -} - -func (rp *ResourceProfile) String() string { return utils.ToJSON(rp) } -func (rp *ResourceProfile) FieldAsString(fldPath []string) (_ string, err error) { - var val any - if val, err = rp.FieldAsInterface(fldPath); err != nil { + var cfg *utils.ResourceProfile + cfg, err = rS.dm.GetResourceProfile(ctx, tnt, arg.ID, true, true, utils.NonTransactional) + if err != nil { return } - return utils.IfaceAsString(val), nil -} -func (rp *ResourceProfile) FieldAsInterface(fldPath []string) (_ any, err error) { - if len(fldPath) != 1 { - return nil, utils.ErrNotFound - } - switch fldPath[0] { - default: - fld, idx := utils.GetPathIndex(fldPath[0]) - if idx != nil { - switch fld { - case utils.ThresholdIDs: - if *idx < len(rp.ThresholdIDs) { - return rp.ThresholdIDs[*idx], nil - } - case utils.FilterIDs: - if *idx < len(rp.FilterIDs) { - return rp.FilterIDs[*idx], nil - } - } - } - return nil, utils.ErrNotFound - case utils.Tenant: - return rp.Tenant, nil - case utils.ID: - return rp.ID, nil - case utils.FilterIDs: - return rp.FilterIDs, nil - case utils.UsageTTL: - return rp.UsageTTL, nil - case utils.Limit: - return rp.Limit, nil - case utils.AllocationMessage: - return rp.AllocationMessage, nil - case utils.Blocker: - return rp.Blocker, nil - case utils.Stored: - return rp.Stored, nil - case utils.Weights: - return rp.Weights, nil - case utils.ThresholdIDs: - return rp.ThresholdIDs, nil + + *reply = utils.ResourceWithConfig{ + Resource: res, + Config: cfg, } + + return } diff --git a/apis/resources_it_test.go b/resources/resources_it_test.go similarity index 93% rename from apis/resources_it_test.go rename to resources/resources_it_test.go index 14f0725a2..fd318ba34 100644 --- a/apis/resources_it_test.go +++ b/resources/resources_it_test.go @@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ -package apis +package resources import ( "io" @@ -150,7 +150,7 @@ func testResourceSKillEngine(t *testing.T) { } func testResourceSGetResourceBeforeSet(t *testing.T) { // cache it with not found - var rplyRes *engine.Resource + var rplyRes *utils.Resource if err := rsRPC.Call(context.Background(), utils.ResourceSv1GetResource, &utils.TenantIDWithAPIOpts{ TenantID: &utils.TenantID{ @@ -162,7 +162,7 @@ func testResourceSGetResourceBeforeSet(t *testing.T) { // cache it with not foun } func testResourceSGetResourceProfileBeforeSet(t *testing.T) { // cache it with not found - var rplyRes *[]*engine.ResourceProfile + var rplyRes *[]*utils.ResourceProfile var args *utils.ArgsItemIDs if err := rsRPC.Call(context.Background(), utils.AdminSv1GetResourceProfiles, args, &rplyRes); err == nil || err.Error() != utils.ErrNotFound.Error() { @@ -171,8 +171,8 @@ func testResourceSGetResourceProfileBeforeSet(t *testing.T) { // cache it with n } func testResourceSSetResourceProfiles(t *testing.T) { - rsPrf1 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsPrf1 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -194,8 +194,8 @@ func testResourceSSetResourceProfiles(t *testing.T) { t.Error("Unexpected reply returned", reply) } - rsPrf2 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsPrf2 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup2", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -218,14 +218,14 @@ func testResourceSSetResourceProfiles(t *testing.T) { } func testResourceSGetResourceAfterSet(t *testing.T) { - var rplyRes engine.Resource - var rplyResPrf engine.ResourceProfile - expRes := engine.Resource{ + var rplyRes utils.Resource + var rplyResPrf utils.ResourceProfile + expRes := utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup1", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), } - expResPrf := engine.ResourceProfile{ + expResPrf := utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -260,12 +260,12 @@ func testResourceSGetResourceAfterSet(t *testing.T) { utils.ToJSON(expResPrf), utils.ToJSON(rplyResPrf)) } - expRes = engine.Resource{ + expRes = utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), } - expResPrf = engine.ResourceProfile{ + expResPrf = utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup2", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -302,14 +302,14 @@ func testResourceSGetResourceAfterSet(t *testing.T) { } func testResourceSGetResourceWithConfigAfterSet(t *testing.T) { - var rplyRes engine.ResourceWithConfig - expRes := engine.ResourceWithConfig{ - Resource: &engine.Resource{ + var rplyRes utils.ResourceWithConfig + expRes := utils.ResourceWithConfig{ + Resource: &utils.Resource{ Tenant: "cgrates.org", ID: "ResGroup2", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), }, - Config: &engine.ResourceProfile{ + Config: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup2", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -351,9 +351,9 @@ func testResourceSGetResourceProfileIDs(t *testing.T) { } func testResourceSGetResourceProfiles(t *testing.T) { - var rplyRes []*engine.ResourceProfile + var rplyRes []*utils.ResourceProfile var args *utils.ArgsItemIDs - exp := []*engine.ResourceProfile{ + exp := []*utils.ResourceProfile{ { Tenant: "cgrates.org", ID: "ResGroup1", @@ -413,19 +413,23 @@ func testResourceSGetResourcesForEvent(t *testing.T) { }, } - exp := engine.Resources{ + exp := Resources{ { - Tenant: "cgrates.org", - ID: "ResGroup1", - Usages: make(map[string]*engine.ResourceUsage), + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "ResGroup1", + Usages: make(map[string]*utils.ResourceUsage), + }, }, { - Tenant: "cgrates.org", - ID: "ResGroup2", - Usages: make(map[string]*engine.ResourceUsage), + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "ResGroup2", + Usages: make(map[string]*utils.ResourceUsage), + }, }, } - var reply engine.Resources + var reply Resources if err := rsRPC.Call(context.Background(), utils.ResourceSv1GetResourcesForEvent, args, &reply); err != nil { t.Error(err) @@ -546,7 +550,7 @@ func testResourceSRemoveResourceProfiles(t *testing.T) { } func testResourceSGetResourceProfilesAfterRemove(t *testing.T) { - var rplyResPrf engine.ResourceProfile + var rplyResPrf utils.ResourceProfile if err := rsRPC.Call(context.Background(), utils.AdminSv1GetResourceProfile, utils.TenantID{ Tenant: "cgrates.org", @@ -650,7 +654,7 @@ func testResourceSSetThresholdProfile(t *testing.T) { } func testResourceSSetResourceProfile(t *testing.T) { - rsPrf := &engine.ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES_1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -666,7 +670,7 @@ func testResourceSSetResourceProfile(t *testing.T) { t.Error("Unexpected reply returned", reply) } - var result *engine.ResourceProfile + var result *utils.ResourceProfile if err := rsRPC.Call(context.Background(), utils.AdminSv1GetResourceProfile, &utils.TenantID{Tenant: "cgrates.org", ID: rsPrf.ID}, &result); err != nil { t.Error(err) @@ -747,8 +751,8 @@ func testResourceSCheckThresholdAfterResourceRelease(t *testing.T) { } func testResourceSGetResourceProfilesWithPrefix(t *testing.T) { - rsPrf1 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsPrf1 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "PrefixResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -770,8 +774,8 @@ func testResourceSGetResourceProfilesWithPrefix(t *testing.T) { t.Error("Unexpected reply returned", reply) } - rsPrf2 := &engine.ResourceProfileWithAPIOpts{ - ResourceProfile: &engine.ResourceProfile{ + rsPrf2 := &utils.ResourceProfileWithAPIOpts{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup2", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -792,11 +796,11 @@ func testResourceSGetResourceProfilesWithPrefix(t *testing.T) { t.Error("Unexpected reply returned", reply) } - var rplyRes []*engine.ResourceProfile + var rplyRes []*utils.ResourceProfile args := &utils.ArgsItemIDs{ ItemsPrefix: "PrefixRes", } - exp := []*engine.ResourceProfile{ + exp := []*utils.ResourceProfile{ { Tenant: "cgrates.org", ID: "PrefixResGroup1", diff --git a/engine/z_resources_test.go b/resources/resources_test.go similarity index 59% rename from engine/z_resources_test.go rename to resources/resources_test.go index e5c93eb17..c7e581811 100644 --- a/engine/z_resources_test.go +++ b/resources/resources_test.go @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ -package engine +package resources import ( "bytes" @@ -29,177 +29,50 @@ import ( "github.com/cgrates/birpc" "github.com/cgrates/birpc/context" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/rpcclient" "github.com/cgrates/cgrates/utils" ) -func TestResourceProfileTenantID(t *testing.T) { - testStruct := ResourceProfile{ - Tenant: "test_tenant", - ID: "test_id", - } - result := testStruct.TenantID() - expected := utils.ConcatenatedKey(testStruct.Tenant, testStruct.ID) - if !reflect.DeepEqual(expected, result) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", expected, result) - } -} - -func TestResourceUsageTenantID(t *testing.T) { - testStruct := ResourceUsage{ - Tenant: "test_tenant", - ID: "test_id", - } - result := testStruct.TenantID() - expected := utils.ConcatenatedKey(testStruct.Tenant, testStruct.ID) - if !reflect.DeepEqual(expected, result) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", expected, result) - } -} - -func TestResourceUsageisActive(t *testing.T) { - testStruct := ResourceUsage{ - Tenant: "test_tenant", - ID: "test_id", - ExpiryTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC), - } - result := testStruct.isActive(time.Date(2014, 1, 13, 0, 0, 0, 0, time.UTC)) - if !reflect.DeepEqual(true, result) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", true, result) - } -} - -func TestResourceUsageisActiveFalse(t *testing.T) { - testStruct := ResourceUsage{ - Tenant: "test_tenant", - ID: "test_id", - ExpiryTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC), - } - result := testStruct.isActive(time.Date(2014, 1, 15, 0, 0, 0, 0, time.UTC)) - if !reflect.DeepEqual(false, result) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", false, result) - } -} - -func TestResourceUsageClone(t *testing.T) { - testStruct := &ResourceUsage{ - Tenant: "test_tenant", - ID: "test_id", - ExpiryTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC), - } - result := testStruct.Clone() - if !reflect.DeepEqual(testStruct, result) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct, result) - } - testStruct.Tenant = "test_tenant2" - testStruct.ID = "test_id2" - testStruct.ExpiryTime = time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC) - if reflect.DeepEqual(testStruct.Tenant, result.Tenant) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct.Tenant, result.Tenant) - } - if reflect.DeepEqual(testStruct.ID, result.ID) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct.ID, result.ID) - } - if reflect.DeepEqual(testStruct.ExpiryTime, result.ExpiryTime) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct.ExpiryTime, result.ExpiryTime) - } -} - -func TestResourceTenantID(t *testing.T) { - testStruct := Resource{ - Tenant: "test_tenant", - } - result := testStruct.TenantID() - if reflect.DeepEqual(testStruct.Tenant, result) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct.Tenant, result) - } -} - -func TestResourceTotalUsage1(t *testing.T) { - testStruct := Resource{ - Tenant: "test_tenant", - ID: "test_id", - Usages: map[string]*ResourceUsage{ - "0": { - Tenant: "test_tenant2", - ID: "test_id2", - ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 1, - }, - "1": { - Tenant: "test_tenant3", - ID: "test_id3", - ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 2, - }, - }, - } - result := testStruct.TotalUsage() - if reflect.DeepEqual(3, result) { - t.Errorf("\nExpecting <3>,\n Received <%+v>", result) - } -} - -func TestResourceTotalUsage2(t *testing.T) { - testStruct := Resource{ - Tenant: "test_tenant", - ID: "test_id", - Usages: map[string]*ResourceUsage{ - "0": { - Tenant: "test_tenant2", - ID: "test_id2", - ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 1, - }, - "1": { - Tenant: "test_tenant3", - ID: "test_id3", - ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 2, - }, - }, - } - result := testStruct.TotalUsage() - if reflect.DeepEqual(3, result) { - t.Errorf("\nExpecting <3>,\n Received <%+v>", result) - } -} - func TestResourcesRecordUsage(t *testing.T) { - testStruct := &Resource{ - Tenant: "test_tenant", - ID: "test_id", - Usages: map[string]*ResourceUsage{ - "test_id2": { - Tenant: "test_tenant2", - ID: "test_id2", - ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 1, + testStruct := &resource{ + Resource: &utils.Resource{ + Tenant: "test_tenant", + ID: "test_id", + Usages: map[string]*utils.ResourceUsage{ + "test_id2": { + Tenant: "test_tenant2", + ID: "test_id2", + ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 1, + }, }, }, } - recordStruct := &ResourceUsage{ + recordStruct := &utils.ResourceUsage{ Tenant: "test_tenant3", ID: "test_id3", ExpiryTime: time.Date(2016, 1, 14, 0, 0, 0, 0, time.UTC), Units: 1, } - expStruct := Resource{ - Tenant: "test_tenant", - ID: "test_id", - Usages: map[string]*ResourceUsage{ - "test_id2": { - Tenant: "test_tenant2", - ID: "test_id2", - ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 1, - }, - "test_id3": { - Tenant: "test_tenant3", - ID: "test_id3", - ExpiryTime: time.Date(2016, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 1, + expStruct := resource{ + Resource: &utils.Resource{ + Tenant: "test_tenant", + ID: "test_id", + Usages: map[string]*utils.ResourceUsage{ + "test_id2": { + Tenant: "test_tenant2", + ID: "test_id2", + ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 1, + }, + "test_id3": { + Tenant: "test_tenant3", + ID: "test_id3", + ExpiryTime: time.Date(2016, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 1, + }, }, }, } @@ -213,33 +86,37 @@ func TestResourcesRecordUsage(t *testing.T) { } func TestResourcesClearUsage(t *testing.T) { - testStruct := &Resource{ - Tenant: "test_tenant", - ID: "test_id", - Usages: map[string]*ResourceUsage{ - "test_id2": { - Tenant: "test_tenant2", - ID: "test_id2", - ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 1, - }, - "test_id3": { - Tenant: "test_tenant3", - ID: "test_id3", - ExpiryTime: time.Date(2016, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 1, + testStruct := &resource{ + Resource: &utils.Resource{ + Tenant: "test_tenant", + ID: "test_id", + Usages: map[string]*utils.ResourceUsage{ + "test_id2": { + Tenant: "test_tenant2", + ID: "test_id2", + ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 1, + }, + "test_id3": { + Tenant: "test_tenant3", + ID: "test_id3", + ExpiryTime: time.Date(2016, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 1, + }, }, }, } - expStruct := Resource{ - Tenant: "test_tenant", - ID: "test_id", - Usages: map[string]*ResourceUsage{ - "test_id2": { - Tenant: "test_tenant2", - ID: "test_id2", - ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), - Units: 1, + expStruct := resource{ + Resource: &utils.Resource{ + Tenant: "test_tenant", + ID: "test_id", + Usages: map[string]*utils.ResourceUsage{ + "test_id2": { + Tenant: "test_tenant2", + ID: "test_id2", + ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 1, + }, }, }, } @@ -253,44 +130,48 @@ func TestResourcesClearUsage(t *testing.T) { } func TestResourceRecordUsage(t *testing.T) { - var r1 *Resource - var ru1 *ResourceUsage - var ru2 *ResourceUsage - ru1 = &ResourceUsage{ + var r1 *resource + var ru1 *utils.ResourceUsage + var ru2 *utils.ResourceUsage + ru1 = &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU1", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 1, } - ru2 = &ResourceUsage{ + ru2 = &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU2", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 2, } - r1 = &Resource{ - Tenant: "cgrates.org", - ID: "RL1", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RL1", - FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 100, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, + r1 = &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL1", + Usages: map[string]*utils.ResourceUsage{ + ru1.ID: ru1, + }, + TTLIdx: []string{ru1.ID}, + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RL1", + FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 100, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, - AllocationMessage: "ALLOC", + UsageTTL: time.Millisecond, + AllocationMessage: "ALLOC", + }, }, - Usages: map[string]*ResourceUsage{ - ru1.ID: ru1, - }, - TTLIdx: []string{ru1.ID}, tUsage: utils.Float64Pointer(2), } @@ -300,7 +181,7 @@ func TestResourceRecordUsage(t *testing.T) { if err := r1.recordUsage(ru1); err == nil { t.Error("duplicate ResourceUsage id should not be allowed") } - if _, found := r1.Usages[ru2.ID]; !found { + if _, found := r1.Resource.Usages[ru2.ID]; !found { t.Error("ResourceUsage was not recorded") } if *r1.tUsage != 4 { @@ -310,44 +191,48 @@ func TestResourceRecordUsage(t *testing.T) { } func TestResourceRemoveExpiredUnits(t *testing.T) { - var r1 *Resource - var ru1 *ResourceUsage - var ru2 *ResourceUsage - ru1 = &ResourceUsage{ + var r1 *resource + var ru1 *utils.ResourceUsage + var ru2 *utils.ResourceUsage + ru1 = &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU1", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 1, } - ru2 = &ResourceUsage{ + ru2 = &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU2", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 2, } - r1 = &Resource{ - Tenant: "cgrates.org", - ID: "RL1", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RL1", - FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 100, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, + r1 = &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL1", + Usages: map[string]*utils.ResourceUsage{ + ru1.ID: ru1, + }, + TTLIdx: []string{ru1.ID}, + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RL1", + FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 100, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, - AllocationMessage: "ALLOC", + UsageTTL: time.Millisecond, + AllocationMessage: "ALLOC", + }, }, - Usages: map[string]*ResourceUsage{ - ru1.ID: ru1, - }, - TTLIdx: []string{ru1.ID}, tUsage: utils.Float64Pointer(2), } @@ -357,66 +242,70 @@ func TestResourceRemoveExpiredUnits(t *testing.T) { if err := r1.recordUsage(ru1); err == nil { t.Error("duplicate ResourceUsage id should not be allowed") } - if _, found := r1.Usages[ru2.ID]; !found { + if _, found := r1.Resource.Usages[ru2.ID]; !found { t.Error("ResourceUsage was not recorded") } if *r1.tUsage != 4 { t.Errorf("expecting: %+v, received: %+v", 4, r1.tUsage) } } - r1.Usages = map[string]*ResourceUsage{ + r1.Resource.Usages = map[string]*utils.ResourceUsage{ ru1.ID: ru1, } *r1.tUsage = 2 r1.removeExpiredUnits() - if len(r1.Usages) != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, len(r1.Usages)) + if len(r1.Resource.Usages) != 0 { + t.Errorf("Expecting: %+v, received: %+v", 0, len(r1.Resource.Usages)) } - if len(r1.TTLIdx) != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, len(r1.TTLIdx)) + if len(r1.Resource.TTLIdx) != 0 { + t.Errorf("Expecting: %+v, received: %+v", 0, len(r1.Resource.TTLIdx)) } if r1.tUsage != nil && *r1.tUsage != 0 { t.Errorf("Expecting: %+v, received: %+v", 0, r1.tUsage) } } func TestResourceUsedUnits(t *testing.T) { - ru1 := &ResourceUsage{ + ru1 := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU1", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 1, } - ru2 := &ResourceUsage{ + ru2 := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU2", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 2, } - r1 := &Resource{ - Tenant: "cgrates.org", - ID: "RL1", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RL1", - FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 100, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, + r1 := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL1", + Usages: map[string]*utils.ResourceUsage{ + ru1.ID: ru1, + }, + TTLIdx: []string{ru1.ID}, + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RL1", + FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 100, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, - AllocationMessage: "ALLOC", + UsageTTL: time.Millisecond, + AllocationMessage: "ALLOC", + }, }, - Usages: map[string]*ResourceUsage{ - ru1.ID: ru1, - }, - TTLIdx: []string{ru1.ID}, tUsage: utils.Float64Pointer(2), } @@ -426,58 +315,62 @@ func TestResourceUsedUnits(t *testing.T) { if err := r1.recordUsage(ru1); err == nil { t.Error("duplicate ResourceUsage id should not be allowed") } - if _, found := r1.Usages[ru2.ID]; !found { + if _, found := r1.Resource.Usages[ru2.ID]; !found { t.Error("ResourceUsage was not recorded") } if *r1.tUsage != 4 { t.Errorf("expecting: %+v, received: %+v", 4, r1.tUsage) } } - r1.Usages = map[string]*ResourceUsage{ + r1.Resource.Usages = map[string]*utils.ResourceUsage{ ru1.ID: ru1, } r1.tUsage = nil - if usedUnits := r1.TotalUsage(); usedUnits != 1 { + if usedUnits := r1.Resource.TotalUsage(); usedUnits != 1 { t.Errorf("Expecting: %+v, received: %+v", 1, usedUnits) } } func TestResourceClearUsage(t *testing.T) { - ru1 := &ResourceUsage{ + ru1 := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU1", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 1, } - ru2 := &ResourceUsage{ + ru2 := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU2", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 2, } - r1 := &Resource{ - Tenant: "cgrates.org", - ID: "RL1", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RL1", - FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 100, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, + r1 := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL1", + Usages: map[string]*utils.ResourceUsage{ + ru1.ID: ru1, + }, + TTLIdx: []string{ru1.ID}, + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RL1", + FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 100, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, - AllocationMessage: "ALLOC", + UsageTTL: time.Millisecond, + AllocationMessage: "ALLOC", + }, }, - Usages: map[string]*ResourceUsage{ - ru1.ID: ru1, - }, - TTLIdx: []string{ru1.ID}, tUsage: utils.Float64Pointer(2), } @@ -487,89 +380,97 @@ func TestResourceClearUsage(t *testing.T) { if err := r1.recordUsage(ru1); err == nil { t.Error("duplicate ResourceUsage id should not be allowed") } - if _, found := r1.Usages[ru2.ID]; !found { + if _, found := r1.Resource.Usages[ru2.ID]; !found { t.Error("ResourceUsage was not recorded") } if *r1.tUsage != 4 { t.Errorf("expecting: %+v, received: %+v", 4, r1.tUsage) } } - r2 := &Resource{ - Tenant: "cgrates.org", - ID: "RL2", - rPrf: &ResourceProfile{ - ID: "RL2", - FilterIDs: []string{"FLTR_RES_RL2", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 50, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, + r2 := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL2", + // AllocationMessage: "ALLOC2", + Usages: map[string]*utils.ResourceUsage{ + ru2.ID: ru2, + }, }, - // AllocationMessage: "ALLOC2", - Usages: map[string]*ResourceUsage{ - ru2.ID: ru2, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + ID: "RL2", + FilterIDs: []string{"FLTR_RES_RL2", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 50, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, + UsageTTL: time.Millisecond, + }, }, tUsage: utils.Float64Pointer(2), } - r1.Usages = map[string]*ResourceUsage{ + r1.Resource.Usages = map[string]*utils.ResourceUsage{ ru1.ID: ru1, } r1.tUsage = nil r1.clearUsage(ru1.ID) - if len(r1.Usages) != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, len(r1.Usages)) + if len(r1.Resource.Usages) != 0 { + t.Errorf("Expecting: %+v, received: %+v", 0, len(r1.Resource.Usages)) } - if r1.TotalUsage() != 0 { + if r1.Resource.TotalUsage() != 0 { t.Errorf("Expecting: %+v, received: %+v", 0, r1.tUsage) } if err := r2.clearUsage(ru2.ID); err != nil { t.Error(err) - } else if len(r2.Usages) != 0 { - t.Errorf("Unexpected usages %+v", r2.Usages) + } else if len(r2.Resource.Usages) != 0 { + t.Errorf("Unexpected usages %+v", r2.Resource.Usages) } else if *r2.tUsage != 0 { t.Errorf("Unexpected tUsage %+v", r2.tUsage) } } func TestResourceRecordUsages(t *testing.T) { - ru1 := &ResourceUsage{ + ru1 := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU1", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 1, } - ru2 := &ResourceUsage{ + ru2 := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU2", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 2, } - r1 := &Resource{ - Tenant: "cgrates.org", - ID: "RL1", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RL1", - FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 100, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, + r1 := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL1", + Usages: map[string]*utils.ResourceUsage{ + ru1.ID: ru1, + }, + TTLIdx: []string{ru1.ID}, + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RL1", + FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 100, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, - AllocationMessage: "ALLOC", + UsageTTL: time.Millisecond, + AllocationMessage: "ALLOC", + }, }, - Usages: map[string]*ResourceUsage{ - ru1.ID: ru1, - }, - TTLIdx: []string{ru1.ID}, tUsage: utils.Float64Pointer(2), } @@ -579,39 +480,43 @@ func TestResourceRecordUsages(t *testing.T) { if err := r1.recordUsage(ru1); err == nil { t.Error("duplicate ResourceUsage id should not be allowed") } - if _, found := r1.Usages[ru2.ID]; !found { + if _, found := r1.Resource.Usages[ru2.ID]; !found { t.Error("ResourceUsage was not recorded") } if *r1.tUsage != 4 { t.Errorf("expecting: %+v, received: %+v", 4, r1.tUsage) } } - r2 := &Resource{ - Tenant: "cgrates.org", - ID: "RL2", - rPrf: &ResourceProfile{ - ID: "RL2", - FilterIDs: []string{"FLTR_RES_RL2", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 50, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, + r2 := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL2", + // AllocationMessage: "ALLOC2", + Usages: map[string]*utils.ResourceUsage{ + ru2.ID: ru2, + }, }, - // AllocationMessage: "ALLOC2", - Usages: map[string]*ResourceUsage{ - ru2.ID: ru2, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + ID: "RL2", + FilterIDs: []string{"FLTR_RES_RL2", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 50, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, + UsageTTL: time.Millisecond, + }, }, tUsage: utils.Float64Pointer(2), } rs := Resources{r2, r1} - r1.Usages = map[string]*ResourceUsage{ + r1.Resource.Usages = map[string]*utils.ResourceUsage{ ru1.ID: ru1, } - r1.Usages = map[string]*ResourceUsage{ + r1.Resource.Usages = map[string]*utils.ResourceUsage{ ru1.ID: ru1, } r1.tUsage = nil @@ -620,41 +525,45 @@ func TestResourceRecordUsages(t *testing.T) { } } func TestResourceAllocateResource(t *testing.T) { - ru1 := &ResourceUsage{ + ru1 := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU1", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 1, } - ru2 := &ResourceUsage{ + ru2 := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU2", ExpiryTime: time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC), Units: 2, } - r1 := &Resource{ - Tenant: "cgrates.org", - ID: "RL1", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RL1", - FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 100, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, + r1 := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL1", + Usages: map[string]*utils.ResourceUsage{ + ru1.ID: ru1, + }, + TTLIdx: []string{ru1.ID}, + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RL1", + FilterIDs: []string{"FLTR_RES_RL1", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 100, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, - AllocationMessage: "ALLOC", + UsageTTL: time.Millisecond, + AllocationMessage: "ALLOC", + }, }, - Usages: map[string]*ResourceUsage{ - ru1.ID: ru1, - }, - TTLIdx: []string{ru1.ID}, tUsage: utils.Float64Pointer(2), } @@ -664,39 +573,43 @@ func TestResourceAllocateResource(t *testing.T) { if err := r1.recordUsage(ru1); err == nil { t.Error("duplicate ResourceUsage id should not be allowed") } - if _, found := r1.Usages[ru2.ID]; !found { + if _, found := r1.Resource.Usages[ru2.ID]; !found { t.Error("ResourceUsage was not recorded") } if *r1.tUsage != 4 { t.Errorf("expecting: %+v, received: %+v", 4, r1.tUsage) } } - r2 := &Resource{ - Tenant: "cgrates.org", - ID: "RL2", - rPrf: &ResourceProfile{ - ID: "RL2", - FilterIDs: []string{"FLTR_RES_RL2", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - Weights: utils.DynamicWeights{ - { - Weight: 50, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, + r2 := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RL2", + // AllocationMessage: "ALLOC2", + Usages: map[string]*utils.ResourceUsage{ + ru2.ID: ru2, + }, }, - // AllocationMessage: "ALLOC2", - Usages: map[string]*ResourceUsage{ - ru2.ID: ru2, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + ID: "RL2", + FilterIDs: []string{"FLTR_RES_RL2", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, + Weights: utils.DynamicWeights{ + { + Weight: 50, + }}, + Limit: 2, + ThresholdIDs: []string{"TEST_ACTIONS"}, + UsageTTL: time.Millisecond, + }, }, tUsage: utils.Float64Pointer(2), } rs := Resources{r1, r2} - r1.Usages = map[string]*ResourceUsage{ + r1.Resource.Usages = map[string]*utils.ResourceUsage{ ru1.ID: ru1, } - r1.Usages = map[string]*ResourceUsage{ + r1.Resource.Usages = map[string]*utils.ResourceUsage{ ru1.ID: ru1, } r1.tUsage = nil @@ -717,8 +630,8 @@ func TestResourceAllocateResource(t *testing.T) { if _, err := rs.allocateResource(ru2, false); err != utils.ErrResourceUnavailable { t.Error("Did not receive " + utils.ErrResourceUnavailable.Error() + " error") } - rs[0].rPrf.Limit = 1 - rs[1].rPrf.Limit = 4 + rs[0].rPrf.ResourceProfile.Limit = 1 + rs[1].rPrf.ResourceProfile.Limit = 4 if alcMessage, err := rs.allocateResource(ru1, false); err != nil { t.Error(err.Error()) } else { @@ -743,23 +656,10 @@ func TestResourceAllocateResource(t *testing.T) { // TestRSCacheSetGet assurace the presence of private params in cached resource func TestRSCacheSetGet(t *testing.T) { - r := &Resource{ + r := &utils.Resource{ Tenant: "cgrates.org", ID: "RL", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RL", - FilterIDs: []string{"FLTR_RES_RL", "*ai:~*req.AnswerTime:2014-07-03T13:43:00Z|2014-07-03T13:44:00Z"}, - AllocationMessage: "ALLOC_RL", - Weights: utils.DynamicWeights{ - { - Weight: 50, - }}, - Limit: 2, - ThresholdIDs: []string{"TEST_ACTIONS"}, - UsageTTL: time.Millisecond, - }, - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU2": { Tenant: "cgrates.org", ID: "RU2", @@ -767,30 +667,29 @@ func TestRSCacheSetGet(t *testing.T) { Units: 2, }, }, - tUsage: utils.Float64Pointer(2), - dirty: utils.BoolPointer(true), } - if err := Cache.Set(context.TODO(), utils.CacheResources, r.TenantID(), r, nil, true, ""); err != nil { + if err := engine.Cache.Set(context.TODO(), utils.CacheResources, r.TenantID(), r, nil, true, ""); err != nil { t.Errorf("Expecting: nil, received: %s", err) } - if x, ok := Cache.Get(utils.CacheResources, r.TenantID()); !ok { + if x, ok := engine.Cache.Get(utils.CacheResources, r.TenantID()); !ok { t.Error("not in cache") } else if x == nil { t.Error("nil resource") - } else if !reflect.DeepEqual(r, x.(*Resource)) { + } else if !reflect.DeepEqual(r, x.(*utils.Resource)) { t.Errorf("Expecting: %+v, received: %+v", r, x) } } func TestResourceV1AuthorizeResourceMissingStruct(t *testing.T) { - var dmRES *DataManager + var dmRES *engine.DataManager cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES = NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES = engine.NewDataManager(data, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dmRES) resService := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) + fltrs, nil) var reply *string argsMissingTenant := &utils.CGREvent{ ID: "id1", @@ -817,17 +716,17 @@ func TestResourceV1AuthorizeResourceMissingStruct(t *testing.T) { } func TestResourceAddResourceProfile(t *testing.T) { - var dmRES *DataManager + var dmRES *engine.DataManager cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES = NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES = engine.NewDataManager(data, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil - fltrRes1 := &Filter{ + fltrRes1 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_1", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -851,10 +750,10 @@ func TestResourceAddResourceProfile(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes1, true) - fltrRes2 := &Filter{ + fltrRes2 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_2", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -878,10 +777,10 @@ func TestResourceAddResourceProfile(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes2, true) - fltrRes3 := &Filter{ + fltrRes3 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_3", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaPrefix, Element: "~*req.Resources", @@ -890,7 +789,7 @@ func TestResourceAddResourceProfile(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes3, true) - resprf := []*ResourceProfile{ + resprf := []*utils.ResourceProfile{ { Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "ResourceProfile1", @@ -931,27 +830,24 @@ func TestResourceAddResourceProfile(t *testing.T) { ThresholdIDs: []string{""}, }, } - resourceTest := Resources{ + resourceTest := []*utils.Resource{ { Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "ResourceProfile1", - Usages: map[string]*ResourceUsage{}, + Usages: map[string]*utils.ResourceUsage{}, TTLIdx: []string{}, - rPrf: resprf[0], }, { Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "ResourceProfile2", - Usages: map[string]*ResourceUsage{}, + Usages: map[string]*utils.ResourceUsage{}, TTLIdx: []string{}, - rPrf: resprf[1], }, { Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "ResourceProfile3", - Usages: map[string]*ResourceUsage{}, + Usages: map[string]*utils.ResourceUsage{}, TTLIdx: []string{}, - rPrf: resprf[2], }, } for _, resProfile := range resprf { @@ -972,19 +868,20 @@ func TestResourceAddResourceProfile(t *testing.T) { } func TestResourceMatchingResourcesForEvent(t *testing.T) { - var dmRES *DataManager + var dmRES *engine.DataManager cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES = NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES = engine.NewDataManager(data, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dmRES) resService := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) - fltrRes1 := &Filter{ + fltrs, nil) + fltrRes1 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_1", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1008,10 +905,10 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes1, true) - fltrRes2 := &Filter{ + fltrRes2 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_2", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1035,10 +932,10 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes2, true) - fltrRes3 := &Filter{ + fltrRes3 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_3", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaPrefix, Element: "~*req.Resources", @@ -1047,68 +944,80 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes3, true) - resprf := []*ResourceProfile{ + resprf := []*resourceProfile{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - FilterIDs: []string{"FLTR_RES_1", "*ai:*now:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + FilterIDs: []string{"FLTR_RES_1", "*ai:*now:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", // identifier of this resource - FilterIDs: []string{"FLTR_RES_2", "*ai:*now:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", // identifier of this resource + FilterIDs: []string{"FLTR_RES_2", "*ai:*now:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - FilterIDs: []string{"FLTR_RES_3", "*ai:*now:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + FilterIDs: []string{"FLTR_RES_3", "*ai:*now:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, } resourceTest := Resources{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[0], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[0], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[1], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[1], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[2], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[2], }, } resEvs := []*utils.CGREvent{ @@ -1148,10 +1057,10 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { } timeDurationExample := 10 * time.Second for _, resProfile := range resprf { - dmRES.SetResourceProfile(context.TODO(), resProfile, true) + dmRES.SetResourceProfile(context.TODO(), resProfile.ResourceProfile, true) } for _, res := range resourceTest { - dmRES.SetResource(context.TODO(), res) + dmRES.SetResource(context.TODO(), res.Resource) } mres, err := resService.matchingResourcesForEvent(context.TODO(), resEvs[0].Tenant, resEvs[0], "TestResourceMatchingResourcesForEvent1", &timeDurationExample) @@ -1159,10 +1068,10 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[0].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[0].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].rPrf, mres[0].rPrf) } @@ -1173,10 +1082,10 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[1].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[1].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[1].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[1].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[1].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].rPrf, mres[0].rPrf) } @@ -1187,10 +1096,10 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[2].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[2].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[2].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[2].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[2].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].rPrf, mres[0].rPrf) } @@ -1198,68 +1107,80 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { // UsageTTL 0 in ResourceProfile and give 10s duration func TestResourceUsageTTLCase1(t *testing.T) { - resprf := []*ResourceProfile{ + resprf := []*resourceProfile{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", // identifier of this resource - FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", // identifier of this resource + FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, } resourceTest := Resources{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[0], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[0], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[1], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[1], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[2], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[2], }, } resEvs := []*utils.CGREvent{ @@ -1300,20 +1221,21 @@ func TestResourceUsageTTLCase1(t *testing.T) { timeDurationExample := 10 * time.Second - var dmRES *DataManager + var dmRES *engine.DataManager cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES = NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES = engine.NewDataManager(data, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil - Cache.Clear(nil) + engine.Cache.Clear(nil) + fltrs := engine.NewFilterS(cfg, nil, dmRES) resService := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) - fltrRes1 := &Filter{ + fltrs, nil) + fltrRes1 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_1", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1337,10 +1259,10 @@ func TestResourceUsageTTLCase1(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes1, true) - fltrRes2 := &Filter{ + fltrRes2 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_2", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1364,10 +1286,10 @@ func TestResourceUsageTTLCase1(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes2, true) - fltrRes3 := &Filter{ + fltrRes3 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_3", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaPrefix, Element: "~*req.Resources", @@ -1376,13 +1298,13 @@ func TestResourceUsageTTLCase1(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes3, true) - resprf[0].UsageTTL = 0 + resprf[0].ResourceProfile.UsageTTL = 0 resourceTest[0].rPrf = resprf[0] resourceTest[0].ttl = &timeDurationExample - if err := dmRES.SetResourceProfile(context.TODO(), resprf[0], true); err != nil { + if err := dmRES.SetResourceProfile(context.TODO(), resprf[0].ResourceProfile, true); err != nil { t.Error(err) } - if err := dmRES.SetResource(context.TODO(), resourceTest[0]); err != nil { + if err := dmRES.SetResource(context.TODO(), resourceTest[0].Resource); err != nil { t.Error(err) } mres, err := resService.matchingResourcesForEvent(context.TODO(), resEvs[0].Tenant, resEvs[0], @@ -1391,10 +1313,10 @@ func TestResourceUsageTTLCase1(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[0].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[0].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].rPrf, mres[0].rPrf) } else if !reflect.DeepEqual(resourceTest[0].ttl, mres[0].ttl) { @@ -1404,68 +1326,80 @@ func TestResourceUsageTTLCase1(t *testing.T) { // UsageTTL 5s in ResourceProfile and give nil duration func TestResourceUsageTTLCase2(t *testing.T) { - resprf := []*ResourceProfile{ + resprf := []*resourceProfile{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", // identifier of this resource - FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", // identifier of this resource + FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, } resourceTest := Resources{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[0], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[0], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[1], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[1], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[2], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[2], }, } resEvs := []*utils.CGREvent{ @@ -1504,19 +1438,20 @@ func TestResourceUsageTTLCase2(t *testing.T) { }, } - var dmRES *DataManager + var dmRES *engine.DataManager cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES = NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES = engine.NewDataManager(data, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dmRES) resService := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) - fltrRes1 := &Filter{ + fltrs, nil) + fltrRes1 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_1", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1540,10 +1475,10 @@ func TestResourceUsageTTLCase2(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes1, true) - fltrRes2 := &Filter{ + fltrRes2 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_2", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1567,10 +1502,10 @@ func TestResourceUsageTTLCase2(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes2, true) - fltrRes3 := &Filter{ + fltrRes3 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_3", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaPrefix, Element: "~*req.Resources", @@ -1579,13 +1514,13 @@ func TestResourceUsageTTLCase2(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes3, true) - resprf[0].UsageTTL = 0 + resprf[0].ResourceProfile.UsageTTL = 0 resourceTest[0].rPrf = resprf[0] - resourceTest[0].ttl = &resprf[0].UsageTTL - if err := dmRES.SetResourceProfile(context.TODO(), resprf[0], true); err != nil { + resourceTest[0].ttl = &resprf[0].ResourceProfile.UsageTTL + if err := dmRES.SetResourceProfile(context.TODO(), resprf[0].ResourceProfile, true); err != nil { t.Error(err) } - if err := dmRES.SetResource(context.TODO(), resourceTest[0]); err != nil { + if err := dmRES.SetResource(context.TODO(), resourceTest[0].Resource); err != nil { t.Error(err) } mres, err := resService.matchingResourcesForEvent(context.TODO(), resEvs[0].Tenant, resEvs[0], @@ -1594,10 +1529,10 @@ func TestResourceUsageTTLCase2(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[0].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[0].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].rPrf, mres[0].rPrf) } else if !reflect.DeepEqual(resourceTest[0].ttl, mres[0].ttl) { @@ -1607,68 +1542,80 @@ func TestResourceUsageTTLCase2(t *testing.T) { // UsageTTL 5s in ResourceProfile and give 0 duration func TestResourceUsageTTLCase3(t *testing.T) { - resprf := []*ResourceProfile{ + resprf := []*resourceProfile{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", // identifier of this resource - FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", // identifier of this resource + FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, } resourceTest := Resources{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[0], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[0], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[1], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[1], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[2], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[2], }, } resEvs := []*utils.CGREvent{ @@ -1707,20 +1654,21 @@ func TestResourceUsageTTLCase3(t *testing.T) { }, } - var dmRES *DataManager + var dmRES *engine.DataManager cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES = NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES = engine.NewDataManager(data, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil - Cache.Clear(nil) + engine.Cache.Clear(nil) + fltrs := engine.NewFilterS(cfg, nil, dmRES) resService := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) - fltrRes1 := &Filter{ + fltrs, nil) + fltrRes1 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_1", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1744,10 +1692,10 @@ func TestResourceUsageTTLCase3(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes1, true) - fltrRes2 := &Filter{ + fltrRes2 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_2", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1771,10 +1719,10 @@ func TestResourceUsageTTLCase3(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes2, true) - fltrRes3 := &Filter{ + fltrRes3 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_3", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaPrefix, Element: "~*req.Resources", @@ -1783,13 +1731,13 @@ func TestResourceUsageTTLCase3(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes3, true) - resprf[0].UsageTTL = 0 + resprf[0].ResourceProfile.UsageTTL = 0 resourceTest[0].rPrf = resprf[0] resourceTest[0].ttl = nil - if err := dmRES.SetResourceProfile(context.TODO(), resprf[0], true); err != nil { + if err := dmRES.SetResourceProfile(context.TODO(), resprf[0].ResourceProfile, true); err != nil { t.Error(err) } - if err := dmRES.SetResource(context.TODO(), resourceTest[0]); err != nil { + if err := dmRES.SetResource(context.TODO(), resourceTest[0].Resource); err != nil { t.Error(err) } mres, err := resService.matchingResourcesForEvent(context.TODO(), resEvs[0].Tenant, resEvs[0], @@ -1798,10 +1746,10 @@ func TestResourceUsageTTLCase3(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[0].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[0].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].rPrf, mres[0].rPrf) } else if !reflect.DeepEqual(resourceTest[0].ttl, mres[0].ttl) { @@ -1811,68 +1759,80 @@ func TestResourceUsageTTLCase3(t *testing.T) { // UsageTTL 5s in ResourceProfile and give 10s duration func TestResourceUsageTTLCase4(t *testing.T) { - resprf := []*ResourceProfile{ + resprf := []*resourceProfile{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", // identifier of this resource - FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", // identifier of this resource + FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, } resourceTest := Resources{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[0], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[0], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[1], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[1], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[2], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[2], }, } resEvs := []*utils.CGREvent{ @@ -1911,20 +1871,21 @@ func TestResourceUsageTTLCase4(t *testing.T) { }, } - var dmRES *DataManager + var dmRES *engine.DataManager cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES = NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES = engine.NewDataManager(data, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil - Cache.Clear(nil) + engine.Cache.Clear(nil) + fltrs := engine.NewFilterS(cfg, nil, dmRES) resService := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) - fltrRes1 := &Filter{ + fltrs, nil) + fltrRes1 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_1", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1948,10 +1909,10 @@ func TestResourceUsageTTLCase4(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes1, true) - fltrRes2 := &Filter{ + fltrRes2 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_2", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -1975,10 +1936,10 @@ func TestResourceUsageTTLCase4(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes2, true) - fltrRes3 := &Filter{ + fltrRes3 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_3", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaPrefix, Element: "~*req.Resources", @@ -1988,13 +1949,13 @@ func TestResourceUsageTTLCase4(t *testing.T) { } timeDurationExample := 10 * time.Second dmRES.SetFilter(context.Background(), fltrRes3, true) - resprf[0].UsageTTL = 5 + resprf[0].ResourceProfile.UsageTTL = 5 resourceTest[0].rPrf = resprf[0] resourceTest[0].ttl = &timeDurationExample - if err := dmRES.SetResourceProfile(context.TODO(), resprf[0], true); err != nil { + if err := dmRES.SetResourceProfile(context.TODO(), resprf[0].ResourceProfile, true); err != nil { t.Error(err) } - if err := dmRES.SetResource(context.TODO(), resourceTest[0]); err != nil { + if err := dmRES.SetResource(context.TODO(), resourceTest[0].Resource); err != nil { t.Error(err) } mres, err := resService.matchingResourcesForEvent(context.TODO(), resEvs[0].Tenant, resEvs[0], @@ -2003,10 +1964,10 @@ func TestResourceUsageTTLCase4(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[0].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[0].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].rPrf, mres[0].rPrf) } else if !reflect.DeepEqual(resourceTest[0].ttl, mres[0].ttl) { @@ -2015,68 +1976,80 @@ func TestResourceUsageTTLCase4(t *testing.T) { } func TestResourceResIDsMp(t *testing.T) { - resprf := []*ResourceProfile{ + resprf := []*resourceProfile{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + FilterIDs: []string{"FLTR_RES_1", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", // identifier of this resource - FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", // identifier of this resource + FilterIDs: []string{"FLTR_RES_2", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + FilterIDs: []string{"FLTR_RES_3", "*ai:~*req.AnswerTime:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, } resourceTest := Resources{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[0], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[0], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[1], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[1], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[2], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[2], }, } expected := utils.StringSet{ @@ -2090,20 +2063,21 @@ func TestResourceResIDsMp(t *testing.T) { } func TestResourceMatchWithIndexFalse(t *testing.T) { - var dmRES *DataManager + var dmRES *engine.DataManager cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES = NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES = engine.NewDataManager(data, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dmRES) resService := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) - Cache.Clear(nil) - fltrRes1 := &Filter{ + fltrs, nil) + engine.Cache.Clear(nil) + fltrRes1 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_1", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -2127,10 +2101,10 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes1, true) - fltrRes2 := &Filter{ + fltrRes2 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_2", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaString, Element: "~*req.Resources", @@ -2154,10 +2128,10 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes2, true) - fltrRes3 := &Filter{ + fltrRes3 := &engine.Filter{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "FLTR_RES_3", - Rules: []*FilterRule{ + Rules: []*engine.FilterRule{ { Type: utils.MetaPrefix, Element: "~*req.Resources", @@ -2166,68 +2140,80 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { }, } dmRES.SetFilter(context.Background(), fltrRes3, true) - resprf := []*ResourceProfile{ + resprf := []*resourceProfile{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - FilterIDs: []string{"FLTR_RES_1", "*ai:*now:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + FilterIDs: []string{"FLTR_RES_1", "*ai:*now:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", // identifier of this resource - FilterIDs: []string{"FLTR_RES_2", "*ai:*now:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", // identifier of this resource + FilterIDs: []string{"FLTR_RES_2", "*ai:*now:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - FilterIDs: []string{"FLTR_RES_3", "*ai:*now:2014-07-14T14:25:00Z"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{""}, + ResourceProfile: &utils.ResourceProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + FilterIDs: []string{"FLTR_RES_3", "*ai:*now:2014-07-14T14:25:00Z"}, + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{""}, + }, }, } resourceTest := Resources{ { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile1", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[0], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile1", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[0], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile2", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[1], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile2", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[1], }, { - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - ID: "ResourceProfile3", - Usages: map[string]*ResourceUsage{}, - TTLIdx: []string{}, - rPrf: resprf[2], + Resource: &utils.Resource{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ResourceProfile3", + Usages: map[string]*utils.ResourceUsage{}, + TTLIdx: []string{}, + }, + rPrf: resprf[2], }, } resEvs := []*utils.CGREvent{ @@ -2267,10 +2253,10 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { } timeDurationExample := 10 * time.Second for _, resProfile := range resprf { - dmRES.SetResourceProfile(context.TODO(), resProfile, true) + dmRES.SetResourceProfile(context.TODO(), resProfile.ResourceProfile, true) } for _, res := range resourceTest { - dmRES.SetResource(context.TODO(), res) + dmRES.SetResource(context.TODO(), res.Resource) } resService.cfg.ResourceSCfg().IndexedSelects = false mres, err := resService.matchingResourcesForEvent(context.TODO(), resEvs[0].Tenant, resEvs[0], @@ -2280,10 +2266,10 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { } mres.unlock() - if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[0].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[0].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].rPrf, mres[0].rPrf) } @@ -2294,10 +2280,10 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[1].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[1].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[1].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[1].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[1].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].rPrf, mres[0].rPrf) } @@ -2308,10 +2294,10 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { t.Errorf("Error: %+v", err) } mres.unlock() - if !reflect.DeepEqual(resourceTest[2].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resourceTest[2].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].ID, mres[0].ID) + if !reflect.DeepEqual(resourceTest[2].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resourceTest[2].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resourceTest[2].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].rPrf, mres[0].rPrf) } @@ -2319,19 +2305,20 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { func TestResourceCaching(t *testing.T) { //clear the cache - Cache.Clear(nil) + engine.Cache.Clear(nil) // start fresh with new dataManager cfg := config.NewDefaultCGRConfig() - dm := NewDataManager(NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, nil) + dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, - &FilterS{dm: dm, cfg: cfg}, nil) + fltrs, nil) - resProf := &ResourceProfile{ + resProf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResourceProfileCached", FilterIDs: []string{"*string:~*req.Account:1001", "*ai:*now:2014-07-14T14:25:00Z"}, @@ -2345,22 +2332,27 @@ func TestResourceCaching(t *testing.T) { ThresholdIDs: []string{utils.MetaNone}, } - if err := Cache.Set(context.TODO(), utils.CacheResourceProfiles, "cgrates.org:ResourceProfileCached", - resProf, nil, cacheCommit(utils.EmptyString), utils.EmptyString); err != nil { + if err := engine.Cache.Set(context.TODO(), utils.CacheResourceProfiles, "cgrates.org:ResourceProfileCached", + resProf, nil, true, utils.EmptyString); err != nil { t.Errorf("Expecting: nil, received: %s", err) } - res := &Resource{Tenant: resProf.Tenant, + res := &utils.Resource{Tenant: resProf.Tenant, ID: resProf.ID, - Usages: make(map[string]*ResourceUsage)} + Usages: make(map[string]*utils.ResourceUsage)} - if err := Cache.Set(context.TODO(), utils.CacheResources, "cgrates.org:ResourceProfileCached", - res, nil, cacheCommit(utils.EmptyString), utils.EmptyString); err != nil { + if err := engine.Cache.Set(context.TODO(), utils.CacheResources, "cgrates.org:ResourceProfileCached", + res, nil, true, utils.EmptyString); err != nil { t.Errorf("Expecting: nil, received: %s", err) } - resources := Resources{res} - if err := Cache.Set(context.TODO(), utils.CacheEventResources, "TestResourceCaching", resources.resIDsMp(), nil, true, ""); err != nil { + resources := Resources{ + { + Resource: res, + rPrf: &resourceProfile{ResourceProfile: resProf}, + }, + } + if err := engine.Cache.Set(context.TODO(), utils.CacheEventResources, "TestResourceCaching", resources.resIDsMp(), nil, true, ""); err != nil { t.Errorf("Expecting: nil, received: %s", err) } @@ -2375,13 +2367,13 @@ func TestResourceCaching(t *testing.T) { mres, err := rS.matchingResourcesForEvent(context.TODO(), ev.Tenant, ev, "TestResourceCaching", nil) if err != nil { - t.Errorf("Error: %+v", err) + t.Fatal(err) } mres.unlock() - if !reflect.DeepEqual(resources[0].Tenant, mres[0].Tenant) { - t.Errorf("Expecting: %+v, received: %+v", resources[0].Tenant, mres[0].Tenant) - } else if !reflect.DeepEqual(resources[0].ID, mres[0].ID) { - t.Errorf("Expecting: %+v, received: %+v", resources[0].ID, mres[0].ID) + if !reflect.DeepEqual(resources[0].Resource.Tenant, mres[0].Resource.Tenant) { + t.Errorf("Expecting: %+v, received: %+v", resources[0].Resource.Tenant, mres[0].Resource.Tenant) + } else if !reflect.DeepEqual(resources[0].Resource.ID, mres[0].Resource.ID) { + t.Errorf("Expecting: %+v, received: %+v", resources[0].Resource.ID, mres[0].Resource.ID) } else if !reflect.DeepEqual(resources[0].rPrf, mres[0].rPrf) { t.Errorf("Expecting: %+v, received: %+v", resources[0].rPrf, mres[0].rPrf) } else if !reflect.DeepEqual(resources[0].ttl, mres[0].ttl) { @@ -2397,29 +2389,33 @@ func TestResourcesRemoveExpiredUnitsResetTotalUsage(t *testing.T) { var buf bytes.Buffer utils.Logger = utils.NewStdLoggerWithWriter(&buf, "", 4) - r := &Resource{ - TTLIdx: []string{"ResGroup1", "ResGroup2", "ResGroup3"}, - Usages: map[string]*ResourceUsage{ - "ResGroup2": { - Tenant: "cgrates.org", - ID: "RU_2", - Units: 11, - ExpiryTime: time.Date(2021, 5, 3, 13, 0, 0, 0, time.UTC), - }, - "ResGroup3": { - Tenant: "cgrates.org", - ID: "RU_3", + r := &resource{ + Resource: &utils.Resource{ + TTLIdx: []string{"ResGroup1", "ResGroup2", "ResGroup3"}, + Usages: map[string]*utils.ResourceUsage{ + "ResGroup2": { + Tenant: "cgrates.org", + ID: "RU_2", + Units: 11, + ExpiryTime: time.Date(2021, 5, 3, 13, 0, 0, 0, time.UTC), + }, + "ResGroup3": { + Tenant: "cgrates.org", + ID: "RU_3", + }, }, }, tUsage: utils.Float64Pointer(10), } - exp := &Resource{ - TTLIdx: []string{"ResGroup3"}, - Usages: map[string]*ResourceUsage{ - "ResGroup3": { - Tenant: "cgrates.org", - ID: "RU_3", + exp := &resource{ + Resource: &utils.Resource{ + TTLIdx: []string{"ResGroup3"}, + Usages: map[string]*utils.ResourceUsage{ + "ResGroup3": { + Tenant: "cgrates.org", + ID: "RU_3", + }, }, }, } @@ -2438,9 +2434,9 @@ func TestResourcesRemoveExpiredUnitsResetTotalUsage(t *testing.T) { } func TestResourcesAvailable(t *testing.T) { - r := ResourceWithConfig{ - Resource: &Resource{ - Usages: map[string]*ResourceUsage{ + r := utils.ResourceWithConfig{ + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ "RU_1": { Units: 4, }, @@ -2449,7 +2445,7 @@ func TestResourcesAvailable(t *testing.T) { }, }, }, - Config: &ResourceProfile{ + Config: &utils.ResourceProfile{ Limit: 10, }, } @@ -2463,16 +2459,18 @@ func TestResourcesAvailable(t *testing.T) { } func TestResourcesRecordUsageZeroTTL(t *testing.T) { - r := &Resource{ - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", + r := &resource{ + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, }, }, ttl: utils.DurationPointer(0), } - ru := &ResourceUsage{ + ru := &utils.ResourceUsage{ ID: "RU_2", } @@ -2484,37 +2482,41 @@ func TestResourcesRecordUsageZeroTTL(t *testing.T) { } func TestResourcesRecordUsageGtZeroTTL(t *testing.T) { - r := &Resource{ - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", + r := &resource{ + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, }, + TTLIdx: []string{"RU_1"}, }, - TTLIdx: []string{"RU_1"}, - ttl: utils.DurationPointer(1 * time.Second), + ttl: utils.DurationPointer(1 * time.Second), } - ru := &ResourceUsage{ + ru := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU_2", } - exp := &Resource{ - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", + exp := &resource{ + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, }, + TTLIdx: []string{"RU_1", "RU_2"}, }, - TTLIdx: []string{"RU_1", "RU_2"}, - ttl: utils.DurationPointer(1 * time.Second), + ttl: utils.DurationPointer(1 * time.Second), } err := r.recordUsage(ru) - exp.Usages[ru.ID].ExpiryTime = r.Usages[ru.ID].ExpiryTime + exp.Resource.Usages[ru.ID].ExpiryTime = r.Resource.Usages[ru.ID].ExpiryTime if err != nil { t.Error(err) @@ -2546,68 +2548,76 @@ func TestResourcesRecordUsageClearErr(t *testing.T) { rs := Resources{ { - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, }, + TTLIdx: []string{"RU_1", "RU_2"}, }, - TTLIdx: []string{"RU_1", "RU_2"}, - ttl: utils.DurationPointer(1 * time.Second), + ttl: utils.DurationPointer(1 * time.Second), }, { - Usages: map[string]*ResourceUsage{ - "RU_3": { - Tenant: "cgrates.org", - ID: "RU_3", - }, - "RU_4": { - Tenant: "cgrates.org", - ID: "RU_4", + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_3": { + Tenant: "cgrates.org", + ID: "RU_3", + }, + "RU_4": { + Tenant: "cgrates.org", + ID: "RU_4", + }, }, + TTLIdx: []string{"RU_3"}, }, - TTLIdx: []string{"RU_3"}, - ttl: utils.DurationPointer(2 * time.Second), + ttl: utils.DurationPointer(2 * time.Second), }, } - ru := &ResourceUsage{ + ru := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU_4", } exp := Resources{ { - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, }, + TTLIdx: []string{"RU_1", "RU_2", "RU_4"}, }, - TTLIdx: []string{"RU_1", "RU_2", "RU_4"}, - ttl: utils.DurationPointer(1 * time.Second), + ttl: utils.DurationPointer(1 * time.Second), }, { - Usages: map[string]*ResourceUsage{ - "RU_3": { - Tenant: "cgrates.org", - ID: "RU_3", - }, - "RU_4": { - Tenant: "cgrates.org", - ID: "RU_4", + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_3": { + Tenant: "cgrates.org", + ID: "RU_3", + }, + "RU_4": { + Tenant: "cgrates.org", + ID: "RU_4", + }, }, + TTLIdx: []string{"RU_3"}, }, - TTLIdx: []string{"RU_3"}, - ttl: utils.DurationPointer(2 * time.Second), + ttl: utils.DurationPointer(2 * time.Second), }, } @@ -2619,7 +2629,7 @@ func TestResourcesRecordUsageClearErr(t *testing.T) { utils.Logger = utils.NewStdLoggerWithWriter(&mockWriter{ WriteF: func(p []byte) (n int, err error) { - delete(rs[0].Usages, "RU_4") + delete(rs[0].Resource.Usages, "RU_4") return buf.Write(p) }, }, "", 4) @@ -2643,7 +2653,7 @@ func TestResourcesRecordUsageClearErr(t *testing.T) { } func TestResourceAllocateResourceOtherDB(t *testing.T) { - rProf := &ResourceProfile{ + rProf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RL_DB", FilterIDs: []string{"*string:~*opts.Resource:RL_DB"}, @@ -2656,18 +2666,18 @@ func TestResourceAllocateResourceOtherDB(t *testing.T) { UsageTTL: -time.Nanosecond, } - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - dm := NewDataManager(NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, nil) - fltS := NewFilterS(cfg, nil, dm) + dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, nil) + fltS := engine.NewFilterS(cfg, nil, dm) rs := NewResourceService(dm, cfg, fltS, nil) if err := dm.SetResourceProfile(context.TODO(), rProf, true); err != nil { t.Fatal(err) } - if err := dm.SetResource(context.TODO(), &Resource{ + if err := dm.SetResource(context.TODO(), &utils.Resource{ Tenant: "cgrates.org", ID: "RL_DB", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { // the resource in DB is expired (should be cleaned when the next allocate is called) Tenant: "cgrates.org", ID: "RU1", @@ -2707,18 +2717,20 @@ func TestResourceClearUsageErr(t *testing.T) { utils.Logger = utils.NewStdLoggerWithWriter(&buf, "", 4) rs := Resources{ { - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, }, + TTLIdx: []string{"RU_1", "RU_2"}, }, - TTLIdx: []string{"RU_1", "RU_2"}, - ttl: utils.DurationPointer(1 * time.Second), + ttl: utils.DurationPointer(1 * time.Second), }, } @@ -2740,7 +2752,7 @@ func TestResourceClearUsageErr(t *testing.T) { func TestResourcesAllocateResourceErrRsUnavailable(t *testing.T) { rs := Resources{} - ru := &ResourceUsage{} + ru := &utils.ResourceUsage{} experr := utils.ErrResourceUnavailable rcv, err := rs.allocateResource(ru, false) @@ -2757,29 +2769,31 @@ func TestResourcesAllocateResourceErrRsUnavailable(t *testing.T) { func TestResourcesAllocateResourceEmptyConfiguration(t *testing.T) { rs := Resources{ { - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, }, + TTLIdx: []string{"RU_1", "RU_2"}, + Tenant: "cgrates.org", + ID: "Res_1", }, - TTLIdx: []string{"RU_1", "RU_2"}, - ttl: utils.DurationPointer(1 * time.Second), - Tenant: "cgrates.org", - ID: "Res_1", + ttl: utils.DurationPointer(1 * time.Second), }, } - ru := &ResourceUsage{ + ru := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU_2", } - experr := fmt.Sprintf("empty configuration for resourceID: %s", rs[0].TenantID()) + experr := fmt.Sprintf("empty configuration for resourceID: %s", rs[0].Resource.TenantID()) rcv, err := rs.allocateResource(ru, false) if err == nil || err.Error() != experr { @@ -2794,28 +2808,32 @@ func TestResourcesAllocateResourceEmptyConfiguration(t *testing.T) { func TestResourcesAllocateResourceDryRun(t *testing.T) { rs := Resources{ { - Usages: map[string]*ResourceUsage{ - "RU_1": { - Tenant: "cgrates.org", - ID: "RU_1", - }, - "RU_2": { - Tenant: "cgrates.org", - ID: "RU_2", - }, - }, - TTLIdx: []string{"RU_1", "RU_2"}, - ttl: utils.DurationPointer(1 * time.Second), - Tenant: "cgrates.org", - ID: "Res_1", - rPrf: &ResourceProfile{ + Resource: &utils.Resource{ Tenant: "cgrates.org", - ID: "ResGroup1", + ID: "Res_1", + Usages: map[string]*utils.ResourceUsage{ + "RU_1": { + Tenant: "cgrates.org", + ID: "RU_1", + }, + "RU_2": { + Tenant: "cgrates.org", + ID: "RU_2", + }, + }, + TTLIdx: []string{"RU_1", "RU_2"}, + }, + ttl: utils.DurationPointer(1 * time.Second), + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "ResGroup1", + }, }, }, } - ru := &ResourceUsage{ + ru := &utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU_2", } @@ -2833,11 +2851,11 @@ func TestResourcesAllocateResourceDryRun(t *testing.T) { } func TestResourcesStoreResources(t *testing.T) { - tmp := Cache + tmp := engine.Cache tmpLogger := utils.Logger defer func() { utils.Logger = tmpLogger - Cache = tmp + engine.Cache = tmp }() var buf bytes.Buffer @@ -2848,17 +2866,19 @@ func TestResourcesStoreResources(t *testing.T) { }, } - value := &Resource{ - dirty: utils.BoolPointer(true), - Tenant: "cgrates.org", - ID: "testResource", + value := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "testResource", + }, + dirty: utils.BoolPointer(true), } - Cache.SetWithoutReplicate(utils.CacheResources, "Res1", value, nil, true, + engine.Cache.SetWithoutReplicate(utils.CacheResources, "Res1", value, nil, true, utils.NonTransactional) explog := fmt.Sprintf("CGRateS <> [WARNING] <%s> failed saving Resource with ID: %s, error: %s\n", - utils.ResourceS, value.ID, utils.ErrNoDatabaseConn.Error()) + utils.ResourceS, value.Resource.ID, utils.ErrNoDatabaseConn.Error()) exp := &ResourceS{ storedResources: utils.StringSet{ "Res1": struct{}{}, @@ -2879,7 +2899,7 @@ func TestResourcesStoreResources(t *testing.T) { func TestResourcesStoreResourceNotDirty(t *testing.T) { rS := &ResourceS{} - r := &Resource{ + r := &resource{ dirty: utils.BoolPointer(false), } @@ -2893,10 +2913,11 @@ func TestResourcesStoreResourceNotDirty(t *testing.T) { func TestResourcesStoreResourceOK(t *testing.T) { cfg := config.NewDefaultCGRConfig() rS := &ResourceS{ - dm: NewDataManager(NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, nil), + dm: engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, nil), } - r := &Resource{ - dirty: utils.BoolPointer(true), + r := &resource{ + Resource: &utils.Resource{}, + dirty: utils.BoolPointer(true), } err := rS.storeResource(context.TODO(), r) @@ -2911,13 +2932,13 @@ func TestResourcesStoreResourceOK(t *testing.T) { } func TestResourcesStoreResourceErrCache(t *testing.T) { - tmp := Cache + tmp := engine.Cache tmpLogger := utils.Logger var buf bytes.Buffer utils.Logger = utils.NewStdLoggerWithWriter(&buf, "", 6) defer func() { - Cache = tmp + engine.Cache = tmp utils.Logger = tmpLogger }() @@ -2929,15 +2950,17 @@ func TestResourcesStoreResourceErrCache(t *testing.T) { cfg.CacheCfg().Partitions[utils.CacheResources].Replicate = true cfg.RPCConns()["test"] = &config.RPCConn{Conns: []*config.RemoteHost{{}}} config.SetCgrConfig(cfg) - dm := NewDataManager(NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, NewConnManager(cfg)) + dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, engine.NewConnManager(cfg)) rS := NewResourceService(dm, cfg, nil, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - r := &Resource{ - Tenant: "cgrates.org", - ID: "RES1", - dirty: utils.BoolPointer(true), + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + r := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES1", + }, + dirty: utils.BoolPointer(true), } - Cache.Set(context.Background(), utils.CacheResources, r.TenantID(), r, nil, true, "") + engine.Cache.Set(context.Background(), utils.CacheResources, r.Resource.TenantID(), r, nil, true, "") explog := `CGRateS <> [WARNING] failed caching Resource with ID: cgrates.org:RES1, error: DISCONNECTED ` @@ -2959,18 +2982,22 @@ func TestResourcesStoreResourceErrCache(t *testing.T) { func TestResourcesAllocateResourceEmptyKey(t *testing.T) { rs := Resources{ { - Usages: map[string]*ResourceUsage{ - "": {}, + Resource: &utils.Resource{ + Usages: map[string]*utils.ResourceUsage{ + "": {}, + }, }, - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RP_1", - AllocationMessage: "allocation msg", + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RP_1", + AllocationMessage: "allocation msg", + }, }, }, } - ru := &ResourceUsage{} + ru := &utils.ResourceUsage{} exp := "allocation msg" rcv, err := rs.allocateResource(ru, false) @@ -2988,9 +3015,11 @@ func TestResourcesProcessThresholdsNoConns(t *testing.T) { rS := &ResourceS{ cfg: cfg, } - r := &Resource{ - Tenant: "cgrates.org", - ID: "RES_1", + r := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES_1", + }, } opts := map[string]any{} @@ -3002,14 +3031,14 @@ func TestResourcesProcessThresholdsNoConns(t *testing.T) { } func TestResourcesProcessThresholdsOK(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().ThresholdSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)} - Cache = NewCacheS(cfg, nil, nil, nil) + engine.Cache = engine.NewCacheS(cfg, nil, nil, nil) ccM := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ @@ -3039,16 +3068,20 @@ func TestResourcesProcessThresholdsOK(t *testing.T) { rpcInternal <- ccM rS := &ResourceS{ cfg: cfg, - connMgr: NewConnManager(cfg), + connMgr: engine.NewConnManager(cfg), } rS.connMgr.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), utils.ThresholdSv1, rpcInternal) - r := &Resource{ - Tenant: "cgrates.org", - ID: "RES_1", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RP_1", - ThresholdIDs: []string{"THD_1"}, + r := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES_1", + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RP_1", + ThresholdIDs: []string{"THD_1"}, + }, }, } @@ -3061,10 +3094,10 @@ func TestResourcesProcessThresholdsOK(t *testing.T) { } func TestResourcesProcessThresholdsCallErr(t *testing.T) { - tmp := Cache + tmp := engine.Cache tmpLogger := utils.Logger defer func() { - Cache = tmp + engine.Cache = tmp utils.Logger = tmpLogger }() @@ -3073,7 +3106,7 @@ func TestResourcesProcessThresholdsCallErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().ThresholdSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)} - Cache = NewCacheS(cfg, nil, nil, nil) + engine.Cache = engine.NewCacheS(cfg, nil, nil, nil) ccM := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ @@ -3103,16 +3136,20 @@ func TestResourcesProcessThresholdsCallErr(t *testing.T) { rpcInternal <- ccM rS := &ResourceS{ cfg: cfg, - connMgr: NewConnManager(cfg), + connMgr: engine.NewConnManager(cfg), } rS.connMgr.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), utils.ThresholdSv1, rpcInternal) - r := &Resource{ - Tenant: "cgrates.org", - ID: "RES_1", - rPrf: &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RP_1", - ThresholdIDs: []string{"THD_1"}, + r := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES_1", + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RP_1", + ThresholdIDs: []string{"THD_1"}, + }, }, } @@ -3134,11 +3171,15 @@ func TestResourcesProcessThresholdsThdConnMetaNone(t *testing.T) { rS := &ResourceS{ cfg: cfg, } - r := &Resource{ - Tenant: "cgrates.org", - ID: "RES_1", - rPrf: &ResourceProfile{ - ThresholdIDs: []string{utils.MetaNone}, + r := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES_1", + }, + rPrf: &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + ThresholdIDs: []string{utils.MetaNone}, + }, }, } opts := map[string]any{} @@ -3161,142 +3202,19 @@ func (ccM *ccMock) Call(ctx *context.Context, serviceMethod string, args any, re return call(ctx, args, reply) } } -func TestResourcesUpdateResource(t *testing.T) { - cfg := config.NewDefaultCGRConfig() - dm := NewDataManager(NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg, nil) - Cache.Clear(nil) - res := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - UsageTTL: 0, - Limit: 10, - Stored: true, - } - r := &Resource{ - Tenant: res.Tenant, - ID: res.ID, - Usages: map[string]*ResourceUsage{ - "jkbdfgs": { - Tenant: res.Tenant, - ID: "jkbdfgs", - ExpiryTime: time.Now(), - Units: 5, - }, - }, - TTLIdx: []string{"jkbdfgs"}, - } - expR := &Resource{ - Tenant: res.Tenant, - ID: res.ID, - Usages: make(map[string]*ResourceUsage), - } - if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { - t.Fatal(err) - } - - if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(r, expR) { - t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) - } - - if err := dm.RemoveResource(context.Background(), r.Tenant, r.ID); err != nil { - t.Fatal(err) - } - - if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { - t.Fatal(err) - } - - if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(r, expR) { - t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) - } - - if err := dm.SetResource(context.Background(), r); err != nil { - t.Fatal(err) - } - - res = &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - UsageTTL: 0, - Limit: 5, - Stored: true, - } - if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { - t.Fatal(err) - } - if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(r, expR) { - t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) - } - - if err := dm.SetResource(context.Background(), r); err != nil { - t.Fatal(err) - } - - res = &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - UsageTTL: 10, - Limit: 5, - Stored: true, - } - if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { - t.Fatal(err) - } - if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(r, expR) { - t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) - } - - if err := dm.SetResource(context.Background(), r); err != nil { - t.Fatal(err) - } - - res = &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - UsageTTL: 10, - Limit: 5, - Stored: false, - } - if err := dm.SetResourceProfile(context.Background(), res, true); err != nil { - t.Fatal(err) - } - if r, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(r, expR) { - t.Errorf("Expected: %s, received: %s", utils.ToJSON(expR), utils.ToJSON(r)) - } - - if err := dm.RemoveResourceProfile(context.Background(), res.Tenant, res.ID, true); err != nil { - t.Fatal(err) - } - - if _, err := dm.GetResource(context.Background(), res.Tenant, res.ID, false, false, utils.NonTransactional); err != utils.ErrNotFound { - t.Fatal(err) - } - - dm.DataDB().Flush(utils.EmptyString) -} func TestResourcesV1ResourcesForEventOK(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -3309,21 +3227,17 @@ func TestResourcesV1ResourcesForEventOK(t *testing.T) { Limit: 10, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + TTLIdx: []string{}, + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), - TTLIdx: []string{}, } err := dm.SetResourceProfile(context.Background(), rsPrf, true) if err != nil { @@ -3334,7 +3248,7 @@ func TestResourcesV1ResourcesForEventOK(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -3349,20 +3263,20 @@ func TestResourcesV1ResourcesForEventOK(t *testing.T) { exp := Resources{ { - rPrf: rsPrf, - Tenant: "cgrates.org", - ID: "RES1", - Usages: map[string]*ResourceUsage{ - "RU1": { - Tenant: "cgrates.org", - ID: "RU1", - Units: 10, + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES1", + TTLIdx: []string{}, + Usages: map[string]*utils.ResourceUsage{ + "RU1": { + Tenant: "cgrates.org", + ID: "RU1", + Units: 10, + }, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(72 * time.Hour), - TTLIdx: []string{}, + rPrf: &resourceProfile{ResourceProfile: rsPrf}, + ttl: utils.DurationPointer(72 * time.Hour), }, } var reply Resources @@ -3375,11 +3289,11 @@ func TestResourcesV1ResourcesForEventOK(t *testing.T) { } func TestResourcesV1ResourcesForEventNotFound(t *testing.T) { - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - rsPrf := &ResourceProfile{ + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -3391,11 +3305,10 @@ func TestResourcesV1ResourcesForEventNotFound(t *testing.T) { Limit: 10, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", @@ -3412,7 +3325,7 @@ func TestResourcesV1ResourcesForEventNotFound(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -3434,11 +3347,11 @@ func TestResourcesV1ResourcesForEventNotFound(t *testing.T) { } func TestResourcesV1ResourcesForEventMissingParameters(t *testing.T) { - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - rsPrf := &ResourceProfile{ + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -3450,11 +3363,10 @@ func TestResourcesV1ResourcesForEventMissingParameters(t *testing.T) { Limit: 10, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", @@ -3471,7 +3383,7 @@ func TestResourcesV1ResourcesForEventMissingParameters(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) experr := `MANDATORY_IE_MISSING: [Event]` @@ -3527,50 +3439,48 @@ func TestResourcesV1ResourcesForEventMissingParameters(t *testing.T) { } func TestResourcesV1ResourcesForEventCacheReplyExists(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit = 1 config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) cacheKey := utils.ConcatenatedKey(utils.ResourceSv1GetResourcesForEvent, utils.ConcatenatedKey("cgrates.org", "ResourcesForEventTest")) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 10, + UsageTTL: time.Minute, + }, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } @@ -3579,7 +3489,7 @@ func TestResourcesV1ResourcesForEventCacheReplyExists(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -3594,23 +3504,25 @@ func TestResourcesV1ResourcesForEventCacheReplyExists(t *testing.T) { cacheReply := Resources{ { - rPrf: rsPrf, - Tenant: "cgrates.org", - ID: "RES1", - Usages: map[string]*ResourceUsage{ - "RU1": { - Tenant: "cgrates.org", - ID: "RU1", - Units: 10, + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES1", + Usages: map[string]*utils.ResourceUsage{ + "RU1": { + Tenant: "cgrates.org", + ID: "RU1", + Units: 10, + }, }, + TTLIdx: []string{}, }, + rPrf: rsPrf, dirty: utils.BoolPointer(false), tUsage: utils.Float64Pointer(10), ttl: utils.DurationPointer(time.Minute), - TTLIdx: []string{}, }, } - Cache.Set(context.Background(), utils.CacheRPCResponses, cacheKey, + engine.Cache.Set(context.Background(), utils.CacheRPCResponses, cacheKey, &utils.CachedRPCResponse{Result: &cacheReply, Error: nil}, nil, true, utils.NonTransactional) var reply Resources @@ -3625,21 +3537,21 @@ func TestResourcesV1ResourcesForEventCacheReplyExists(t *testing.T) { } func TestResourcesV1ResourcesForEventCacheReplySet(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit = 1 config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) cacheKey := utils.ConcatenatedKey(utils.ResourceSv1GetResourcesForEvent, utils.ConcatenatedKey("cgrates.org", "ResourcesForEventTest")) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -3652,20 +3564,16 @@ func TestResourcesV1ResourcesForEventCacheReplySet(t *testing.T) { Limit: 10, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } err := dm.SetResourceProfile(context.Background(), rsPrf, true) @@ -3677,7 +3585,7 @@ func TestResourcesV1ResourcesForEventCacheReplySet(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -3692,31 +3600,32 @@ func TestResourcesV1ResourcesForEventCacheReplySet(t *testing.T) { exp := &Resources{ { - rPrf: rsPrf, - Tenant: "cgrates.org", - ID: "RES1", - Usages: map[string]*ResourceUsage{ - "RU1": { - Tenant: "cgrates.org", - ID: "RU1", - Units: 10, + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES1", + Usages: map[string]*utils.ResourceUsage{ + "RU1": { + Tenant: "cgrates.org", + ID: "RU1", + Units: 10, + }, }, + TTLIdx: []string{}, + }, + ttl: utils.DurationPointer(72 * time.Hour), + rPrf: &resourceProfile{ + ResourceProfile: rsPrf, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(72 * time.Hour), - TTLIdx: []string{}, }, } var reply Resources if err := rS.V1GetResourcesForEvent(context.Background(), args, &reply); err != nil { t.Error(err) } else if !reflect.DeepEqual(reply, *exp) { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", - utils.ToJSON(exp), utils.ToJSON(reply)) + t.Errorf("expected: <%v>, received: <%v>", exp, reply) } - if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has { + if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has { resp := itm.(*utils.CachedRPCResponse) if !reflect.DeepEqual(resp.Result, exp) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(exp), utils.ToJSON(resp.Result)) @@ -3727,44 +3636,27 @@ func TestResourcesV1ResourcesForEventCacheReplySet(t *testing.T) { } func TestResourcesV1GetResourceOK(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, - } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } err := dm.SetResource(context.Background(), rs) @@ -3772,24 +3664,20 @@ func TestResourcesV1GetResourceOK(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) - exp := Resource{ - rPrf: rsPrf, + exp := utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + TTLIdx: []string{}, + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), - TTLIdx: []string{}, } args := &utils.TenantIDWithAPIOpts{ @@ -3797,7 +3685,7 @@ func TestResourcesV1GetResourceOK(t *testing.T) { ID: "RES1", }, } - var reply Resource + var reply utils.Resource if err := rS.V1GetResource(context.Background(), args, &reply); err != nil { t.Error(err) } else if !reflect.DeepEqual(reply, exp) { @@ -3807,44 +3695,27 @@ func TestResourcesV1GetResourceOK(t *testing.T) { } func TestResourcesV1GetResourceNotFound(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, - } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } err := dm.SetResource(context.Background(), rs) @@ -3852,7 +3723,7 @@ func TestResourcesV1GetResourceNotFound(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.TenantIDWithAPIOpts{ @@ -3861,7 +3732,7 @@ func TestResourcesV1GetResourceNotFound(t *testing.T) { ID: "RES2", }, } - var reply Resource + var reply utils.Resource if err := rS.V1GetResource(context.Background(), args, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) @@ -3869,44 +3740,27 @@ func TestResourcesV1GetResourceNotFound(t *testing.T) { } func TestResourcesV1GetResourceMissingParameters(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, - } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } err := dm.SetResource(context.Background(), rs) @@ -3914,7 +3768,7 @@ func TestResourcesV1GetResourceMissingParameters(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.TenantIDWithAPIOpts{ @@ -3922,7 +3776,7 @@ func TestResourcesV1GetResourceMissingParameters(t *testing.T) { } experr := `MANDATORY_IE_MISSING: [ID]` - var reply Resource + var reply utils.Resource if err := rS.V1GetResource(context.Background(), args, &reply); err == nil || err.Error() != experr { t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) @@ -3930,101 +3784,18 @@ func TestResourcesV1GetResourceMissingParameters(t *testing.T) { } func TestResourcesV1GetResourceWithConfigOK(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, - } - rs := &Resource{ - rPrf: rsPrf, - Tenant: "cgrates.org", - ID: "RES1", - Usages: map[string]*ResourceUsage{ - "RU1": { - Tenant: "cgrates.org", - ID: "RU1", - Units: 10, - }, - }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), - TTLIdx: []string{}, - } - err := dm.SetResource(context.Background(), rs) - if err != nil { - t.Error(err) - } - - fltrs := NewFilterS(cfg, nil, dm) - rS := NewResourceService(dm, cfg, fltrs, nil) - - exp := ResourceWithConfig{ - Resource: &Resource{ - rPrf: rsPrf, - Tenant: "cgrates.org", - ID: "RES1", - Usages: map[string]*ResourceUsage{ - "RU1": { - Tenant: "cgrates.org", - ID: "RU1", - Units: 10, - }, - }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), - TTLIdx: []string{}, - }, - Config: rsPrf, - } - - args := &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{ - ID: "RES1", - }, - } - var reply ResourceWithConfig - if err := rS.V1GetResourceWithConfig(context.Background(), args, &reply); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(reply, exp) { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", - utils.ToJSON(exp), utils.ToJSON(reply)) - } -} - -func TestResourcesV1GetResourceWithConfigNilrPrfOK(t *testing.T) { - tmp := Cache - defer func() { - Cache = tmp - }() - - Cache.Clear(nil) - cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -4041,19 +3812,16 @@ func TestResourcesV1GetResourceWithConfigNilrPrfOK(t *testing.T) { if err != nil { t.Error(err) } - rs := &Resource{ + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } err = dm.SetResource(context.Background(), rs) @@ -4061,24 +3829,20 @@ func TestResourcesV1GetResourceWithConfigNilrPrfOK(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) - exp := ResourceWithConfig{ - Resource: &Resource{ - rPrf: rsPrf, + exp := utils.ResourceWithConfig{ + Resource: &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, }, Config: rsPrf, @@ -4089,7 +3853,7 @@ func TestResourcesV1GetResourceWithConfigNilrPrfOK(t *testing.T) { ID: "RES1", }, } - var reply ResourceWithConfig + var reply utils.ResourceWithConfig if err := rS.V1GetResourceWithConfig(context.Background(), args, &reply); err != nil { t.Error(err) } else if !reflect.DeepEqual(reply, exp) { @@ -4099,18 +3863,18 @@ func TestResourcesV1GetResourceWithConfigNilrPrfOK(t *testing.T) { } func TestResourcesV1GetResourceWithConfigNilrPrfProfileNotFound(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES2", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -4127,19 +3891,16 @@ func TestResourcesV1GetResourceWithConfigNilrPrfProfileNotFound(t *testing.T) { if err != nil { t.Error(err) } - rs := &Resource{ + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } err = dm.SetResource(context.Background(), rs) @@ -4147,7 +3908,7 @@ func TestResourcesV1GetResourceWithConfigNilrPrfProfileNotFound(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.TenantIDWithAPIOpts{ @@ -4155,7 +3916,7 @@ func TestResourcesV1GetResourceWithConfigNilrPrfProfileNotFound(t *testing.T) { ID: "RES1", }, } - var reply ResourceWithConfig + var reply utils.ResourceWithConfig if err := rS.V1GetResourceWithConfig(context.Background(), args, &reply); err == nil || err != utils.ErrNotFound { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) @@ -4163,44 +3924,27 @@ func TestResourcesV1GetResourceWithConfigNilrPrfProfileNotFound(t *testing.T) { } func TestResourcesV1GetResourceWithConfigResourceNotFound(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES2", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, - } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES2", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } err := dm.SetResource(context.Background(), rs) @@ -4208,7 +3952,7 @@ func TestResourcesV1GetResourceWithConfigResourceNotFound(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.TenantIDWithAPIOpts{ @@ -4216,51 +3960,34 @@ func TestResourcesV1GetResourceWithConfigResourceNotFound(t *testing.T) { ID: "RES1", }, } - var reply ResourceWithConfig + var reply utils.ResourceWithConfig if err := rS.V1GetResourceWithConfig(context.Background(), args, &reply); err == nil || err != utils.ErrNotFound { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } } func TestResourcesV1GetResourceWithConfigMissingParameters(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, - } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } err := dm.SetResource(context.Background(), rs) @@ -4268,51 +3995,53 @@ func TestResourcesV1GetResourceWithConfigMissingParameters(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) experr := `MANDATORY_IE_MISSING: [ID]` args := &utils.TenantIDWithAPIOpts{ TenantID: &utils.TenantID{}, } - var reply ResourceWithConfig + var reply utils.ResourceWithConfig if err := rS.V1GetResourceWithConfig(context.Background(), args, &reply); err == nil || err.Error() != experr { t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) } } func TestResourcesV1AuthorizeResourcesOK(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 10, + UsageTTL: time.Minute, + }, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4336,37 +4065,39 @@ func TestResourcesV1AuthorizeResourcesOK(t *testing.T) { } func TestResourcesV1AuthorizeResourcesNotAuthorized(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 0, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 0, + UsageTTL: time.Minute, + }, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4390,37 +4121,39 @@ func TestResourcesV1AuthorizeResourcesNotAuthorized(t *testing.T) { } func TestResourcesV1AuthorizeResourcesNoMatch(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 10, + UsageTTL: time.Minute, + }, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4444,37 +4177,39 @@ func TestResourcesV1AuthorizeResourcesNoMatch(t *testing.T) { } func TestResourcesV1AuthorizeResourcesNilCGREvent(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 10, + UsageTTL: time.Minute, + }, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) experr := `MANDATORY_IE_MISSING: [Event]` @@ -4487,37 +4222,39 @@ func TestResourcesV1AuthorizeResourcesNilCGREvent(t *testing.T) { } func TestResourcesV1AuthorizeResourcesMissingUsageID(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 10, + UsageTTL: time.Minute, + }, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4538,22 +4275,22 @@ func TestResourcesV1AuthorizeResourcesMissingUsageID(t *testing.T) { } func TestResourcesV1AuthorizeResourcesCacheReplyExists(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit = 1 config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) cacheKey := utils.ConcatenatedKey(utils.ResourceSv1AuthorizeResources, utils.ConcatenatedKey("cgrates.org", "EventAuthorizeResource")) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -4566,20 +4303,16 @@ func TestResourcesV1AuthorizeResourcesCacheReplyExists(t *testing.T) { Limit: 10, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } @@ -4592,7 +4325,7 @@ func TestResourcesV1AuthorizeResourcesCacheReplyExists(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4608,7 +4341,7 @@ func TestResourcesV1AuthorizeResourcesCacheReplyExists(t *testing.T) { } cacheReply := "Approved" - Cache.Set(context.Background(), utils.CacheRPCResponses, cacheKey, + engine.Cache.Set(context.Background(), utils.CacheRPCResponses, cacheKey, &utils.CachedRPCResponse{Result: &cacheReply, Error: nil}, nil, true, utils.NonTransactional) @@ -4622,22 +4355,22 @@ func TestResourcesV1AuthorizeResourcesCacheReplyExists(t *testing.T) { } func TestResourcesV1AuthorizeResourcesCacheReplySet(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit = 1 config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) cacheKey := utils.ConcatenatedKey(utils.ResourceSv1AuthorizeResources, utils.ConcatenatedKey("cgrates.org", "EventAuthorizeResource")) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -4650,20 +4383,16 @@ func TestResourcesV1AuthorizeResourcesCacheReplySet(t *testing.T) { Limit: -1, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 4, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } @@ -4676,7 +4405,7 @@ func TestResourcesV1AuthorizeResourcesCacheReplySet(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4698,7 +4427,7 @@ func TestResourcesV1AuthorizeResourcesCacheReplySet(t *testing.T) { t.Errorf("Unexpected reply returned: %q", reply) } - if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has { + if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has { resp := itm.(*utils.CachedRPCResponse) if *resp.Result.(*string) != "Approved" { t.Errorf("expected: <%+v>, \nreceived: <%+v>", @@ -4710,37 +4439,39 @@ func TestResourcesV1AuthorizeResourcesCacheReplySet(t *testing.T) { } func TestResourcesV1AllocateResourcesOK(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 10, + UsageTTL: time.Minute, + }, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4764,37 +4495,39 @@ func TestResourcesV1AllocateResourcesOK(t *testing.T) { } func TestResourcesV1AllocateResourcesNoMatch(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 10, + UsageTTL: time.Minute, + }, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4817,18 +4550,18 @@ func TestResourcesV1AllocateResourcesNoMatch(t *testing.T) { } func TestResourcesV1AllocateResourcesMissingParameters(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -4847,7 +4580,7 @@ func TestResourcesV1AllocateResourcesMissingParameters(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4906,22 +4639,22 @@ func TestResourcesV1AllocateResourcesMissingParameters(t *testing.T) { } func TestResourcesV1AllocateResourcesCacheReplyExists(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit = 1 config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) cacheKey := utils.ConcatenatedKey(utils.ResourceSv1AllocateResources, utils.ConcatenatedKey("cgrates.org", "EventAllocateResource")) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -4934,20 +4667,16 @@ func TestResourcesV1AllocateResourcesCacheReplyExists(t *testing.T) { Limit: -1, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } @@ -4960,7 +4689,7 @@ func TestResourcesV1AllocateResourcesCacheReplyExists(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -4976,7 +4705,7 @@ func TestResourcesV1AllocateResourcesCacheReplyExists(t *testing.T) { } cacheReply := "cacheApproved" - Cache.Set(context.Background(), utils.CacheRPCResponses, cacheKey, + engine.Cache.Set(context.Background(), utils.CacheRPCResponses, cacheKey, &utils.CachedRPCResponse{Result: &cacheReply, Error: nil}, nil, true, utils.NonTransactional) @@ -4990,22 +4719,22 @@ func TestResourcesV1AllocateResourcesCacheReplyExists(t *testing.T) { } func TestResourcesV1AllocateResourcesCacheReplySet(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit = 1 config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) cacheKey := utils.ConcatenatedKey(utils.ResourceSv1AllocateResources, utils.ConcatenatedKey("cgrates.org", "EventAllocateResource")) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5018,20 +4747,16 @@ func TestResourcesV1AllocateResourcesCacheReplySet(t *testing.T) { Limit: -1, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 4, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } @@ -5044,7 +4769,7 @@ func TestResourcesV1AllocateResourcesCacheReplySet(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -5066,7 +4791,7 @@ func TestResourcesV1AllocateResourcesCacheReplySet(t *testing.T) { t.Errorf("Unexpected reply returned: %q", reply) } - if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has { + if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has { resp := itm.(*utils.CachedRPCResponse) if *resp.Result.(*string) != "Approved" { t.Errorf("expected: <%+v>, \nreceived: <%+v>", @@ -5078,18 +4803,18 @@ func TestResourcesV1AllocateResourcesCacheReplySet(t *testing.T) { } func TestResourcesV1AllocateResourcesResAllocErr(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5107,7 +4832,7 @@ func TestResourcesV1AllocateResourcesResAllocErr(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -5130,20 +4855,20 @@ func TestResourcesV1AllocateResourcesResAllocErr(t *testing.T) { } func TestResourcesV1AllocateResourcesProcessThErr(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().StoreInterval = 2 cfg.ResourceSCfg().ThresholdSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)} - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5156,20 +4881,16 @@ func TestResourcesV1AllocateResourcesProcessThErr(t *testing.T) { Limit: -1, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } @@ -5191,9 +4912,9 @@ func TestResourcesV1AllocateResourcesProcessThErr(t *testing.T) { } rpcInternal := make(chan birpc.ClientConnector, 1) rpcInternal <- ccM - cM := NewConnManager(cfg) + cM := engine.NewConnManager(cfg) cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), utils.ThresholdSv1, rpcInternal) - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, cM) args := &utils.CGREvent{ @@ -5217,18 +4938,18 @@ func TestResourcesV1AllocateResourcesProcessThErr(t *testing.T) { } func TestResourcesV1ReleaseResourcesOK(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5247,7 +4968,7 @@ func TestResourcesV1ReleaseResourcesOK(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -5276,18 +4997,18 @@ func TestResourcesV1ReleaseResourcesOK(t *testing.T) { } func TestResourcesV1ReleaseResourcesUsageNotFound(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5306,7 +5027,7 @@ func TestResourcesV1ReleaseResourcesUsageNotFound(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -5347,18 +5068,18 @@ func TestResourcesV1ReleaseResourcesUsageNotFound(t *testing.T) { } func TestResourcesV1ReleaseResourcesNoMatch(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5377,7 +5098,7 @@ func TestResourcesV1ReleaseResourcesNoMatch(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -5400,18 +5121,18 @@ func TestResourcesV1ReleaseResourcesNoMatch(t *testing.T) { } func TestResourcesV1ReleaseResourcesMissingParameters(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5430,7 +5151,7 @@ func TestResourcesV1ReleaseResourcesMissingParameters(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -5489,22 +5210,22 @@ func TestResourcesV1ReleaseResourcesMissingParameters(t *testing.T) { } func TestResourcesV1ReleaseResourcesCacheReplyExists(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit = 1 config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) cacheKey := utils.ConcatenatedKey(utils.ResourceSv1ReleaseResources, utils.ConcatenatedKey("cgrates.org", "EventReleaseResource")) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5517,20 +5238,16 @@ func TestResourcesV1ReleaseResourcesCacheReplyExists(t *testing.T) { Limit: -1, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 10, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } @@ -5543,7 +5260,7 @@ func TestResourcesV1ReleaseResourcesCacheReplyExists(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -5559,7 +5276,7 @@ func TestResourcesV1ReleaseResourcesCacheReplyExists(t *testing.T) { }, } cacheReply := "cacheReply" - Cache.Set(context.Background(), utils.CacheRPCResponses, cacheKey, + engine.Cache.Set(context.Background(), utils.CacheRPCResponses, cacheKey, &utils.CachedRPCResponse{Result: &cacheReply, Error: nil}, nil, true, utils.NonTransactional) @@ -5573,22 +5290,22 @@ func TestResourcesV1ReleaseResourcesCacheReplyExists(t *testing.T) { } func TestResourcesV1ReleaseResourcesCacheReplySet(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit = 1 config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) cacheKey := utils.ConcatenatedKey(utils.ResourceSv1ReleaseResources, utils.ConcatenatedKey("cgrates.org", "EventReleaseResource")) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5601,20 +5318,16 @@ func TestResourcesV1ReleaseResourcesCacheReplySet(t *testing.T) { Limit: -1, UsageTTL: time.Minute, } - rs := &Resource{ - rPrf: rsPrf, + rs := &utils.Resource{ Tenant: "cgrates.org", ID: "RES1", - Usages: map[string]*ResourceUsage{ + Usages: map[string]*utils.ResourceUsage{ "RU1": { Tenant: "cgrates.org", ID: "RU1", Units: 4, }, }, - dirty: utils.BoolPointer(false), - tUsage: utils.Float64Pointer(10), - ttl: utils.DurationPointer(time.Minute), TTLIdx: []string{}, } @@ -5627,7 +5340,7 @@ func TestResourcesV1ReleaseResourcesCacheReplySet(t *testing.T) { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -5649,7 +5362,7 @@ func TestResourcesV1ReleaseResourcesCacheReplySet(t *testing.T) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) } - if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has { + if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has { resp := itm.(*utils.CachedRPCResponse) if *resp.Result.(*string) != "" { t.Errorf("expected: <%+v>, \nreceived: <%+v>", @@ -5661,18 +5374,18 @@ func TestResourcesV1ReleaseResourcesCacheReplySet(t *testing.T) { } func TestResourcesV1ReleaseResourcesProcessThErr(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().StoreInterval = 2 cfg.ResourceSCfg().ThresholdSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)} - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) ccM := &ccMock{ calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.ThresholdSv1ProcessEvent: func(ctx *context.Context, args, reply any) error { @@ -5682,49 +5395,53 @@ func TestResourcesV1ReleaseResourcesProcessThErr(t *testing.T) { } rpcInternal := make(chan birpc.ClientConnector, 1) rpcInternal <- ccM - cM := NewConnManager(cfg) + cM := engine.NewConnManager(cfg) cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), utils.ThresholdSv1, rpcInternal) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: -1, - UsageTTL: time.Minute, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: -1, + UsageTTL: time.Minute, + }, } - rs := &Resource{ - rPrf: rsPrf, - Tenant: "cgrates.org", - ID: "RES1", - Usages: map[string]*ResourceUsage{ - "RU_Test": { - Tenant: "cgrates.org", - ID: "RU_Test", - Units: 4, + rs := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES1", + Usages: map[string]*utils.ResourceUsage{ + "RU_Test": { + Tenant: "cgrates.org", + ID: "RU_Test", + Units: 4, + }, }, + TTLIdx: []string{}, }, dirty: utils.BoolPointer(false), tUsage: utils.Float64Pointer(10), ttl: utils.DurationPointer(time.Minute), - TTLIdx: []string{}, + rPrf: rsPrf, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Error(err) } - err = dm.SetResource(context.Background(), rs) + err = dm.SetResource(context.Background(), rs.Resource) if err != nil { t.Error(err) } - fltrs := NewFilterS(cfg, nil, dm) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, cM) args := &utils.CGREvent{ @@ -5741,7 +5458,7 @@ func TestResourcesV1ReleaseResourcesProcessThErr(t *testing.T) { var reply string var resources Resources resources = append(resources, rs) - if _, err := resources.allocateResource(&ResourceUsage{ + if _, err := resources.allocateResource(&utils.ResourceUsage{ Tenant: "cgrates.org", ID: "RU_ID", Units: 1}, true); err != nil { @@ -5757,7 +5474,7 @@ func TestResourcesV1ReleaseResourcesProcessThErr(t *testing.T) { } func TestResourcesStoreResourceError(t *testing.T) { - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().StoreInterval = -1 cfg.RPCConns()["test"] = &config.RPCConn{ @@ -5768,12 +5485,12 @@ func TestResourcesStoreResourceError(t *testing.T) { config.SetCgrConfig(cfg) defer config.SetCgrConfig(dft) - db := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(db, cfg, NewConnManager(cfg)) + db := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(db, cfg, engine.NewConnManager(cfg)) - rS := NewResourceService(dm, cfg, NewFilterS(cfg, nil, dm), nil) + rS := NewResourceService(dm, cfg, engine.NewFilterS(cfg, nil, dm), nil) - rsPrf := &ResourceProfile{ + rsPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "RES1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -5825,15 +5542,16 @@ func TestResourcesStoreResourceError(t *testing.T) { func TestResourceMatchingResourcesForEventNotFoundInCache(t *testing.T) { cfg := config.NewDefaultCGRConfig() - db := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES := NewDataManager(db, cfg, nil) + db := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES := engine.NewDataManager(db, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dmRES) rS := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) + fltrs, nil) - Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventNotFoundInCache", nil, nil, true, utils.NonTransactional) + engine.Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventNotFoundInCache", nil, nil, true, utils.NonTransactional) _, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), "TestResourceMatchingResourcesForEventNotFoundInCache", utils.DurationPointer(10*time.Second)) if err != utils.ErrNotFound { @@ -5843,15 +5561,16 @@ func TestResourceMatchingResourcesForEventNotFoundInCache(t *testing.T) { func TestResourceMatchingResourcesForEventNotFoundInDB(t *testing.T) { cfg := config.NewDefaultCGRConfig() - db := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dmRES := NewDataManager(db, cfg, nil) + db := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dmRES := engine.NewDataManager(db, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dmRES) rS := NewResourceService(dmRES, cfg, - &FilterS{dm: dmRES, cfg: cfg}, nil) + fltrs, nil) - Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventNotFoundInDB", utils.StringSet{"Res2": {}}, nil, true, utils.NonTransactional) + engine.Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventNotFoundInDB", utils.StringSet{"Res2": {}}, nil, true, utils.NonTransactional) _, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), "TestResourceMatchingResourcesForEventNotFoundInDB", utils.DurationPointer(10*time.Second)) if err != utils.ErrNotFound { @@ -5861,52 +5580,58 @@ func TestResourceMatchingResourcesForEventNotFoundInDB(t *testing.T) { func TestResourceMatchingResourcesForEventLocks(t *testing.T) { cfg := config.NewDefaultCGRConfig() - db := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(db, cfg, nil) + db := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(db, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, - &FilterS{dm: dm, cfg: cfg}, nil) - Cache.Clear(nil) + fltrs, nil) + engine.Cache.Clear(nil) - prfs := make([]*ResourceProfile, 0) + prfs := make([]*resourceProfile, 0) ids := utils.StringSet{} - for i := 0; i < 10; i++ { - rPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: fmt.Sprintf("RES%d", i), - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{utils.MetaNone}, + for i := range 10 { + rPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: fmt.Sprintf("RES%d", i), + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{utils.MetaNone}, + }, } - dm.SetResourceProfile(context.Background(), rPrf, true) + dm.SetResourceProfile(context.Background(), rPrf.ResourceProfile, true) prfs = append(prfs, rPrf) - ids.Add(rPrf.ID) + ids.Add(rPrf.ResourceProfile.ID) } dm.RemoveResource(context.Background(), "cgrates.org", "RES1") - Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocks", ids, nil, true, utils.NonTransactional) - _, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), + engine.Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocks", ids, nil, true, utils.NonTransactional) + rs, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), "TestResourceMatchingResourcesForEventLocks", utils.DurationPointer(10*time.Second)) if err != utils.ErrNotFound { t.Errorf("Error: %+v", err) } for _, rPrf := range prfs { if rPrf.isLocked() { - t.Fatalf("Expected profile to not be locked %q", rPrf.ID) + t.Fatalf("Expected profile to not be locked %q", rPrf.ResourceProfile.ID) } - if rPrf.ID == "RES1" { + if rPrf.ResourceProfile.ID == "RES1" { continue } - if r, err := dm.GetResource(context.Background(), rPrf.Tenant, rPrf.ID, true, false, utils.NonTransactional); err != nil { - t.Errorf("error %s for <%s>", err, rPrf.ID) - } else if r.isLocked() { - t.Fatalf("Expected resource to not be locked %q", rPrf.ID) + for _, r := range rs { + if r.Resource.ID != rPrf.ResourceProfile.ID { + continue + } + if r.isLocked() { + t.Fatalf("Expected resource to not be locked %q", rPrf.ResourceProfile.ID) + } } } @@ -5914,21 +5639,42 @@ func TestResourceMatchingResourcesForEventLocks(t *testing.T) { func TestResourceMatchingResourcesForEventLocks2(t *testing.T) { cfg := config.NewDefaultCGRConfig() - db := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(db, cfg, nil) + db := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(db, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, - &FilterS{dm: dm, cfg: cfg}, nil) - Cache.Clear(nil) + fltrs, nil) + engine.Cache.Clear(nil) - prfs := make([]*ResourceProfile, 0) + prfs := make([]*resourceProfile, 0) ids := utils.StringSet{} - for i := 0; i < 10; i++ { - rPrf := &ResourceProfile{ + for i := range 10 { + rPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: fmt.Sprintf("RES%d", i), + UsageTTL: 10 * time.Second, + Limit: 10.00, + AllocationMessage: "AllocationMessage", + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }}, + ThresholdIDs: []string{utils.MetaNone}, + }, + } + dm.SetResourceProfile(context.Background(), rPrf.ResourceProfile, true) + prfs = append(prfs, rPrf) + ids.Add(rPrf.ResourceProfile.ID) + } + rPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ Tenant: "cgrates.org", - ID: fmt.Sprintf("RES%d", i), + ID: "RES20", + FilterIDs: []string{"FLTR_RES_201"}, UsageTTL: 10 * time.Second, Limit: 10.00, AllocationMessage: "AllocationMessage", @@ -5937,125 +5683,49 @@ func TestResourceMatchingResourcesForEventLocks2(t *testing.T) { Weight: 20.00, }}, ThresholdIDs: []string{utils.MetaNone}, - } - dm.SetResourceProfile(context.Background(), rPrf, true) - prfs = append(prfs, rPrf) - ids.Add(rPrf.ID) + }, } - rPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES20", - FilterIDs: []string{"FLTR_RES_201"}, - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: 20.00, - }}, - ThresholdIDs: []string{utils.MetaNone}, - } - err := db.SetResourceProfileDrv(context.Background(), rPrf) + err := db.SetResourceProfileDrv(context.Background(), rPrf.ResourceProfile) if err != nil { t.Fatal(err) } prfs = append(prfs, rPrf) - ids.Add(rPrf.ID) - Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocks2", ids, nil, true, utils.NonTransactional) - _, err = rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), + ids.Add(rPrf.ResourceProfile.ID) + engine.Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocks2", ids, nil, true, utils.NonTransactional) + rs, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), "TestResourceMatchingResourcesForEventLocks2", utils.DurationPointer(10*time.Second)) - expErr := utils.ErrPrefixNotFound(rPrf.FilterIDs[0]) + expErr := utils.ErrPrefixNotFound(rPrf.ResourceProfile.FilterIDs[0]) if err == nil || err.Error() != expErr.Error() { t.Errorf("Expected error: %s ,received: %+v", expErr, err) } for _, rPrf := range prfs { if rPrf.isLocked() { - t.Fatalf("Expected profile to not be locked %q", rPrf.ID) + t.Fatalf("Expected profile to not be locked %q", rPrf.ResourceProfile.ID) } - if rPrf.ID == "RES20" { + if rPrf.ResourceProfile.ID == "RES20" { continue } - if r, err := dm.GetResource(context.Background(), rPrf.Tenant, rPrf.ID, true, false, utils.NonTransactional); err != nil { - t.Errorf("error %s for <%s>", err, rPrf.ID) - } else if r.isLocked() { - t.Fatalf("Expected resource to not be locked %q", rPrf.ID) - } - } -} - -func TestResourceMatchingResourcesForEventLocksBlocker(t *testing.T) { - cfg := config.NewDefaultCGRConfig() - db := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(db, cfg, nil) - cfg.ResourceSCfg().StoreInterval = 1 - cfg.ResourceSCfg().StringIndexedFields = nil - cfg.ResourceSCfg().PrefixIndexedFields = nil - rS := NewResourceService(dm, cfg, - &FilterS{dm: dm, cfg: cfg}, nil) - Cache.Clear(nil) - - prfs := make([]*ResourceProfile, 0) - ids := utils.StringSet{} - for i := 0; i < 10; i++ { - rPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: fmt.Sprintf("RES%d", i), - UsageTTL: 10 * time.Second, - Limit: 10.00, - AllocationMessage: "AllocationMessage", - Weights: utils.DynamicWeights{ - { - Weight: float64(10 - i), - }}, - Blocker: i == 4, - ThresholdIDs: []string{utils.MetaNone}, - } - dm.SetResourceProfile(context.Background(), rPrf, true) - prfs = append(prfs, rPrf) - ids.Add(rPrf.ID) - } - Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocksBlocker", ids, nil, true, utils.NonTransactional) - mres, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), - "TestResourceMatchingResourcesForEventLocksBlocker", utils.DurationPointer(10*time.Second)) - if err != nil { - t.Errorf("Error: %+v", err) - } - defer mres.unlock() - if len(mres) != 5 { - t.Fatal("Expected 6 resources") - } - for _, rPrf := range prfs[5:] { - if rPrf.isLocked() { - t.Errorf("Expected profile to not be locked %q", rPrf.ID) - } - if r, err := dm.GetResource(context.Background(), rPrf.Tenant, rPrf.ID, true, false, utils.NonTransactional); err != nil { - t.Errorf("error %s for <%s>", err, rPrf.ID) - } else if r.isLocked() { - t.Fatalf("Expected resource to not be locked %q", rPrf.ID) - } - } - for _, rPrf := range prfs[:5] { - if !rPrf.isLocked() { - t.Errorf("Expected profile to be locked %q", rPrf.ID) - } - if r, err := dm.GetResource(context.Background(), rPrf.Tenant, rPrf.ID, true, false, utils.NonTransactional); err != nil { - t.Errorf("error %s for <%s>", err, rPrf.ID) - } else if !r.isLocked() { - t.Fatalf("Expected resource to be locked %q", rPrf.ID) + for _, r := range rs { + if r.Resource.ID != rPrf.ResourceProfile.ID { + continue + } + if r.isLocked() { + t.Fatalf("Expected resource to not be locked %q", rPrf.ResourceProfile.ID) + } } } } func TestResourceMatchingResourcesForEventLocks3(t *testing.T) { cfg := config.NewDefaultCGRConfig() - prfs := make([]*ResourceProfile, 0) - Cache.Clear(nil) - db := &DataDBMock{ - GetResourceProfileDrvF: func(_ *context.Context, tnt, id string) (*ResourceProfile, error) { + prfs := make([]*utils.ResourceProfile, 0) + engine.Cache.Clear(nil) + db := &engine.DataDBMock{ + GetResourceProfileDrvF: func(_ *context.Context, tnt, id string) (*utils.ResourceProfile, error) { if id == "RES1" { return nil, utils.ErrNotImplemented } - rPrf := &ResourceProfile{ + rPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: id, UsageTTL: 10 * time.Second, @@ -6067,51 +5737,55 @@ func TestResourceMatchingResourcesForEventLocks3(t *testing.T) { }}, ThresholdIDs: []string{utils.MetaNone}, } - Cache.Set(context.Background(), utils.CacheResources, rPrf.TenantID(), &Resource{ - Tenant: rPrf.Tenant, - ID: rPrf.ID, - Usages: make(map[string]*ResourceUsage), - }, nil, true, utils.NonTransactional) + engine.Cache.Set(context.Background(), utils.CacheResources, rPrf.TenantID(), + &utils.Resource{ + Tenant: rPrf.Tenant, + ID: rPrf.ID, + Usages: make(map[string]*utils.ResourceUsage), + }, nil, true, utils.NonTransactional) prfs = append(prfs, rPrf) return rPrf, nil }, } - dm := NewDataManager(db, cfg, nil) + dm := engine.NewDataManager(db, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, - &FilterS{dm: dm, cfg: cfg}, nil) + fltrs, nil) ids := utils.StringSet{} - for i := 0; i < 10; i++ { + for i := range 10 { ids.Add(fmt.Sprintf("RES%d", i)) } - Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocks3", ids, nil, true, utils.NonTransactional) - _, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), + engine.Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocks3", ids, nil, true, utils.NonTransactional) + mres, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), "TestResourceMatchingResourcesForEventLocks3", utils.DurationPointer(10*time.Second)) if err != utils.ErrNotImplemented { t.Errorf("Error: %+v", err) } - for _, rPrf := range prfs { - if rPrf.isLocked() { - t.Fatalf("Expected profile to not be locked %q", rPrf.ID) + for _, r := range mres { + if r.rPrf.isLocked() { + t.Fatalf("Expected profile to not be locked %q", r.rPrf.ResourceProfile.ID) } } } func TestResourcesLockUnlockResourceProfiles(t *testing.T) { - rp := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - Limit: 10, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - ThresholdIDs: []string{utils.MetaNone}, + rp := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + Limit: 10, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + ThresholdIDs: []string{utils.MetaNone}, + }, } //lock profile with empty lkID parameter @@ -6143,9 +5817,11 @@ func TestResourcesLockUnlockResourceProfiles(t *testing.T) { } func TestResourcesLockUnlockResources(t *testing.T) { - rs := &Resource{ - Tenant: "cgrates.org", - ID: "RES1", + rs := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES1", + }, } //lock resource with empty lkID parameter @@ -6194,8 +5870,8 @@ func TestResourcesRunBackupStoreIntervalLessThanZero(t *testing.T) { func TestResourcesRunBackupStop(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().StoreInterval = 5 * time.Millisecond - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) tnt := "cgrates.org" resID := "Res1" rS := &ResourceS{ @@ -6207,12 +5883,14 @@ func TestResourcesRunBackupStop(t *testing.T) { loopStopped: make(chan struct{}, 1), stopBackup: make(chan struct{}), } - value := &Resource{ - dirty: utils.BoolPointer(true), - Tenant: tnt, - ID: resID, + value := &resource{ + Resource: &utils.Resource{ + Tenant: tnt, + ID: resID, + }, + dirty: utils.BoolPointer(true), } - Cache.SetWithoutReplicate(utils.CacheResources, resID, value, nil, true, "") + engine.Cache.SetWithoutReplicate(utils.CacheResources, resID, value, nil, true, "") // Backup loop checks for the state of the stopBackup // channel after storing the resource. Channel can be @@ -6220,8 +5898,7 @@ func TestResourcesRunBackupStop(t *testing.T) { close(rS.stopBackup) rS.runBackup(context.Background()) - want := &Resource{ - dirty: utils.BoolPointer(false), + want := &utils.Resource{ Tenant: tnt, ID: resID, } @@ -6272,25 +5949,25 @@ func TestResourcesStartLoop(t *testing.T) { } // func TestResourcesMatchingResourcesForEvent2(t *testing.T) { -// tmp := Cache +// tmp := engine.Cache // tmpC := config.CgrConfig() // defer func() { -// Cache = tmp +// engine.Cache = tmp // config.SetCgrConfig(tmpC) // }() -// Cache.Clear(nil) +// engine.Cache.Clear(nil) // cfg := config.NewDefaultCGRConfig() // cfg.CacheCfg().ReplicationConns = []string{"test"} // cfg.CacheCfg().Partitions[utils.CacheEventResources].Replicate = true // cfg.RPCConns()["test"] = &config.RPCConn{Conns: []*config.RemoteHost{{}}} // config.SetCgrConfig(cfg) -// data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) -// dm := NewDataManager(data, cfg.CacheCfg(), nil) -// connMgr = NewConnManager(cfg) -// Cache = NewCacheS(cfg, dm, nil,nil) +// data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) +// dm := engine.NewDataManager(data, cfg.CacheCfg(), nil) +// connMgr = engine.NewConnManager(cfg) +// engine.Cache = engine.NewCacheS(cfg, dm, nil,nil) -// fltrs := NewFilterS(cfg, nil, dm) +// fltrs := engine.NewFilterS(cfg, nil, dm) // rsPrf := &ResourceProfile{ // Tenant: "cgrates.org", @@ -6319,33 +5996,31 @@ func TestResourcesStartLoop(t *testing.T) { // APIOpts: map[string]any{}, // } -// Cache.SetWithoutReplicate(utils.CacheEventResources, ev.ID, utils.StringSet{ +// engine.Cache.SetWithoutReplicate(utils.CacheEventResources, ev.ID, utils.StringSet{ // "RES1": struct{}{}, // }, nil, true, utils.NonTransactional) // _, err = rS.matchingResourcesForEvent(context.Background(), "cgrates.org", ev, ev.ID, utils.DurationPointer(10*time.Second)) // } func TestResourcesMatchingResourcesForEventCacheSetErr(t *testing.T) { - tmp := Cache + tmp := engine.Cache tmpC := config.CgrConfig() - tmpCM := connMgr defer func() { - Cache = tmp + engine.Cache = tmp config.SetCgrConfig(tmpC) - connMgr = tmpCM }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().ReplicationConns = []string{"test"} cfg.CacheCfg().Partitions[utils.CacheEventResources].Replicate = true cfg.RPCConns()["test"] = &config.RPCConn{Conns: []*config.RemoteHost{{}}} config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - connMgr = NewConnManager(cfg) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + connMgr := engine.NewConnManager(cfg) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, connMgr) ev := &utils.CGREvent{ @@ -6366,43 +6041,43 @@ func TestResourcesMatchingResourcesForEventCacheSetErr(t *testing.T) { } func TestResourcesMatchingResourcesForEventFinalCacheSetErr(t *testing.T) { - tmp := Cache + tmp := engine.Cache tmpC := config.CgrConfig() - tmpCM := connMgr defer func() { - Cache = tmp + engine.Cache = tmp config.SetCgrConfig(tmpC) - connMgr = tmpCM }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.CacheCfg().ReplicationConns = []string{"test"} cfg.CacheCfg().Partitions[utils.CacheEventResources].Replicate = true cfg.RPCConns()["test"] = &config.RPCConn{Conns: []*config.RemoteHost{{}}} config.SetCgrConfig(cfg) - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - connMgr = NewConnManager(cfg) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + connMgr := engine.NewConnManager(cfg) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) - rsPrf := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - ThresholdIDs: []string{utils.MetaNone}, - AllocationMessage: "Approved", - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - Limit: 10, - UsageTTL: time.Minute, - Stored: true, + rsPrf := &resourceProfile{ + ResourceProfile: &utils.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ThresholdIDs: []string{utils.MetaNone}, + AllocationMessage: "Approved", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }}, + Limit: 10, + UsageTTL: time.Minute, + Stored: true, + }, } - err := dm.SetResourceProfile(context.Background(), rsPrf, true) + err := dm.SetResourceProfile(context.Background(), rsPrf.ResourceProfile, true) if err != nil { t.Fatal(err) } @@ -6416,13 +6091,15 @@ func TestResourcesMatchingResourcesForEventFinalCacheSetErr(t *testing.T) { }, APIOpts: map[string]any{}, } - exp := &Resource{ - Tenant: "cgrates.org", - rPrf: rsPrf, - ID: "RES1", - Usages: make(map[string]*ResourceUsage), - ttl: utils.DurationPointer(10 * time.Second), - dirty: utils.BoolPointer(false), + exp := &resource{ + Resource: &utils.Resource{ + Tenant: "cgrates.org", + ID: "RES1", + Usages: make(map[string]*utils.ResourceUsage), + }, + ttl: utils.DurationPointer(10 * time.Second), + dirty: utils.BoolPointer(false), + rPrf: rsPrf, } if rcv, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", ev, ev.ID, @@ -6438,20 +6115,20 @@ func TestResourcesMatchingResourcesForEventFinalCacheSetErr(t *testing.T) { } func TestResourcesV1ResourcesForEventErrRetrieveUsageID(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.UsageID = []*config.DynamicStringOpt{ config.NewDynamicStringOpt([]string{"FLTR_Invalid"}, "*any", "value", nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6471,20 +6148,20 @@ func TestResourcesV1ResourcesForEventErrRetrieveUsageID(t *testing.T) { } func TestResourcesV1ResourcesForEventErrRetrieveUsageTTL(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.UsageTTL = []*config.DynamicDurationOpt{ config.NewDynamicDurationOpt([]string{"FLTR_Invalid"}, "*any", time.Minute, nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6504,20 +6181,20 @@ func TestResourcesV1ResourcesForEventErrRetrieveUsageTTL(t *testing.T) { } func TestResourcesV1AuthorizeResourcesErrRetrieveUsageID(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.UsageID = []*config.DynamicStringOpt{ config.NewDynamicStringOpt([]string{"FLTR_Invalid"}, "*any", "value", nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6537,20 +6214,20 @@ func TestResourcesV1AuthorizeResourcesErrRetrieveUsageID(t *testing.T) { } func TestResourcesV1AuthorizeResourcesErrRetrieveUnits(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.Units = []*config.DynamicFloat64Opt{ config.NewDynamicFloat64Opt([]string{"FLTR_Invalid"}, "*any", 3, nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6570,20 +6247,20 @@ func TestResourcesV1AuthorizeResourcesErrRetrieveUnits(t *testing.T) { } func TestResourcesV1AuthorizeResourcesErrRetrieveUsageTTL(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.UsageTTL = []*config.DynamicDurationOpt{ config.NewDynamicDurationOpt([]string{"FLTR_Invalid"}, "*any", time.Minute, nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6603,20 +6280,20 @@ func TestResourcesV1AuthorizeResourcesErrRetrieveUsageTTL(t *testing.T) { } func TestResourcesV1AllocateResourcesErrRetrieveUsageID(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.UsageID = []*config.DynamicStringOpt{ config.NewDynamicStringOpt([]string{"FLTR_Invalid"}, "*any", "value", nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6636,20 +6313,20 @@ func TestResourcesV1AllocateResourcesErrRetrieveUsageID(t *testing.T) { } func TestResourcesV1AllocateResourcesErrRetrieveUsageTTL(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.UsageTTL = []*config.DynamicDurationOpt{ config.NewDynamicDurationOpt([]string{"FLTR_Invalid"}, "*any", time.Minute, nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6669,20 +6346,20 @@ func TestResourcesV1AllocateResourcesErrRetrieveUsageTTL(t *testing.T) { } func TestResourcesV1AllocateResourcesErrRetrieveUnits(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.Units = []*config.DynamicFloat64Opt{ config.NewDynamicFloat64Opt([]string{"FLTR_Invalid"}, "*any", 3, nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6702,20 +6379,20 @@ func TestResourcesV1AllocateResourcesErrRetrieveUnits(t *testing.T) { } func TestResourcesV1ReleaseResourcesErrRetrieveUsageID(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.UsageID = []*config.DynamicStringOpt{ config.NewDynamicStringOpt([]string{"FLTR_Invalid"}, "*any", "value", nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6735,20 +6412,20 @@ func TestResourcesV1ReleaseResourcesErrRetrieveUsageID(t *testing.T) { } func TestResourcesV1ReleaseResourcesErrRetrieveUsageTTL(t *testing.T) { - tmp := Cache + tmp := engine.Cache defer func() { - Cache = tmp + engine.Cache = tmp }() - Cache.Clear(nil) + engine.Cache.Clear(nil) cfg := config.NewDefaultCGRConfig() cfg.ResourceSCfg().Opts.UsageTTL = []*config.DynamicDurationOpt{ config.NewDynamicDurationOpt([]string{"FLTR_Invalid"}, "*any", time.Minute, nil), } - data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(data, cfg, nil) - Cache = NewCacheS(cfg, dm, nil, nil) - fltrs := NewFilterS(cfg, nil, dm) + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg, nil) + engine.Cache = engine.NewCacheS(cfg, dm, nil, nil) + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, fltrs, nil) args := &utils.CGREvent{ @@ -6766,268 +6443,26 @@ func TestResourcesV1ReleaseResourcesErrRetrieveUsageTTL(t *testing.T) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) } } -func TestResourceProfileSet(t *testing.T) { - cp := ResourceProfile{} - exp := ResourceProfile{ - Tenant: "cgrates.org", - ID: "ID", - FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - UsageTTL: 10, - Limit: 10, - AllocationMessage: "new", - Blocker: true, - Stored: true, - ThresholdIDs: []string{"TH1"}, - } - if err := cp.Set([]string{}, "", false); err != utils.ErrWrongPath { - t.Error(err) - } - if err := cp.Set([]string{"NotAField"}, "", false); err != utils.ErrWrongPath { - t.Error(err) - } - if err := cp.Set([]string{"NotAField", "1"}, "", false); err != utils.ErrWrongPath { - t.Error(err) - } - - if err := cp.Set([]string{utils.Tenant}, "cgrates.org", false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.ID}, "ID", false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.FilterIDs}, "fltr1;*string:~*req.Account:1001", false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.Weights}, ";10", false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.UsageTTL}, 10, false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.Limit}, 10, false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.AllocationMessage}, "new", false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.Blocker}, true, false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.Stored}, true, false); err != nil { - t.Error(err) - } - if err := cp.Set([]string{utils.ThresholdIDs}, "TH1", false); err != nil { - t.Error(err) - } - - if !reflect.DeepEqual(exp, cp) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(cp)) - } -} - -func TestResourceProfileAsInterface(t *testing.T) { - rp := ResourceProfile{ - Tenant: "cgrates.org", - ID: "ID", - FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - UsageTTL: 10, - Limit: 10, - AllocationMessage: "new", - Blocker: true, - Stored: true, - ThresholdIDs: []string{"TH1"}, - } - if _, err := rp.FieldAsInterface(nil); err != utils.ErrNotFound { - t.Fatal(err) - } - if _, err := rp.FieldAsInterface([]string{"field"}); err != utils.ErrNotFound { - t.Fatal(err) - } - if _, err := rp.FieldAsInterface([]string{"field", ""}); err != utils.ErrNotFound { - t.Fatal(err) - } - if val, err := rp.FieldAsInterface([]string{utils.Tenant}); err != nil { - t.Fatal(err) - } else if exp := "cgrates.org"; exp != val { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.ID}); err != nil { - t.Fatal(err) - } else if exp := utils.ID; exp != val { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.FilterIDs}); err != nil { - t.Fatal(err) - } else if exp := rp.FilterIDs; !reflect.DeepEqual(exp, val) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.FilterIDs + "[0]"}); err != nil { - t.Fatal(err) - } else if exp := rp.FilterIDs[0]; exp != val { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.Weights}); err != nil { - t.Fatal(err) - } else if exp := rp.Weights; !reflect.DeepEqual(exp, val) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.ThresholdIDs}); err != nil { - t.Fatal(err) - } else if exp := rp.ThresholdIDs; !reflect.DeepEqual(exp, val) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.ThresholdIDs + "[0]"}); err != nil { - t.Fatal(err) - } else if exp := rp.ThresholdIDs[0]; exp != val { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - - if val, err := rp.FieldAsInterface([]string{utils.UsageTTL}); err != nil { - t.Fatal(err) - } else if exp := rp.UsageTTL; !reflect.DeepEqual(exp, val) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.Limit}); err != nil { - t.Fatal(err) - } else if exp := rp.Limit; !reflect.DeepEqual(exp, val) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.AllocationMessage}); err != nil { - t.Fatal(err) - } else if exp := rp.AllocationMessage; !reflect.DeepEqual(exp, val) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.Blocker}); err != nil { - t.Fatal(err) - } else if exp := rp.Blocker; !reflect.DeepEqual(exp, val) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, err := rp.FieldAsInterface([]string{utils.Stored}); err != nil { - t.Fatal(err) - } else if exp := rp.Stored; !reflect.DeepEqual(exp, val) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - - if _, err := rp.FieldAsString([]string{""}); err != utils.ErrNotFound { - t.Fatal(err) - } - if val, err := rp.FieldAsString([]string{utils.ID}); err != nil { - t.Fatal(err) - } else if exp := "ID"; exp != val { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - if val, exp := rp.String(), utils.ToJSON(rp); exp != val { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) - } - -} - -func TestResourceProfileMerge(t *testing.T) { - dp := &ResourceProfile{} - exp := &ResourceProfile{ - Tenant: "cgrates.org", - ID: "ID", - FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - UsageTTL: 10, - Limit: 10, - AllocationMessage: "new", - Blocker: true, - Stored: true, - ThresholdIDs: []string{"TH1"}, - } - if dp.Merge(&ResourceProfile{ - Tenant: "cgrates.org", - ID: "ID", - FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, - Weights: utils.DynamicWeights{ - { - Weight: 10, - }}, - UsageTTL: 10, - Limit: 10, - AllocationMessage: "new", - Blocker: true, - Stored: true, - ThresholdIDs: []string{"TH1"}, - }); !reflect.DeepEqual(exp, dp) { - t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(dp)) - } -} - -func TestResourceMatchingResourcesForEventLocksErr(t *testing.T) { - - defer func() { - Cache = NewCacheS(config.NewDefaultCGRConfig(), nil, nil, nil) - }() - Cache = NewCacheS(config.NewDefaultCGRConfig(), nil, nil, nil) - - cfg := config.NewDefaultCGRConfig() - db := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - ids := utils.StringSet{} - for i := 0; i < 10; i++ { - ids.Add(fmt.Sprintf("RES%d", i)) - } - if err := Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocks3", ids, nil, true, utils.NonTransactional); err != nil { - t.Error(err) - } - Cache.cfg.CacheCfg().ReplicationConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator)} - Cache.cfg.CacheCfg().Partitions[utils.CacheEventResources].Replicate = true - - cc := make(chan birpc.ClientConnector, 1) - cc <- &ccMock{ - - calls: map[string]func(ctx *context.Context, args any, reply any) error{ - utils.CacheSv1ReplicateRemove: func(ctx *context.Context, args, reply any) error { return utils.ErrNotImplemented }, - }, - } - - cM := NewConnManager(cfg) - cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaReplicator), utils.CacheSv1, cc) - - Cache.connMgr = cM - - dm := NewDataManager(db, cfg, cM) - rS := NewResourceService(dm, cfg, - &FilterS{dm: dm, cfg: cfg, connMgr: cM}, cM) - - _, err := rS.matchingResourcesForEvent(context.Background(), "cgrates.org", new(utils.CGREvent), - "TestResourceMatchingResourcesForEventLocks3", utils.DurationPointer(10*time.Second)) - if err != utils.ErrNotImplemented { - t.Errorf("Error: %+v", err) - } - -} func TestResourceMatchingResourcesForEventWeightFromDynamicsErr(t *testing.T) { defer func() { - Cache = NewCacheS(config.NewDefaultCGRConfig(), nil, nil, nil) + engine.Cache = engine.NewCacheS(config.NewDefaultCGRConfig(), nil, nil, nil) }() cfg := config.NewDefaultCGRConfig() - db := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) - dm := NewDataManager(db, cfg, nil) + db := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(db, cfg, nil) cfg.ResourceSCfg().StoreInterval = 1 cfg.ResourceSCfg().StringIndexedFields = nil cfg.ResourceSCfg().PrefixIndexedFields = nil + fltrs := engine.NewFilterS(cfg, nil, dm) rS := NewResourceService(dm, cfg, - &FilterS{dm: dm, cfg: cfg}, nil) + fltrs, nil) ids := utils.StringSet{} - for i := 0; i < 10; i++ { - rPrf := &ResourceProfile{ + for i := range 10 { + rPrf := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: fmt.Sprintf("RES%d", i), UsageTTL: 10 * time.Second, @@ -7044,7 +6479,7 @@ func TestResourceMatchingResourcesForEventWeightFromDynamicsErr(t *testing.T) { dm.SetResourceProfile(context.Background(), rPrf, true) ids.Add(rPrf.ID) } - if err := Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocksBlocker", ids, nil, true, utils.NonTransactional); err != nil { + if err := engine.Cache.Set(context.Background(), utils.CacheEventResources, "TestResourceMatchingResourcesForEventLocksBlocker", ids, nil, true, utils.NonTransactional); err != nil { t.Error(err) } diff --git a/routes/libroutes.go b/routes/libroutes.go index 354e5e15b..fc7b506f9 100644 --- a/routes/libroutes.go +++ b/routes/libroutes.go @@ -134,7 +134,7 @@ func (sRoutes *SortedRoutes) SortQOS(params []string) { // sort ascendent based on ResourceUsage with fallback on Weight func (sRoutes *SortedRoutes) SortResourceAscendent() { sort.Slice(sRoutes.Routes, func(i, j int) bool { - cmp := sRoutes.Routes[i].getSortedData(utils.ResourceUsage).Compare(sRoutes.Routes[j].getSortedData(utils.ResourceUsage)) + cmp := sRoutes.Routes[i].getSortedData(utils.ResourceUsageStr).Compare(sRoutes.Routes[j].getSortedData(utils.ResourceUsageStr)) if cmp == 0 { return sRoutes.compareWeight(i, j) } @@ -146,7 +146,7 @@ func (sRoutes *SortedRoutes) SortResourceAscendent() { // sort descendent based on ResourceUsage with fallback on Weight func (sRoutes *SortedRoutes) SortResourceDescendent() { sort.Slice(sRoutes.Routes, func(i, j int) bool { - cmp := sRoutes.Routes[i].getSortedData(utils.ResourceUsage).Compare(sRoutes.Routes[j].getSortedData(utils.ResourceUsage)) + cmp := sRoutes.Routes[i].getSortedData(utils.ResourceUsageStr).Compare(sRoutes.Routes[j].getSortedData(utils.ResourceUsageStr)) if cmp == 0 { return sRoutes.compareWeight(i, j) } diff --git a/routes/libroutes_test.go b/routes/libroutes_test.go index 9c3418266..7015bb165 100644 --- a/routes/libroutes_test.go +++ b/routes/libroutes_test.go @@ -972,12 +972,12 @@ func TestLibRoutesResAscSameWeight(t *testing.T) { route := &SortedRoute{ RouteID: strconv.Itoa(i), sortingDataDecimal: map[string]*utils.Decimal{ - utils.ResourceUsage: utils.NewDecimalFromFloat64(5.0), - utils.Weight: utils.NewDecimalFromFloat64(10.0), + utils.ResourceUsageStr: utils.NewDecimalFromFloat64(5.0), + utils.Weight: utils.NewDecimalFromFloat64(10.0), }, SortingData: map[string]any{ - utils.ResourceUsage: 5.0, - utils.Weight: 10.0, + utils.ResourceUsageStr: 5.0, + utils.Weight: 10.0, }, } sSpls.Routes = append(sSpls.Routes, route) @@ -1001,12 +1001,12 @@ func TestLibRoutesResDescSameWeight(t *testing.T) { route := &SortedRoute{ RouteID: strconv.Itoa(i), sortingDataDecimal: map[string]*utils.Decimal{ - utils.ResourceUsage: utils.NewDecimalFromFloat64(5.0), - utils.Weight: utils.NewDecimalFromFloat64(10.0), + utils.ResourceUsageStr: utils.NewDecimalFromFloat64(5.0), + utils.Weight: utils.NewDecimalFromFloat64(10.0), }, SortingData: map[string]any{ - utils.ResourceUsage: 5.0, - utils.Weight: 10.0, + utils.ResourceUsageStr: 5.0, + utils.Weight: 10.0, }, } sSpls.Routes = append(sSpls.Routes, route) @@ -1235,23 +1235,23 @@ func TestSortResourceAscendentDescendent(t *testing.T) { { RouteID: "route2", sortingDataDecimal: map[string]*utils.Decimal{ - utils.ResourceUsage: utils.NewDecimalFromFloat64(10.0), - utils.Weight: utils.NewDecimalFromFloat64(10.0), + utils.ResourceUsageStr: utils.NewDecimalFromFloat64(10.0), + utils.Weight: utils.NewDecimalFromFloat64(10.0), }, SortingData: map[string]any{ - utils.ResourceUsage: 10.0, - utils.Weight: 10.0, + utils.ResourceUsageStr: 10.0, + utils.Weight: 10.0, }, }, { RouteID: "route1", sortingDataDecimal: map[string]*utils.Decimal{ - utils.ResourceUsage: utils.NewDecimalFromFloat64(10.0), - utils.Weight: utils.NewDecimalFromFloat64(11.0), + utils.ResourceUsageStr: utils.NewDecimalFromFloat64(10.0), + utils.Weight: utils.NewDecimalFromFloat64(11.0), }, SortingData: map[string]any{ - utils.ResourceUsage: 10.0, - utils.Weight: 11.0, + utils.ResourceUsageStr: 10.0, + utils.Weight: 11.0, }, }, }, @@ -1270,8 +1270,8 @@ func TestSortResourceAscendentDescendent(t *testing.T) { } //SortingResourceAscendent/Descendent while ResourceUsages are not equal - sSpls.Routes[0].SortingData[utils.ResourceUsage] = 11.0 - sSpls.Routes[0].sortingDataDecimal[utils.ResourceUsage] = utils.NewDecimalFromFloat64(11.0) + sSpls.Routes[0].SortingData[utils.ResourceUsageStr] = 11.0 + sSpls.Routes[0].sortingDataDecimal[utils.ResourceUsageStr] = utils.NewDecimalFromFloat64(11.0) expSRts = sSpls sSpls.SortResourceAscendent() if !reflect.DeepEqual(expSRts, sSpls) { diff --git a/routes/route_resource_sort.go b/routes/route_resource_sort.go index d27b2cfb7..8b2f2cd8a 100644 --- a/routes/route_resource_sort.go +++ b/routes/route_resource_sort.go @@ -57,7 +57,7 @@ func populateResourcesForRoutes(ctx *context.Context, cfg *config.CGRConfig, } var tUsage float64 for _, resID := range route.ResourceIDs { - var res engine.Resource + var res utils.Resource if err = connMgr.Call(ctx, cfg.RouteSCfg().ResourceSConns, utils.ResourceSv1GetResource, &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: ev.Tenant, ID: resID}}, &res); err != nil && err.Error() != utils.ErrNotFound.Error() { @@ -68,8 +68,8 @@ func populateResourcesForRoutes(ctx *context.Context, cfg *config.CGRConfig, } tUsage += res.TotalUsage() } - srtRoute.SortingData[utils.ResourceUsage] = tUsage - srtRoute.sortingDataDecimal[utils.ResourceUsage] = utils.NewDecimalFromFloat64(tUsage) + srtRoute.SortingData[utils.ResourceUsageStr] = tUsage + srtRoute.sortingDataDecimal[utils.ResourceUsageStr] = utils.NewDecimalFromFloat64(tUsage) var pass bool if pass, err = routeLazyPass(ctx, route.lazyCheckRules, ev, srtRoute.SortingData, cfg.FilterSCfg().ResourceSConns, diff --git a/routes/route_resource_sort_test.go b/routes/route_resource_sort_test.go index d647298a1..de57cfd40 100644 --- a/routes/route_resource_sort_test.go +++ b/routes/route_resource_sort_test.go @@ -80,10 +80,10 @@ func TestPopulateResourcesForRoutesOK(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.RouteSCfg().ResourceSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources)} - res := &engine.Resource{ + res := &utils.Resource{ Tenant: "cgrates.org", ID: "RSC1", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), } cc := make(chan birpc.ClientConnector, 1) @@ -91,7 +91,7 @@ func TestPopulateResourcesForRoutesOK(t *testing.T) { calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.ResourceSv1GetResource: func(ctx *context.Context, args, reply any) error { - rplCast, canCast := reply.(*engine.Resource) + rplCast, canCast := reply.(*utils.Resource) if !canCast { t.Errorf("Wrong argument type : %T", reply) return nil @@ -127,9 +127,9 @@ func TestPopulateResourcesForRoutesOK(t *testing.T) { RouteID: "Route1", RouteParameters: "param1", SortingData: map[string]any{ - utils.Blocker: true, - utils.ResourceUsage: 0, - utils.Weight: 10, + utils.Blocker: true, + utils.ResourceUsageStr: 0, + utils.Weight: 10, }, }, } @@ -189,9 +189,9 @@ func TestPopulateResourcesForRoutesCallErr(t *testing.T) { RouteID: "Route1", RouteParameters: "param1", SortingData: map[string]any{ - utils.Blocker: true, - utils.ResourceUsage: 0, - utils.Weight: 10, + utils.Blocker: true, + utils.ResourceUsageStr: 0, + utils.Weight: 10, }, }, } @@ -217,10 +217,10 @@ func TestPopulateResourcesForRoutesLazyPassErr(t *testing.T) { cfg := config.NewDefaultCGRConfig() cfg.RouteSCfg().ResourceSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources)} - res := &engine.Resource{ + res := &utils.Resource{ Tenant: "cgrates.org", ID: "RSC1", - Usages: make(map[string]*engine.ResourceUsage), + Usages: make(map[string]*utils.ResourceUsage), } cc := make(chan birpc.ClientConnector, 1) @@ -228,7 +228,7 @@ func TestPopulateResourcesForRoutesLazyPassErr(t *testing.T) { calls: map[string]func(ctx *context.Context, args any, reply any) error{ utils.ResourceSv1GetResource: func(ctx *context.Context, args, reply any) error { - rplCast, canCast := reply.(*engine.Resource) + rplCast, canCast := reply.(*utils.Resource) if !canCast { t.Errorf("Wrong argument type : %T", reply) return nil diff --git a/services/resources.go b/services/resources.go index f26a7af6a..8ffe51b1a 100644 --- a/services/resources.go +++ b/services/resources.go @@ -24,6 +24,7 @@ import ( "github.com/cgrates/birpc/context" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/resources" "github.com/cgrates/cgrates/servmanager" "github.com/cgrates/cgrates/utils" ) @@ -40,7 +41,7 @@ func NewResourceService(cfg *config.CGRConfig) *ResourceService { type ResourceService struct { mu sync.RWMutex cfg *config.CGRConfig - reS *engine.ResourceS + reS *resources.ResourceS stateDeps *StateDependencies // channel subscriptions for state changes } @@ -72,7 +73,7 @@ func (reS *ResourceService) Start(shutdown *utils.SyncedChan, registry *servmana reS.mu.Lock() defer reS.mu.Unlock() - reS.reS = engine.NewResourceService(dbs.DataManager(), reS.cfg, fs.FilterS(), cms.ConnManager()) + reS.reS = resources.NewResourceService(dbs.DataManager(), reS.cfg, fs.FilterS(), cms.ConnManager()) reS.reS.StartLoop(context.TODO()) srv, _ := engine.NewService(reS.reS) // srv, _ := birpc.NewService(apis.NewResourceSv1(reS.reS), "", false) diff --git a/tpes/tpe_resources.go b/tpes/tpe_resources.go index a8b85bd1f..8567840c5 100644 --- a/tpes/tpe_resources.go +++ b/tpes/tpe_resources.go @@ -49,7 +49,7 @@ func (tpRes TPResources) exportItems(ctx *context.Context, wrtr io.Writer, tnt s return } for _, resID := range itmIDs { - var resPrf *engine.ResourceProfile + var resPrf *utils.ResourceProfile resPrf, err = tpRes.dm.GetResourceProfile(ctx, tnt, resID, true, true, utils.NonTransactional) if err != nil { if err.Error() == utils.ErrNotFound.Error() { diff --git a/tpes/tpe_resources_test.go b/tpes/tpe_resources_test.go index 4ed17063c..2da723ed8 100644 --- a/tpes/tpe_resources_test.go +++ b/tpes/tpe_resources_test.go @@ -34,8 +34,8 @@ func TestTPEnewTPResources(t *testing.T) { cfg := config.NewDefaultCGRConfig() connMng := engine.NewConnManager(cfg) dm := engine.NewDataManager(&engine.DataDBMock{ - GetResourceProfileDrvF: func(ctx *context.Context, tnt string, id string) (*engine.ResourceProfile, error) { - rsc := &engine.ResourceProfile{ + GetResourceProfileDrvF: func(ctx *context.Context, tnt string, id string) (*utils.ResourceProfile, error) { + rsc := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -67,7 +67,7 @@ func TestTPEExportItemsResources(t *testing.T) { tpRsc := TPResources{ dm: dm, } - rsc := &engine.ResourceProfile{ + rsc := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -92,7 +92,7 @@ func TestTPEExportItemsResourcesNoDbConn(t *testing.T) { tpRsc := TPResources{ dm: nil, } - rsc := &engine.ResourceProfile{ + rsc := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -119,7 +119,7 @@ func TestTPEExportItemsResourcesIDNotFound(t *testing.T) { tpRsc := TPResources{ dm: dm, } - rsc := &engine.ResourceProfile{ + rsc := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, diff --git a/tpes/tpes_test.go b/tpes/tpes_test.go index 4112253e5..b706caa56 100644 --- a/tpes/tpes_test.go +++ b/tpes/tpes_test.go @@ -240,7 +240,7 @@ func TestGetTariffPlansKeys(t *testing.T) { } // Resources - rsc := &engine.ResourceProfile{ + rsc := &utils.ResourceProfile{ Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001"}, diff --git a/utils/consts.go b/utils/consts.go index df48e2c4c..23cca92db 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -406,7 +406,7 @@ const ( RatingPlans = "RatingPlans" RatingProfiles = "RatingProfiles" AccountActions = "AccountActions" - Resources = "Resources" + ResourcesStr = "Resources" Stats = "Stats" Rankings = "Rankings" Trends = "Trends" @@ -484,7 +484,7 @@ const ( SessionSCosts = "SessionSCosts" RQF = "RQF" - Resource = "Resource" + ResourceStr = "Resource" User = "User" Subscribers = "Subscribers" //Destinations = "Destinations" @@ -663,7 +663,7 @@ const ( CGRDebitInterval = "CGRDebitInterval" VersionName = "Version" MetaTenant = "*tenant" - ResourceUsage = "ResourceUsage" + ResourceUsageStr = "ResourceUsage" MetaDuration = "*duration" MetaLibPhoneNumber = "*libphonenumber" MetaTimeString = "*time_string" diff --git a/utils/resources.go b/utils/resources.go new file mode 100644 index 000000000..fc6570529 --- /dev/null +++ b/utils/resources.go @@ -0,0 +1,242 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package utils + +import ( + "time" +) + +// ResourceProfile represents the user configuration for the resource +type ResourceProfile struct { + Tenant string + ID string // identifier of this resource + FilterIDs []string + UsageTTL time.Duration // auto-expire the usage after this duration + Limit float64 // limixt value + AllocationMessage string // message returned by the winning resource on allocation + Blocker bool // blocker flag to stop processing on filters matched + Stored bool + Weights DynamicWeights // Weight to sort the resources + ThresholdIDs []string // Thresholds to check after changing Limit +} + +// ResourceProfileWithAPIOpts is used in replicatorV1 for dispatcher +type ResourceProfileWithAPIOpts struct { + *ResourceProfile + APIOpts map[string]any +} + +// TenantID returns unique identifier of the ResourceProfile in a multi-tenant environment +func (rp *ResourceProfile) TenantID() string { + return ConcatenatedKey(rp.Tenant, rp.ID) +} + +// ResourceUsage represents an usage counted +type ResourceUsage struct { + Tenant string + ID string // Unique identifier of this ResourceUsage, Eg: FreeSWITCH UUID + ExpiryTime time.Time + Units float64 // Number of units used +} + +// TenantID returns the concatenated key between tenant and ID +func (ru *ResourceUsage) TenantID() string { + return ConcatenatedKey(ru.Tenant, ru.ID) +} + +// isActive checks ExpiryTime at some time +func (ru *ResourceUsage) IsActive(atTime time.Time) bool { + return ru.ExpiryTime.IsZero() || ru.ExpiryTime.Sub(atTime) > 0 +} + +// Clone duplicates ru +func (ru *ResourceUsage) Clone() (cln *ResourceUsage) { + cln = new(ResourceUsage) + *cln = *ru + return +} + +// Resource represents a resource in the system +// not thread safe, needs locking at process level +type Resource struct { + Tenant string + ID string + Usages map[string]*ResourceUsage + TTLIdx []string // holds ordered list of ResourceIDs based on their TTL, empty if feature is disableda +} + +// ResourceWithAPIOpts is used in replicatorV1 for dispatcher +type ResourceWithAPIOpts struct { + *Resource + APIOpts map[string]any +} + +// TenantID returns the unique ID in a multi-tenant environment +func (r *Resource) TenantID() string { + return ConcatenatedKey(r.Tenant, r.ID) +} + +// TotalUsage returns the sum of all usage units +// Exported to be used in FilterS +func (r *Resource) TotalUsage() float64 { + var tu float64 + for _, ru := range r.Usages { + tu += ru.Units + } + return tu +} + +// Available returns the available number of units +// Exported method to be used by filterS +func (r *ResourceWithConfig) Available() float64 { + return r.Config.Limit - r.TotalUsage() +} + +type ResourceWithConfig struct { + *Resource + Config *ResourceProfile +} + +func (rp *ResourceProfile) Set(path []string, val any, _ bool) (err error) { + if len(path) != 1 { + return ErrWrongPath + } + switch path[0] { + default: + return ErrWrongPath + case Tenant: + rp.Tenant = IfaceAsString(val) + case ID: + rp.ID = IfaceAsString(val) + case FilterIDs: + var valA []string + valA, err = IfaceAsStringSlice(val) + rp.FilterIDs = append(rp.FilterIDs, valA...) + case UsageTTL: + rp.UsageTTL, err = IfaceAsDuration(val) + case Limit: + if val != EmptyString { + rp.Limit, err = IfaceAsFloat64(val) + } + case AllocationMessage: + rp.AllocationMessage = IfaceAsString(val) + case Blocker: + rp.Blocker, err = IfaceAsBool(val) + case Stored: + rp.Stored, err = IfaceAsBool(val) + case Weights: + if val != EmptyString { + rp.Weights, err = NewDynamicWeightsFromString(IfaceAsString(val), InfieldSep, ANDSep) + } + case ThresholdIDs: + var valA []string + valA, err = IfaceAsStringSlice(val) + rp.ThresholdIDs = append(rp.ThresholdIDs, valA...) + } + return +} + +func (rp *ResourceProfile) Merge(v2 any) { + vi := v2.(*ResourceProfile) + if len(vi.Tenant) != 0 { + rp.Tenant = vi.Tenant + } + if len(vi.ID) != 0 { + rp.ID = vi.ID + } + rp.FilterIDs = append(rp.FilterIDs, vi.FilterIDs...) + rp.ThresholdIDs = append(rp.ThresholdIDs, vi.ThresholdIDs...) + if len(vi.AllocationMessage) != 0 { + rp.AllocationMessage = vi.AllocationMessage + } + if vi.UsageTTL != 0 { + rp.UsageTTL = vi.UsageTTL + } + if vi.Limit != 0 { + rp.Limit = vi.Limit + } + if vi.Blocker { + rp.Blocker = vi.Blocker + } + if vi.Stored { + rp.Stored = vi.Stored + } + rp.Weights = append(rp.Weights, vi.Weights...) +} + +func (rp *ResourceProfile) String() string { return ToJSON(rp) } +func (rp *ResourceProfile) FieldAsString(fldPath []string) (_ string, err error) { + var val any + if val, err = rp.FieldAsInterface(fldPath); err != nil { + return + } + return IfaceAsString(val), nil +} +func (rp *ResourceProfile) FieldAsInterface(fldPath []string) (_ any, err error) { + if len(fldPath) != 1 { + return nil, ErrNotFound + } + switch fldPath[0] { + default: + fld, idx := GetPathIndex(fldPath[0]) + if idx != nil { + switch fld { + case ThresholdIDs: + if *idx < len(rp.ThresholdIDs) { + return rp.ThresholdIDs[*idx], nil + } + case FilterIDs: + if *idx < len(rp.FilterIDs) { + return rp.FilterIDs[*idx], nil + } + } + } + return nil, ErrNotFound + case Tenant: + return rp.Tenant, nil + case ID: + return rp.ID, nil + case FilterIDs: + return rp.FilterIDs, nil + case UsageTTL: + return rp.UsageTTL, nil + case Limit: + return rp.Limit, nil + case AllocationMessage: + return rp.AllocationMessage, nil + case Blocker: + return rp.Blocker, nil + case Stored: + return rp.Stored, nil + case Weights: + return rp.Weights, nil + case ThresholdIDs: + return rp.ThresholdIDs, nil + } +} + +// ResourceProfileLockKey returns the ID used to lock a resourceProfile with guardian +func ResourceProfileLockKey(tnt, id string) string { + return ConcatenatedKey(CacheResourceProfiles, tnt, id) +} + +// ResourceLockKey returns the ID used to lock a resource with guardian +func ResourceLockKey(tnt, id string) string { + return ConcatenatedKey(CacheResources, tnt, id) +} diff --git a/utils/resources_test.go b/utils/resources_test.go new file mode 100644 index 000000000..34e6f6ffc --- /dev/null +++ b/utils/resources_test.go @@ -0,0 +1,391 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ +package utils + +import ( + "reflect" + "testing" + "time" +) + +func TestResourceProfileTenantID(t *testing.T) { + testStruct := ResourceProfile{ + Tenant: "test_tenant", + ID: "test_id", + } + result := testStruct.TenantID() + expected := ConcatenatedKey(testStruct.Tenant, testStruct.ID) + if !reflect.DeepEqual(expected, result) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", expected, result) + } +} + +func TestResourceUsageTenantID(t *testing.T) { + testStruct := ResourceUsage{ + Tenant: "test_tenant", + ID: "test_id", + } + result := testStruct.TenantID() + expected := ConcatenatedKey(testStruct.Tenant, testStruct.ID) + if !reflect.DeepEqual(expected, result) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", expected, result) + } +} + +func TestResourceUsageIsActive(t *testing.T) { + testStruct := ResourceUsage{ + Tenant: "test_tenant", + ID: "test_id", + ExpiryTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC), + } + result := testStruct.IsActive(time.Date(2014, 1, 13, 0, 0, 0, 0, time.UTC)) + if !reflect.DeepEqual(true, result) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", true, result) + } +} + +func TestResourceUsageIsActiveFalse(t *testing.T) { + testStruct := ResourceUsage{ + Tenant: "test_tenant", + ID: "test_id", + ExpiryTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC), + } + result := testStruct.IsActive(time.Date(2014, 1, 15, 0, 0, 0, 0, time.UTC)) + if !reflect.DeepEqual(false, result) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", false, result) + } +} + +func TestResourceUsageClone(t *testing.T) { + testStruct := &ResourceUsage{ + Tenant: "test_tenant", + ID: "test_id", + ExpiryTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC), + } + result := testStruct.Clone() + if !reflect.DeepEqual(testStruct, result) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct, result) + } + testStruct.Tenant = "test_tenant2" + testStruct.ID = "test_id2" + testStruct.ExpiryTime = time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC) + if reflect.DeepEqual(testStruct.Tenant, result.Tenant) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct.Tenant, result.Tenant) + } + if reflect.DeepEqual(testStruct.ID, result.ID) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct.ID, result.ID) + } + if reflect.DeepEqual(testStruct.ExpiryTime, result.ExpiryTime) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct.ExpiryTime, result.ExpiryTime) + } +} + +func TestResourceTenantID(t *testing.T) { + testStruct := Resource{ + Tenant: "test_tenant", + } + result := testStruct.TenantID() + if reflect.DeepEqual(testStruct.Tenant, result) { + t.Errorf("\nExpecting <%+v>,\n Received <%+v>", testStruct.Tenant, result) + } +} + +func TestResourceTotalUsage1(t *testing.T) { + testStruct := Resource{ + Tenant: "test_tenant", + ID: "test_id", + Usages: map[string]*ResourceUsage{ + "0": { + Tenant: "test_tenant2", + ID: "test_id2", + ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 1, + }, + "1": { + Tenant: "test_tenant3", + ID: "test_id3", + ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 2, + }, + }, + } + result := testStruct.TotalUsage() + if reflect.DeepEqual(3, result) { + t.Errorf("\nExpecting <3>,\n Received <%+v>", result) + } +} + +func TestResourceTotalUsage2(t *testing.T) { + testStruct := Resource{ + Tenant: "test_tenant", + ID: "test_id", + Usages: map[string]*ResourceUsage{ + "0": { + Tenant: "test_tenant2", + ID: "test_id2", + ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 1, + }, + "1": { + Tenant: "test_tenant3", + ID: "test_id3", + ExpiryTime: time.Date(2015, 1, 14, 0, 0, 0, 0, time.UTC), + Units: 2, + }, + }, + } + result := testStruct.TotalUsage() + if reflect.DeepEqual(3, result) { + t.Errorf("\nExpecting <3>,\n Received <%+v>", result) + } +} + +func TestResourcesAvailable(t *testing.T) { + r := ResourceWithConfig{ + Resource: &Resource{ + Usages: map[string]*ResourceUsage{ + "RU_1": { + Units: 4, + }, + "RU_2": { + Units: 7, + }, + }, + }, + Config: &ResourceProfile{ + Limit: 10, + }, + } + + exp := -1.0 + rcv := r.Available() + + if rcv != exp { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp, rcv) + } +} + +type mockWriter struct { + WriteF func(p []byte) (n int, err error) +} + +func (mW *mockWriter) Write(p []byte) (n int, err error) { + if mW.WriteF != nil { + return mW.WriteF(p) + } + return 0, nil +} + +func TestResourceProfileSet(t *testing.T) { + cp := ResourceProfile{} + exp := ResourceProfile{ + Tenant: "cgrates.org", + ID: "ID", + FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, + Weights: DynamicWeights{ + { + Weight: 10, + }}, + UsageTTL: 10, + Limit: 10, + AllocationMessage: "new", + Blocker: true, + Stored: true, + ThresholdIDs: []string{"TH1"}, + } + if err := cp.Set([]string{}, "", false); err != ErrWrongPath { + t.Error(err) + } + if err := cp.Set([]string{"NotAField"}, "", false); err != ErrWrongPath { + t.Error(err) + } + if err := cp.Set([]string{"NotAField", "1"}, "", false); err != ErrWrongPath { + t.Error(err) + } + + if err := cp.Set([]string{Tenant}, "cgrates.org", false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{ID}, "ID", false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{FilterIDs}, "fltr1;*string:~*req.Account:1001", false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{Weights}, ";10", false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{UsageTTL}, 10, false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{Limit}, 10, false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{AllocationMessage}, "new", false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{Blocker}, true, false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{Stored}, true, false); err != nil { + t.Error(err) + } + if err := cp.Set([]string{ThresholdIDs}, "TH1", false); err != nil { + t.Error(err) + } + + if !reflect.DeepEqual(exp, cp) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(cp)) + } +} + +func TestResourceProfileAsInterface(t *testing.T) { + rp := ResourceProfile{ + Tenant: "cgrates.org", + ID: "ID", + FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, + Weights: DynamicWeights{ + { + Weight: 10, + }}, + UsageTTL: 10, + Limit: 10, + AllocationMessage: "new", + Blocker: true, + Stored: true, + ThresholdIDs: []string{"TH1"}, + } + if _, err := rp.FieldAsInterface(nil); err != ErrNotFound { + t.Fatal(err) + } + if _, err := rp.FieldAsInterface([]string{"field"}); err != ErrNotFound { + t.Fatal(err) + } + if _, err := rp.FieldAsInterface([]string{"field", ""}); err != ErrNotFound { + t.Fatal(err) + } + if val, err := rp.FieldAsInterface([]string{Tenant}); err != nil { + t.Fatal(err) + } else if exp := "cgrates.org"; exp != val { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{ID}); err != nil { + t.Fatal(err) + } else if exp := ID; exp != val { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{FilterIDs}); err != nil { + t.Fatal(err) + } else if exp := rp.FilterIDs; !reflect.DeepEqual(exp, val) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{FilterIDs + "[0]"}); err != nil { + t.Fatal(err) + } else if exp := rp.FilterIDs[0]; exp != val { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{Weights}); err != nil { + t.Fatal(err) + } else if exp := rp.Weights; !reflect.DeepEqual(exp, val) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{ThresholdIDs}); err != nil { + t.Fatal(err) + } else if exp := rp.ThresholdIDs; !reflect.DeepEqual(exp, val) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{ThresholdIDs + "[0]"}); err != nil { + t.Fatal(err) + } else if exp := rp.ThresholdIDs[0]; exp != val { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + + if val, err := rp.FieldAsInterface([]string{UsageTTL}); err != nil { + t.Fatal(err) + } else if exp := rp.UsageTTL; !reflect.DeepEqual(exp, val) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{Limit}); err != nil { + t.Fatal(err) + } else if exp := rp.Limit; !reflect.DeepEqual(exp, val) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{AllocationMessage}); err != nil { + t.Fatal(err) + } else if exp := rp.AllocationMessage; !reflect.DeepEqual(exp, val) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{Blocker}); err != nil { + t.Fatal(err) + } else if exp := rp.Blocker; !reflect.DeepEqual(exp, val) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, err := rp.FieldAsInterface([]string{Stored}); err != nil { + t.Fatal(err) + } else if exp := rp.Stored; !reflect.DeepEqual(exp, val) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + + if _, err := rp.FieldAsString([]string{""}); err != ErrNotFound { + t.Fatal(err) + } + if val, err := rp.FieldAsString([]string{ID}); err != nil { + t.Fatal(err) + } else if exp := "ID"; exp != val { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } + if val, exp := rp.String(), ToJSON(rp); exp != val { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(val)) + } +} + +func TestResourceProfileMerge(t *testing.T) { + dp := &ResourceProfile{} + exp := &ResourceProfile{ + Tenant: "cgrates.org", + ID: "ID", + FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, + Weights: DynamicWeights{ + { + Weight: 10, + }}, + UsageTTL: 10, + Limit: 10, + AllocationMessage: "new", + Blocker: true, + Stored: true, + ThresholdIDs: []string{"TH1"}, + } + if dp.Merge(&ResourceProfile{ + Tenant: "cgrates.org", + ID: "ID", + FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, + Weights: DynamicWeights{ + { + Weight: 10, + }}, + UsageTTL: 10, + Limit: 10, + AllocationMessage: "new", + Blocker: true, + Stored: true, + ThresholdIDs: []string{"TH1"}, + }); !reflect.DeepEqual(exp, dp) { + t.Errorf("Expected %v \n but received \n %v", ToJSON(exp), ToJSON(dp)) + } +}