From b5af6011631adf168fd551fbf8ba749c540ec3d8 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Tue, 29 Apr 2014 13:54:51 +0300 Subject: [PATCH] added max rate --- engine/calldesc.go | 14 +++++++++++++- engine/calldesc_test.go | 24 ++++++++++++++++++++++++ engine/rateinterval.go | 2 +- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/engine/calldesc.go b/engine/calldesc.go index 248ad44f4..1756fd9f4 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -116,7 +116,10 @@ type CallDescriptor struct { FallbackSubject string // the subject to check for destination if not found on primary subject RatingInfos RatingInfos Increments Increments - account *Account + // session limits + MaxRate float64 + MaxRateUnit time.Duration + account *Account } func (cd *CallDescriptor) ValidateCallData() error { @@ -480,9 +483,16 @@ func (origCD *CallDescriptor) getMaxSessionDuration(account *Account) (time.Dura return 0, err } // now let's check how many increments are covered with the avilableCredit + // also check for max rate/max rate unit for _, ts := range cc.Timespans { ts.createIncrementsSlice() //Logger.Debug(fmt.Sprintf("TS: %+v", ts)) + if cd.MaxRate > 0 && cd.MaxRateUnit > 0 { + rate, _, rateUnit := ts.RateInterval.GetRateParameters(ts.GetGroupStart()) + if rate/rateUnit.Seconds() > cd.MaxRate/cd.MaxRateUnit.Seconds() { + return availableDuration, nil + } + } for _, incr := range ts.Increments { if incr.Cost <= availableCredit { availableCredit -= incr.Cost @@ -644,6 +654,8 @@ func (cd *CallDescriptor) Clone() *CallDescriptor { TimeEnd: cd.TimeEnd, LoopIndex: cd.LoopIndex, CallDuration: cd.CallDuration, + MaxRate: cd.MaxRate, + MaxRateUnit: cd.MaxRateUnit, // Amount: cd.Amount, FallbackSubject: cd.FallbackSubject, //RatingInfos: cd.RatingInfos, diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index d19611387..535f6a695 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -323,6 +323,30 @@ func TestMaxSessionTimeWithAccount(t *testing.T) { } } +func TestMaxSessionTimeWithMaxRate(t *testing.T) { + ap, _ := accountingStorage.GetActionTimings("TOPUP10_AT") + for _, at := range ap { + at.Execute() + } + cd := &CallDescriptor{ + Direction: "*out", + TOR: "call", + Tenant: "cgrates.org", + Subject: "12345", + Account: "12345", + Destination: "447956", + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 1, 0, 0, time.UTC), + MaxRate: 1.0, + MaxRateUnit: time.Minute, + } + result, err := cd.GetMaxSessionDuration() + expected := 40 * time.Second + if result != expected || err != nil { + t.Errorf("Expected %v was %v", expected, result) + } +} + func TestMaxSessionTimeWithAccountAlias(t *testing.T) { cd := &CallDescriptor{ TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC), diff --git a/engine/rateinterval.go b/engine/rateinterval.go index eecd708d1..b8bc8bd68 100644 --- a/engine/rateinterval.go +++ b/engine/rateinterval.go @@ -246,7 +246,7 @@ func (i *RateInterval) GetCost(duration, startSecond time.Duration) float64 { } // Gets the price for a the provided start second -func (i *RateInterval) GetRateParameters(startSecond time.Duration) (price float64, rateIncrement, rateUnit time.Duration) { +func (i *RateInterval) GetRateParameters(startSecond time.Duration) (rate float64, rateIncrement, rateUnit time.Duration) { i.Rating.Rates.Sort() for index, price := range i.Rating.Rates { if price.GroupIntervalStart <= startSecond && (index == len(i.Rating.Rates)-1 ||