Responder MaxComputedUsage implementation

This commit is contained in:
DanB
2017-11-02 15:33:31 +01:00
parent 76bc26c726
commit d789cac0b7
6 changed files with 50 additions and 12 deletions

View File

@@ -37,7 +37,7 @@ var (
func init() {
apierDebitStorage, _ = engine.NewMapStorage()
cfg, _ := config.NewDefaultCGRConfig()
responder := new(engine.Responder)
responder := &engine.Responder{MaxComputedUsage: cfg.RALsMaxComputedUsage}
dm = engine.NewDataManager(apierDebitStorage)
engine.SetDataStorage(dm)
apierDebit = &ApierV1{

View File

@@ -229,7 +229,7 @@ func startRater(internalRaterChan chan rpcclient.RpcClientConnection, cacheDoneC
for _, chn := range waitTasks {
<-chn
}
responder := &engine.Responder{ExitChan: exitChan}
responder := &engine.Responder{ExitChan: exitChan, MaxComputedUsage: cfg.RALsMaxComputedUsage}
responder.SetTimeToLive(cfg.ResponseCacheTTL, nil)
apierRpcV1 := &v1.ApierV1{StorDb: loadDb, DataManager: dm, CdrDb: cdrDb,
Config: cfg, Responder: responder, ServManager: serviceManager,

View File

@@ -46,12 +46,13 @@ type AttrGetLcr struct {
}
type Responder struct {
ExitChan chan bool
Stats rpcclient.RpcClientConnection
Timeout time.Duration
Timezone string
cnt int64
responseCache *cache.ResponseCache
ExitChan chan bool
Stats rpcclient.RpcClientConnection
Timeout time.Duration
Timezone string
MaxComputedUsage map[string]time.Duration
cnt int64
responseCache *cache.ResponseCache
}
func (rs *Responder) SetTimeToLive(timeToLive time.Duration, out *int) error {
@@ -66,6 +67,18 @@ func (rs *Responder) getCache() *cache.ResponseCache {
return rs.responseCache
}
// usageAllowed checks requested usage against configured MaxComputedUsage
func (rs *Responder) usageAllowed(tor string, reqUsage time.Duration) (allowed bool) {
mcu, has := rs.MaxComputedUsage[tor]
if !has {
mcu = rs.MaxComputedUsage[utils.ANY]
}
if reqUsage <= mcu {
allowed = true
}
return
}
/*
RPC method thet provides the external RPC interface for getting the rating information.
*/
@@ -91,6 +104,9 @@ func (rs *Responder) GetCost(arg *CallDescriptor, reply *CallCost) (err error) {
}, arg, utils.EXTRA_FIELDS); err != nil && err != utils.ErrNotFound {
return err
}
if !rs.usageAllowed(arg.TOR, arg.GetDuration()) {
return utils.ErrMaxUsageExceeded
}
r, e := guardian.Guardian.Guard(func() (interface{}, error) {
return arg.GetCost()
}, 0, arg.GetAccountKey())
@@ -124,6 +140,9 @@ func (rs *Responder) Debit(arg *CallDescriptor, reply *CallCost) (err error) {
}, arg, utils.EXTRA_FIELDS); err != nil && err != utils.ErrNotFound {
return err
}
if !rs.usageAllowed(arg.TOR, arg.GetDuration()) {
return utils.ErrMaxUsageExceeded
}
r, e := arg.Debit()
if e != nil {
return e
@@ -161,6 +180,9 @@ func (rs *Responder) MaxDebit(arg *CallDescriptor, reply *CallCost) (err error)
}, arg, utils.EXTRA_FIELDS); err != nil && err != utils.ErrNotFound {
return err
}
if !rs.usageAllowed(arg.TOR, arg.GetDuration()) {
return utils.ErrMaxUsageExceeded
}
r, e := arg.MaxDebit()
if e != nil {
rs.getCache().Cache(cacheKey, &cache.CacheItem{
@@ -208,6 +230,9 @@ func (rs *Responder) RefundIncrements(arg *CallDescriptor, reply *float64) (err
})
return err
}
if !rs.usageAllowed(arg.TOR, arg.GetDuration()) {
return utils.ErrMaxUsageExceeded
}
err = arg.RefundIncrements()
rs.getCache().Cache(cacheKey, &cache.CacheItem{
Value: reply,
@@ -247,6 +272,9 @@ func (rs *Responder) RefundRounding(arg *CallDescriptor, reply *float64) (err er
})
return err
}
if !rs.usageAllowed(arg.TOR, arg.GetDuration()) {
return utils.ErrMaxUsageExceeded
}
err = arg.RefundRounding()
rs.getCache().Cache(cacheKey, &cache.CacheItem{
Value: reply,
@@ -276,6 +304,9 @@ func (rs *Responder) GetMaxSessionTime(arg *CallDescriptor, reply *float64) (err
}, arg, utils.EXTRA_FIELDS); err != nil && err != utils.ErrNotFound {
return err
}
if !rs.usageAllowed(arg.TOR, arg.GetDuration()) {
return utils.ErrMaxUsageExceeded
}
r, e := arg.GetMaxSessionDuration()
*reply, err = float64(r), e
return
@@ -312,7 +343,9 @@ func (rs *Responder) GetDerivedMaxSessionTime(ev *CDR, reply *float64) error {
rs.getCache().Cache(cacheKey, &cache.CacheItem{Err: err})
return err
}
if !rs.usageAllowed(ev.ToR, ev.Usage) {
return utils.ErrMaxUsageExceeded
}
maxCallDuration := -1.0
attrsDC := &utils.AttrDerivedChargers{Tenant: ev.GetTenant(utils.META_DEFAULT),
Category: ev.GetCategory(utils.META_DEFAULT), Direction: utils.OUT,
@@ -518,6 +551,9 @@ func (rs *Responder) GetLCR(attrs *AttrGetLcr, reply *LCRCost) error {
rs.getCache().Cache(cacheKey, &cache.CacheItem{Err: err})
return err
}
if !rs.usageAllowed(cd.TOR, cd.GetDuration()) {
return utils.ErrMaxUsageExceeded
}
lcrCost, err := attrs.CallDescriptor.GetLCR(rs.Stats, attrs.LCRFilter, attrs.Paginator)
if err != nil {
rs.getCache().Cache(cacheKey, &cache.CacheItem{Err: err})

View File

@@ -33,6 +33,7 @@ var rsponder *Responder
func init() {
cfg, _ := config.NewDefaultCGRConfig()
config.SetCgrConfig(cfg)
rsponder = &Responder{MaxComputedUsage: cfg.RALsMaxComputedUsage}
}
// Test internal abilites of GetDerivedChargers
@@ -40,7 +41,6 @@ func TestResponderGetDerivedChargers(t *testing.T) {
cfgedDC := &utils.DerivedChargers{DestinationIDs: utils.StringMap{}, Chargers: []*utils.DerivedCharger{&utils.DerivedCharger{RunID: "responder1",
RequestTypeField: utils.META_DEFAULT, DirectionField: "test", TenantField: "test",
CategoryField: "test", AccountField: "test", SubjectField: "test", DestinationField: "test", SetupTimeField: "test", AnswerTimeField: "test", UsageField: "test"}}}
rsponder = &Responder{}
attrs := &utils.AttrDerivedChargers{Tenant: "cgrates.org", Category: "call", Direction: "*out", Account: "responder_test", Subject: "responder_test"}
if err := dm.DataDB().SetDerivedChargers(utils.DerivedChargersKey(utils.OUT, utils.ANY, utils.ANY, utils.ANY, utils.ANY), cfgedDC, utils.NonTransactional); err != nil {
t.Error(err)

View File

@@ -35,7 +35,7 @@ func TestAuthSetStorage(t *testing.T) {
data, _ := engine.NewMapStorageJson()
dbAuth = engine.NewDataManager(data)
engine.SetDataStorage(dbAuth)
rsponder = new(engine.Responder)
rsponder = &engine.Responder{MaxComputedUsage: config.CgrConfig().RALsMaxComputedUsage}
}
@@ -98,7 +98,8 @@ func TestAuthPostpaidNoAcnt(t *testing.T) {
Category: "call", Account: "nonexistent", Subject: "testauthpostpaid1",
Destination: "4986517174963", SetupTime: time.Date(2015, 8, 27, 11, 26, 0, 0, time.UTC)}
var maxSessionTime float64
if err := rsponder.GetDerivedMaxSessionTime(cdr, &maxSessionTime); err == nil || err != utils.ErrAccountNotFound {
if err := rsponder.GetDerivedMaxSessionTime(cdr, &maxSessionTime); err == nil ||
err != utils.ErrAccountNotFound {
t.Error(err)
}
}

View File

@@ -46,6 +46,7 @@ var (
ErrResourceUnavailable = errors.New("RESOURCE_UNAVAILABLE")
ErrNoActiveSession = errors.New("NO_ACTIVE_SESSION")
ErrPartiallyExecuted = errors.New("PARTIALLY_EXECUTED")
ErrMaxUsageExceeded = errors.New("MAX_USAGE_EXCEEDED")
)
// NewCGRError initialises a new CGRError