diff --git a/timespans/calldesc.go b/timespans/calldesc.go index 31fb5bb24..437f460b0 100644 --- a/timespans/calldesc.go +++ b/timespans/calldesc.go @@ -205,17 +205,25 @@ func (cd *CallDescriptor) getPresentSecondCost() (cost float64, err error) { } /* -Returns the cost of a second in the present time conditions. +Returns the aproximate max allowed session for user budget. It will try the max amount received in the call descriptor +and will decrease it by 10% for nine times. So if the user has little credit it will still allow 10% of the initial amount. +If the user has no credit then it will return 0. */ func (cd *CallDescriptor) GetMaxSessionTime() (seconds float64, err error) { _, err = cd.RestoreFromStorage() now := time.Now() - availableCredit := 0.0 + availableCredit, availableSeconds := 0.0, 0.0 if userBudget, err := cd.StorageGetter.GetUserBudget(cd.Subject); err == nil && userBudget != nil { availableCredit = userBudget.Credit + availableSeconds, _ = userBudget.getSecondsForPrefix(cd.StorageGetter, cd.DestinationPrefix) } else { return cd.Amount, err } + // check for zero budget + if availableCredit == 0 { + return availableSeconds, nil + } + maxSessionSeconds := cd.Amount for i := 0; i < 10; i++ { maxDuration, _ := time.ParseDuration(fmt.Sprintf("%vs", maxSessionSeconds)) diff --git a/timespans/calldesc_test.go b/timespans/calldesc_test.go index ac58bdea8..b271c321b 100644 --- a/timespans/calldesc_test.go +++ b/timespans/calldesc_test.go @@ -186,8 +186,8 @@ func TestMinutesCost(t *testing.T) { func TestMaxSessionTimeNoUserBudget(t *testing.T) { getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0723", StorageGetter: getter} - result, err := cd.GetMaxSessionTime(1000) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0723", StorageGetter: getter, Amount: 1000} + result, err := cd.GetMaxSessionTime() if result != 1000 || err != nil { t.Errorf("Expected %v was %v", 1000, result) } @@ -196,13 +196,23 @@ func TestMaxSessionTimeNoUserBudget(t *testing.T) { func TestMaxSessionTimeWithUserBudget(t *testing.T) { getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} - result, err := cd.GetMaxSessionTime(5400) + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} + result, err := cd.GetMaxSessionTime() if result != 1080 || err != nil { t.Errorf("Expected %v was %v", 1080, result) } } +func TestMaxSessionTimeNoCredit(t *testing.T) { + getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) + defer getter.Close() + cd := &CallDescriptor{CstmId: "vdf", Subject: "broker", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} + result, err := cd.GetMaxSessionTime() + if result != 100 || err != nil { + t.Errorf("Expected %v was %v", 100, result) + } +} + /*********************************** BENCHMARKS ***************************************/ func BenchmarkRedisGetting(b *testing.B) { b.StopTimer() @@ -336,10 +346,10 @@ func BenchmarkKyotoSingleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewKyotoStorage("test.kch") defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 100} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(100) + cd.GetMaxSessionTime() } } @@ -347,10 +357,10 @@ func BenchmarkKyotoMultipleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewKyotoStorage("test.kch") defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(5400) + cd.GetMaxSessionTime() } } @@ -358,10 +368,10 @@ func BenchmarkRedisSingleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewRedisStorage("", 10) defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 100} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(100) + cd.GetMaxSessionTime() } } @@ -369,10 +379,10 @@ func BenchmarkRedisMultipleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewRedisStorage("", 10) defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(5400) + cd.GetMaxSessionTime() } } @@ -380,10 +390,10 @@ func BenchmarkMongoSingleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewMongoStorage("127.0.0.1", "test") defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 100} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(100) + cd.GetMaxSessionTime() } } @@ -391,9 +401,9 @@ func BenchmarkMongoMultipleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewMongoStorage("127.0.0.1", "test") defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(5400) + cd.GetMaxSessionTime() } } diff --git a/timespans/test.kch b/timespans/test.kch index 33669ac51..31ae4235e 100644 Binary files a/timespans/test.kch and b/timespans/test.kch differ diff --git a/timespans/test_userbudgets.json b/timespans/test_userbudgets.json index 36056a68e..21cbf1db2 100644 --- a/timespans/test_userbudgets.json +++ b/timespans/test_userbudgets.json @@ -1,5 +1,8 @@ [ {"Id":"minutosu","Credit":21,"SmsCredit":0,"ResetDayOfTheMonth":10,"TariffPlanId":"seara","MinuteBuckets": + [{"Seconds":10,"Priority":10,"Price":0.01,"DestinationId":"nationale"}, + {"Seconds":100,"Priority":20,"Price":0,"DestinationId":"retea"}]}, +{"Id":"broker","Credit":0,"SmsCredit":0,"ResetDayOfTheMonth":10,"TariffPlanId":"seara","MinuteBuckets": [{"Seconds":10,"Priority":10,"Price":0.01,"DestinationId":"nationale"}, {"Seconds":100,"Priority":20,"Price":0,"DestinationId":"retea"}]} ] diff --git a/timespans/userbudget_test.go b/timespans/userbudget_test.go index 2ac8b6718..6349c6416 100644 --- a/timespans/userbudget_test.go +++ b/timespans/userbudget_test.go @@ -10,7 +10,7 @@ var ( retea = &Destination{Id: "retea", Prefixes: []string{"0723", "0724"}} ) -func TestGetSeconds(t *testing.T) { +func TestGetSecondsForPrefix(t *testing.T) { b1 := &MinuteBucket{Seconds: 10, Priority: 10, destination: nationale} b2 := &MinuteBucket{Seconds: 100, Priority: 20, destination: retea} tf1 := &TariffPlan{MinuteBuckets: []*MinuteBucket{b1, b2}} @@ -305,3 +305,14 @@ func BenchmarkUserBudgetMongoStoreRestore(b *testing.B) { getter.GetUserBudget(rifsBudget.Id) } } + +func BenchmarkGetSecondsForPrefix(b *testing.B) { + b1 := &MinuteBucket{Seconds: 10, Priority: 10, destination: nationale} + b2 := &MinuteBucket{Seconds: 100, Priority: 20, destination: retea} + tf1 := &TariffPlan{MinuteBuckets: []*MinuteBucket{b1, b2}} + + ub1 := &UserBudget{Id: "rif", MinuteBuckets: []*MinuteBucket{b1, b2}, Credit: 200, tariffPlan: tf1, ResetDayOfTheMonth: 10} + for i := 0; i < b.N; i++ { + ub1.getSecondsForPrefix(nil, "0723") + } +}