diff --git a/apier/v1/filter_indexes_it_test.go b/apier/v1/filter_indexes_it_test.go index 361b71aa0..a17ef85f4 100644 --- a/apier/v1/filter_indexes_it_test.go +++ b/apier/v1/filter_indexes_it_test.go @@ -714,21 +714,23 @@ func testV1FIdxSetResourceProfileIndexes(t *testing.T) { &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Error(err) } - rlsConfig = &engine.ResourceProfile{ - Tenant: tenant, - ID: "RCFG1", - FilterIDs: []string{"FLTR_RES_RCFG1"}, - ActivationInterval: &utils.ActivationInterval{ - ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), - ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + rlsConfig = &ResourceWrapper{ + ResourceProfile: &engine.ResourceProfile{ + Tenant: tenant, + ID: "RCFG1", + FilterIDs: []string{"FLTR_RES_RCFG1"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + UsageTTL: time.Duration(10) * time.Microsecond, + Limit: 10, + AllocationMessage: "MessageAllocation", + Blocker: true, + Stored: true, + Weight: 20, + ThresholdIDs: []string{"Val1", "Val2"}, }, - UsageTTL: time.Duration(10) * time.Microsecond, - Limit: 10, - AllocationMessage: "MessageAllocation", - Blocker: true, - Stored: true, - Weight: 20, - ThresholdIDs: []string{"Val1", "Val2"}, } if err := tFIdxRpc.Call("ApierV1.SetFilter", filter, &result); err != nil { t.Error(err) @@ -809,21 +811,23 @@ func testV1FIdxSetSecondResourceProfileIndexes(t *testing.T) { &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Error(err) } - rlsConfig = &engine.ResourceProfile{ - Tenant: tenant, - ID: "RCFG2", - FilterIDs: []string{"FLTR_2"}, - ActivationInterval: &utils.ActivationInterval{ - ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), - ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + rlsConfig = &ResourceWrapper{ + ResourceProfile: &engine.ResourceProfile{ + Tenant: tenant, + ID: "RCFG2", + FilterIDs: []string{"FLTR_2"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + UsageTTL: time.Duration(10) * time.Microsecond, + Limit: 10, + AllocationMessage: "MessageAllocation", + Blocker: true, + Stored: true, + Weight: 20, + ThresholdIDs: []string{"Val1", "Val2"}, }, - UsageTTL: time.Duration(10) * time.Microsecond, - Limit: 10, - AllocationMessage: "MessageAllocation", - Blocker: true, - Stored: true, - Weight: 20, - ThresholdIDs: []string{"Val1", "Val2"}, } if err := tFIdxRpc.Call("ApierV1.SetFilter", filter, &result); err != nil { t.Error(err) diff --git a/apier/v1/filterindexecache_it_test.go b/apier/v1/filterindexecache_it_test.go index c32bd0941..bee538f63 100644 --- a/apier/v1/filterindexecache_it_test.go +++ b/apier/v1/filterindexecache_it_test.go @@ -1175,20 +1175,22 @@ func testV1FIdxCaSetResourceProfile(t *testing.T) { } else if result != utils.OK { t.Error("Unexpected reply returned", result) } - rlsConfig = &engine.ResourceProfile{ - Tenant: "cgrates.org", - ID: "RCFG1", - FilterIDs: []string{"FLTR_RES_RCFG1"}, - ActivationInterval: &utils.ActivationInterval{ - ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + rlsConfig = &ResourceWrapper{ + ResourceProfile: &engine.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RCFG1", + FilterIDs: []string{"FLTR_RES_RCFG1"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + UsageTTL: time.Duration(0) * time.Microsecond, + AllocationMessage: "Approved", + Limit: 10, + Blocker: true, + Stored: true, + Weight: 20, + ThresholdIDs: []string{"Val1", "Val2"}, }, - UsageTTL: time.Duration(0) * time.Microsecond, - AllocationMessage: "Approved", - Limit: 10, - Blocker: true, - Stored: true, - Weight: 20, - ThresholdIDs: []string{"Val1", "Val2"}, } if err := tFIdxCaRpc.Call("ApierV1.SetResourceProfile", rlsConfig, &result); err != nil { t.Error(err) @@ -1297,20 +1299,22 @@ func testV1FIdxCaUpdateResourceProfile(t *testing.T) { } else if result != utils.OK { t.Error("Unexpected reply returned", result) } - rlsConfig = &engine.ResourceProfile{ - Tenant: "cgrates.org", - ID: "RCFG1", - FilterIDs: []string{"FLTR_RES_RCFG2"}, - ActivationInterval: &utils.ActivationInterval{ - ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + rlsConfig = &ResourceWrapper{ + ResourceProfile: &engine.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RCFG1", + FilterIDs: []string{"FLTR_RES_RCFG2"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + UsageTTL: time.Duration(10) * time.Microsecond, + Limit: 10, + AllocationMessage: "MessageAllocation", + Blocker: true, + Stored: true, + Weight: 20, + ThresholdIDs: []string{"Val1", "Val2"}, }, - UsageTTL: time.Duration(10) * time.Microsecond, - Limit: 10, - AllocationMessage: "MessageAllocation", - Blocker: true, - Stored: true, - Weight: 20, - ThresholdIDs: []string{"Val1", "Val2"}, } if err := tFIdxCaRpc.Call("ApierV1.SetResourceProfile", rlsConfig, &result); err != nil { diff --git a/apier/v1/resourcesv1.go b/apier/v1/resourcesv1.go index 5b20c4503..44d913f6c 100644 --- a/apier/v1/resourcesv1.go +++ b/apier/v1/resourcesv1.go @@ -107,35 +107,72 @@ func (apierV1 *ApierV1) GetResourceProfileIDs(tenant string, rsPrfIDs *[]string) return nil } +type ResourceWrapper struct { + *engine.ResourceProfile + Cache *string +} + //SetResourceProfile add a new resource configuration -func (apierV1 *ApierV1) SetResourceProfile(res *engine.ResourceProfile, reply *string) error { - if missing := utils.MissingStructFields(res, []string{"Tenant", "ID"}); len(missing) != 0 { +func (apierV1 *ApierV1) SetResourceProfile(arg *ResourceWrapper, reply *string) error { + if missing := utils.MissingStructFields(arg.ResourceProfile, []string{"Tenant", "ID"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } - if err := apierV1.DataManager.SetResourceProfile(res, true); err != nil { + if err := apierV1.DataManager.SetResourceProfile(arg.ResourceProfile, true); err != nil { + return utils.APIErrorHandler(err) + } + //handle caching for ResourceProfile + argCache := engine.ArgsGetCacheItem{ + CacheID: utils.CacheResourceProfiles, + ItemID: arg.TenantID(), + } + if err := apierV1.CallCache(GetCacheOpt(arg.Cache), argCache); err != nil { return utils.APIErrorHandler(err) } if err := apierV1.DataManager.SetResource( - &engine.Resource{Tenant: res.Tenant, - ID: res.ID, + &engine.Resource{Tenant: arg.Tenant, + ID: arg.ID, Usages: make(map[string]*engine.ResourceUsage)}); err != nil { return utils.APIErrorHandler(err) } + //handle caching for Resource + argCache = engine.ArgsGetCacheItem{ + CacheID: utils.CacheResources, + ItemID: arg.TenantID(), + } + if err := apierV1.CallCache(GetCacheOpt(arg.Cache), argCache); err != nil { + return utils.APIErrorHandler(err) + } *reply = utils.OK return nil } //RemoveResourceProfile remove a specific resource configuration -func (apierV1 *ApierV1) RemoveResourceProfile(arg utils.TenantID, reply *string) error { +func (apierV1 *ApierV1) RemoveResourceProfile(arg utils.TenantIDWrapper, reply *string) error { if missing := utils.MissingStructFields(&arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } if err := apierV1.DataManager.RemoveResourceProfile(arg.Tenant, arg.ID, utils.NonTransactional, true); err != nil { return utils.APIErrorHandler(err) } + //handle caching for ResourceProfile + argCache := engine.ArgsGetCacheItem{ + CacheID: utils.CacheResourceProfiles, + ItemID: arg.TenantID(), + } + if err := apierV1.CallCache(GetCacheOpt(arg.Cache), argCache); err != nil { + return utils.APIErrorHandler(err) + } if err := apierV1.DataManager.RemoveResource(arg.Tenant, arg.ID, utils.NonTransactional); err != nil { return utils.APIErrorHandler(err) } + //handle caching for Resource + argCache = engine.ArgsGetCacheItem{ + CacheID: utils.CacheResources, + ItemID: arg.TenantID(), + } + if err := apierV1.CallCache(GetCacheOpt(arg.Cache), argCache); err != nil { + return utils.APIErrorHandler(err) + } *reply = utils.OK return nil } diff --git a/apier/v1/resourcesv1_it_test.go b/apier/v1/resourcesv1_it_test.go index 69abda0e5..82854fe0b 100644 --- a/apier/v1/resourcesv1_it_test.go +++ b/apier/v1/resourcesv1_it_test.go @@ -37,7 +37,7 @@ var ( rlsV1Cfg *config.CGRConfig rlsV1Rpc *rpc.Client rlsV1ConfDIR string //run tests for specific configuration - rlsConfig *engine.ResourceProfile + rlsConfig *ResourceWrapper ) var sTestsRLSV1 = []func(t *testing.T){ @@ -589,22 +589,25 @@ func testV1RsGetResourceProfileBeforeSet(t *testing.T) { } func testV1RsSetResourceProfile(t *testing.T) { - rlsConfig = &engine.ResourceProfile{ - Tenant: "cgrates.org", - ID: "RES_GR_TEST", - FilterIDs: []string{"*string:Account:1001"}, - ActivationInterval: &utils.ActivationInterval{ - ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), - ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + rlsConfig = &ResourceWrapper{ + ResourceProfile: &engine.ResourceProfile{ + Tenant: "cgrates.org", + ID: "RES_GR_TEST", + FilterIDs: []string{"*string:Account:1001"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + UsageTTL: time.Duration(1) * time.Nanosecond, + Limit: 10, + AllocationMessage: "MessageAllocation", + Blocker: true, + Stored: true, + Weight: 20, + ThresholdIDs: []string{"Val1"}, }, - UsageTTL: time.Duration(1) * time.Nanosecond, - Limit: 10, - AllocationMessage: "MessageAllocation", - Blocker: true, - Stored: true, - Weight: 20, - ThresholdIDs: []string{"Val1"}, } + var result string if err := rlsV1Rpc.Call("ApierV1.SetResourceProfile", rlsConfig, &result); err != nil { @@ -629,8 +632,8 @@ func testV1RsGetResourceProfileAfterSet(t *testing.T) { if err := rlsV1Rpc.Call("ApierV1.GetResourceProfile", &utils.TenantID{Tenant: "cgrates.org", ID: rlsConfig.ID}, &reply); err != nil { t.Error(err) - } else if !reflect.DeepEqual(reply, rlsConfig) { - t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(rlsConfig), utils.ToJSON(reply)) + } else if !reflect.DeepEqual(reply, rlsConfig.ResourceProfile) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(rlsConfig.ResourceProfile), utils.ToJSON(reply)) } } @@ -649,8 +652,8 @@ func testV1RsGetResourceProfileAfterUpdate(t *testing.T) { if err := rlsV1Rpc.Call("ApierV1.GetResourceProfile", &utils.TenantID{Tenant: "cgrates.org", ID: rlsConfig.ID}, &reply); err != nil { t.Error(err) - } else if !reflect.DeepEqual(reply, rlsConfig) { - t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(rlsConfig), utils.ToJSON(reply)) + } else if !reflect.DeepEqual(reply, rlsConfig.ResourceProfile) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(rlsConfig.ResourceProfile), utils.ToJSON(reply)) } } diff --git a/engine/datamanager.go b/engine/datamanager.go index fe3fc0b49..7b02569c6 100644 --- a/engine/datamanager.go +++ b/engine/datamanager.go @@ -645,11 +645,6 @@ func (dm *DataManager) SetResource(rs *Resource) (err error) { if err = dm.DataDB().SetResourceDrv(rs); err != nil { return } - if err = dm.CacheDataFromDB( - utils.CacheInstanceToPrefix[utils.CacheResources], - []string{rs.TenantID()}, true); err != nil { - return - } return } @@ -657,8 +652,6 @@ func (dm *DataManager) RemoveResource(tenant, id, transactionID string) (err err if err = dm.DataDB().RemoveResourceDrv(tenant, id); err != nil { return } - Cache.Remove(utils.CacheResources, utils.ConcatenatedKey(tenant, id), - cacheCommit(transactionID), transactionID) return } @@ -696,11 +689,6 @@ func (dm *DataManager) SetResourceProfile(rp *ResourceProfile, withIndex bool) ( if err = dm.DataDB().SetResourceProfileDrv(rp); err != nil { return err } - if err = dm.CacheDataFromDB(utils.ResourceProfilesPrefix, - []string{rp.TenantID()}, true); err != nil { - return - } - //to be implemented in tests if withIndex { if oldRes != nil { var needsRemove bool @@ -732,8 +720,6 @@ func (dm *DataManager) RemoveResourceProfile(tenant, id, transactionID string, w if err = dm.DataDB().RemoveResourceProfileDrv(tenant, id); err != nil { return } - Cache.Remove(utils.CacheResourceProfiles, utils.ConcatenatedKey(tenant, id), - cacheCommit(transactionID), transactionID) if oldRes == nil { return utils.ErrNotFound } diff --git a/engine/onstor_it_test.go b/engine/onstor_it_test.go index 51d35ecde..431b5ad87 100644 --- a/engine/onstor_it_test.go +++ b/engine/onstor_it_test.go @@ -1151,13 +1151,6 @@ func testOnStorITResourceProfile(t *testing.T) { if err := onStor.SetResourceProfile(rL, false); err != nil { t.Error(err) } - //get from cache - if rcv, err := onStor.GetResourceProfile(rL.Tenant, rL.ID, - true, false, utils.NonTransactional); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rL, rcv) { - t.Errorf("Expecting: %v, received: %v", utils.ToJSON(rL), utils.ToJSON(rcv)) - } //get from database if rcv, err := onStor.GetResourceProfile(rL.Tenant, rL.ID, false, true, utils.NonTransactional); err != nil { @@ -1178,13 +1171,6 @@ func testOnStorITResourceProfile(t *testing.T) { t.Error(err) } time.Sleep(sleepDelay) - //get from cache - if rcv, err := onStor.GetResourceProfile(rL.Tenant, rL.ID, - true, false, utils.NonTransactional); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rL, rcv) { - t.Errorf("Expecting: %v, received: %v", utils.ToJSON(rL), utils.ToJSON(rcv)) - } //get from database if rcv, err := onStor.GetResourceProfile(rL.Tenant, rL.ID, false, false, utils.NonTransactional); err != nil { @@ -1197,11 +1183,6 @@ func testOnStorITResourceProfile(t *testing.T) { utils.NonTransactional, false); err != nil { t.Error(err) } - //check cache if removed - if _, rcvErr := onStor.GetResourceProfile(rL.Tenant, rL.ID, - true, false, utils.NonTransactional); rcvErr != utils.ErrNotFound { - t.Error(rcvErr) - } //check database if removed if _, rcvErr := onStor.GetResourceProfile(rL.Tenant, rL.ID, false, false, utils.NonTransactional); rcvErr != utils.ErrNotFound { @@ -1229,14 +1210,6 @@ func testOnStorITResource(t *testing.T) { if err := onStor.SetResource(res); err != nil { t.Error(err) } - //get from cache - if rcv, err := onStor.GetResource("cgrates.org", "RL1", - true, false, utils.NonTransactional); err != nil { - t.Error(err) - } else if !(reflect.DeepEqual(res, rcv)) { - t.Errorf("Expecting: %v, received: %v", utils.ToJSON(res), utils.ToJSON(rcv)) - } - //get from database if rcv, err := onStor.GetResource("cgrates.org", "RL1", false, false, utils.NonTransactional); err != nil { @@ -1256,13 +1229,6 @@ func testOnStorITResource(t *testing.T) { t.Error(err) } time.Sleep(sleepDelay) - //get from cache - if rcv, err := onStor.GetResource("cgrates.org", "RL1", - true, false, utils.NonTransactional); err != nil { - t.Error(err) - } else if !(reflect.DeepEqual(res, rcv)) { - t.Errorf("Expecting: %v, received: %v", utils.ToJSON(res), utils.ToJSON(rcv)) - } //get from database if rcv, err := onStor.GetResource("cgrates.org", "RL1", false, false, utils.NonTransactional); err != nil { @@ -1274,11 +1240,6 @@ func testOnStorITResource(t *testing.T) { if err := onStor.RemoveResource(res.Tenant, res.ID, utils.NonTransactional); err != nil { t.Error(err) } - //check cache if removed - if _, rcvErr := onStor.GetResource(res.Tenant, res.ID, - true, false, utils.NonTransactional); rcvErr != utils.ErrNotFound { - t.Error(rcvErr) - } //check database if removed if _, rcvErr := onStor.GetResource(res.Tenant, res.ID, false, false, utils.NonTransactional); rcvErr != utils.ErrNotFound { diff --git a/engine/resources.go b/engine/resources.go index 2cf1453c5..b613a3796 100644 --- a/engine/resources.go +++ b/engine/resources.go @@ -341,9 +341,15 @@ func (rS *ResourceService) StoreResource(r *Resource) (err error) { fmt.Sprintf(" failed saving Resource with ID: %s, error: %s", r.ID, err.Error())) return - } else { - *r.dirty = false } + //since we no longer handle cache in DataManager do here a manul caching + if err = rS.dm.CacheDataFromDB(utils.ResourcesPrefix, []string{r.TenantID()}, true); err != nil { + utils.Logger.Warning( + fmt.Sprintf(" failed caching Resource with ID: %s, error: %s", + r.TenantID(), err.Error())) + return + } + *r.dirty = false return } diff --git a/engine/resources_test.go b/engine/resources_test.go index 2a30203b0..9abeb03b4 100644 --- a/engine/resources_test.go +++ b/engine/resources_test.go @@ -582,6 +582,7 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { //UsageTTL 0 in ResourceProfile and give 10s duration func TestResourceUsageTTLCase1(t *testing.T) { + Cache.Clear(nil) resprf[0].UsageTTL = time.Duration(0) resourceTest[0].rPrf = resprf[0] resourceTest[0].ttl = &timeDurationExample @@ -608,6 +609,7 @@ func TestResourceUsageTTLCase1(t *testing.T) { //UsageTTL 5s in ResourceProfile and give nil duration func TestResourceUsageTTLCase2(t *testing.T) { + Cache.Clear(nil) resprf[0].UsageTTL = time.Duration(0) resourceTest[0].rPrf = resprf[0] resourceTest[0].ttl = &resprf[0].UsageTTL @@ -634,6 +636,7 @@ func TestResourceUsageTTLCase2(t *testing.T) { //UsageTTL 5s in ResourceProfile and give 0 duration func TestResourceUsageTTLCase3(t *testing.T) { + Cache.Clear(nil) resprf[0].UsageTTL = time.Duration(0) resourceTest[0].rPrf = resprf[0] resourceTest[0].ttl = nil @@ -660,6 +663,7 @@ func TestResourceUsageTTLCase3(t *testing.T) { //UsageTTL 5s in ResourceProfile and give 10s duration func TestResourceUsageTTLCase4(t *testing.T) { + Cache.Clear(nil) resprf[0].UsageTTL = time.Duration(5) resourceTest[0].rPrf = resprf[0] resourceTest[0].ttl = &timeDurationExample @@ -685,6 +689,7 @@ func TestResourceUsageTTLCase4(t *testing.T) { } func TestResourceMatchWithIndexFalse(t *testing.T) { + Cache.Clear(nil) resService.filterS.cfg.ResourceSCfg().IndexedSelects = false mres, err := resService.matchingResourcesForEvent(resEvs[0], &timeDurationExample) if err != nil {