Move Caching for Resource

This commit is contained in:
TeoV
2019-03-25 11:01:09 +02:00
committed by Dan Christian Bogos
parent 8718b21f52
commit 3ac9852e2f
8 changed files with 140 additions and 134 deletions

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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))
}
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -341,9 +341,15 @@ func (rS *ResourceService) StoreResource(r *Resource) (err error) {
fmt.Sprintf("<ResourceS> 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("<ResourceS> failed caching Resource with ID: %s, error: %s",
r.TenantID(), err.Error()))
return
}
*r.dirty = false
return
}

View File

@@ -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 {