Merge branch 'master' of github.com:30x/apidQuota
diff --git a/api.go b/api.go
index b1fa4be..9b6508e 100644
--- a/api.go
+++ b/api.go
@@ -16,9 +16,6 @@
quotaBasePath := globalVariables.Config.GetString(constants.ConfigQuotaBasePath)
services.API().HandleFunc(quotaBasePath, checkQuotaLimitExceeded).Methods("POST")
- services.API().HandleFunc(quotaBasePath+"/resetQuota",
- resetAndCheckQuotaLimit).Methods("POST")
-
}
func checkQuotaLimitExceeded(res http.ResponseWriter, req *http.Request) {
@@ -43,10 +40,9 @@
return
}
-
results, err := qBucket.IncrementQuotaLimit()
if err != nil {
- util.WriteErrorResponse(http.StatusBadRequest, constants.ErrorCheckingQuotaLimit, "error retrieving count for the give identifier "+err.Error(), res, req)
+ util.WriteErrorResponse(http.StatusBadRequest, constants.ErrorCheckingQuotaLimit, "error retrieving count for the give identifier: "+err.Error(), res, req)
return
}
@@ -58,38 +54,3 @@
res.Write(respbytes)
}
-
-func resetAndCheckQuotaLimit(res http.ResponseWriter, req *http.Request) {
- bodyBytes, err := ioutil.ReadAll(req.Body)
- defer req.Body.Close()
- if err != nil {
- util.WriteErrorResponse(http.StatusBadRequest, constants.UnableToParseBody, "unable to read request body: "+err.Error(), res, req)
- return
- }
-
- quotaBucketMap := make(map[string]interface{}, 0)
- if err := json.Unmarshal(bodyBytes, "aBucketMap); err != nil {
- util.WriteErrorResponse(http.StatusBadRequest, constants.UnMarshalJSONError, "unable to convert request body to an object: "+err.Error(), res, req)
- return
- }
-
- // parse the request body into the QuotaBucket struct
- qBucket := new(quotaBucket.QuotaBucket)
- if err = qBucket.FromAPIRequest(quotaBucketMap); err != nil {
- util.WriteErrorResponse(http.StatusBadRequest, constants.ErrorConvertReqBodyToEntity, err.Error(), res, req)
- return
- }
-
- results, err := qBucket.ResetQuotaLimit()
- if err != nil {
- util.WriteErrorResponse(http.StatusBadRequest, constants.ErrorCheckingQuotaLimit, "error retrieving count for the give identifier "+err.Error(), res, req)
- return
- }
-
- respMap := results.ToAPIResponse()
- respbytes, err := json.Marshal(respMap)
-
- res.Header().Set("Content-Type", "application/json")
- res.WriteHeader(http.StatusOK)
- res.Write(respbytes)
-}
diff --git a/constants/constants.go b/constants/constants.go
index 1d5449c..6a15ea1 100644
--- a/constants/constants.go
+++ b/constants/constants.go
@@ -21,8 +21,11 @@
QuotaTypeCalendar = "calendar" // after start time
QuotaTypeRollingWindow = "rollingwindow" // in the past "window" time
- CacheKeyDelimiter = "|"
- CacheTTL = time.Minute * 1
+ CacheKeyDelimiter = "|"
+ CacheTTL = time.Minute * 1
+ DefaultQuotaSyncTime = 300 //in seconds
+ DefaultCount = 0
+
UnableToParseBody = "unable_to_parse_body"
UnMarshalJSONError = "unmarshal_json_error"
ErrorConvertReqBodyToEntity = "error_convert_reqBody_to_entity"
diff --git a/quotaBucket/apiUtil.go b/quotaBucket/apiUtil.go
index b739cad..6a13039 100644
--- a/quotaBucket/apiUtil.go
+++ b/quotaBucket/apiUtil.go
@@ -2,9 +2,9 @@
import (
"errors"
+ "github.com/30x/apidQuota/constants"
"reflect"
"time"
- "github.com/30x/apidQuota/constants"
)
const (
@@ -14,13 +14,13 @@
)
type QuotaBucketResults struct {
- EdgeOrgID string
- ID string
- MaxCount int64
- exceededTokens bool
- currentTokens int64
- startedAt int64
- expiresAt int64
+ EdgeOrgID string
+ ID string
+ MaxCount int64
+ exceeded bool
+ remainingCount int64
+ startTimestamp int64
+ expiresTimestamp int64
}
func (qBucketRequest *QuotaBucket) FromAPIRequest(quotaBucketMap map[string]interface{}) error {
@@ -50,7 +50,9 @@
}
id = value.(string)
+ //build cacheKey - to retrieve from or add to quotaCache
cacheKey = edgeOrgID + constants.CacheKeyDelimiter + id
+
value, ok = quotaBucketMap["interval"]
if !ok {
return errors.New(`missing field: 'interval' is required`)
@@ -166,7 +168,7 @@
syncTimeInt := int64(syncTimeFloat)
//try to retrieve from cache
- newQBucket, ok = getFromCache(cacheKey)
+ newQBucket, ok = getFromCache(cacheKey, weight)
if !ok {
newQBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit, quotaType, preciseAtSecondsLevel,
@@ -178,7 +180,7 @@
qBucketRequest.quotaBucketData = newQBucket.quotaBucketData
if err := qBucketRequest.Validate(); err != nil {
- return errors.New("failed in Validating the quotaBucket: " + err.Error())
+ return errors.New("error validating quotaBucket: " + err.Error())
}
addToCache(qBucketRequest)
@@ -192,10 +194,10 @@
if syncMsgCountType := reflect.TypeOf(syncMsgCountValue); syncMsgCountType.Kind() != reflect.Float64 {
return errors.New(`invalid type : 'syncTimeInSec' should be a number`)
}
- syncMsgCountFloat := value.(float64)
+ syncMsgCountFloat := syncMsgCountValue.(float64)
syncMsgCountInt := int64(syncMsgCountFloat)
//try to retrieve from cache
- newQBucket, ok = getFromCache(cacheKey)
+ newQBucket, ok = getFromCache(cacheKey, weight)
if !ok {
newQBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit, quotaType, preciseAtSecondsLevel,
@@ -206,7 +208,7 @@
qBucketRequest.quotaBucketData = newQBucket.quotaBucketData
if err := qBucketRequest.Validate(); err != nil {
- return errors.New("failed in Validating the quotaBucket: " + err.Error())
+ return errors.New("error validating quotaBucket: " + err.Error())
}
addToCache(qBucketRequest)
@@ -220,7 +222,7 @@
}
//try to retrieve from cache
- newQBucket, ok = getFromCache(cacheKey)
+ newQBucket, ok = getFromCache(cacheKey, weight)
if !ok {
//for synchronous quotaBucket
@@ -232,7 +234,7 @@
qBucketRequest.quotaBucketData = newQBucket.quotaBucketData
if err := qBucketRequest.Validate(); err != nil {
- return errors.New("failed in Validating the quotaBucket: " + err.Error())
+ return errors.New("error validating quotaBucket: " + err.Error())
}
addToCache(qBucketRequest)
return nil
@@ -242,10 +244,8 @@
return nil
}
-
//retrieveFromCache.
- newQBucket, ok = getFromCache(cacheKey)
- qBucketRequest.quotaBucketData = newQBucket.quotaBucketData
+ newQBucket, ok = getFromCache(cacheKey, weight)
if !ok {
//for non distributed quotaBucket
@@ -259,11 +259,12 @@
qBucketRequest.quotaBucketData = newQBucket.quotaBucketData
if err := qBucketRequest.Validate(); err != nil {
- return errors.New("failed in Validating the quotaBucket: " + err.Error())
+ return errors.New("error validating quotaBucket: " + err.Error())
}
addToCache(qBucketRequest)
}
+ qBucketRequest.quotaBucketData = newQBucket.quotaBucketData
return nil
@@ -274,10 +275,10 @@
resultsMap[reqEdgeOrgID] = qBucketResults.ID
resultsMap[reqID] = qBucketResults.ID
resultsMap[reqMaxCount] = qBucketResults.MaxCount
- resultsMap["exceededTokens"] = qBucketResults.exceededTokens
- resultsMap["currentTokens"] = qBucketResults.currentTokens
- resultsMap["startedAt"] = qBucketResults.startedAt
- resultsMap["expiresAt"] = qBucketResults.expiresAt
+ resultsMap["exceeded"] = qBucketResults.exceeded
+ resultsMap["remainingCount"] = qBucketResults.remainingCount
+ resultsMap["startTimestamp"] = qBucketResults.startTimestamp
+ resultsMap["expiresTimestamp"] = qBucketResults.expiresTimestamp
return resultsMap
}
diff --git a/quotaBucket/quotaBucket.go b/quotaBucket/quotaBucket.go
index 0a06b21..f67137c 100644
--- a/quotaBucket/quotaBucket.go
+++ b/quotaBucket/quotaBucket.go
@@ -4,7 +4,9 @@
"errors"
"github.com/30x/apidQuota/constants"
"github.com/30x/apidQuota/globalVariables"
+ "github.com/30x/apidQuota/services"
"strings"
+ "sync/atomic"
"time"
)
@@ -23,48 +25,29 @@
}
-type quotaPeriodData struct {
+type quotaPeriod struct {
inputStartTime time.Time
startTime time.Time
endTime time.Time
}
-type QuotaPeriod struct {
- quotaPeriodData
+func (qp *quotaPeriod) GetPeriodStartTime() time.Time {
+
+ return qp.startTime
}
-func NewQuotaPeriod(inputStartTime int64, startTime int64, endTime int64) QuotaPeriod {
- pInStartTime := time.Unix(inputStartTime, 0)
- pStartTime := time.Unix(startTime, 0)
- pEndTime := time.Unix(endTime, 0)
+func (qp *quotaPeriod) GetPeriodInputStartTime() time.Time {
- periodData := quotaPeriodData{
- inputStartTime: pInStartTime,
- startTime: pStartTime,
- endTime: pEndTime,
- }
-
- period := QuotaPeriod{
- quotaPeriodData: periodData,
- }
-
- return period
-
+ return qp.inputStartTime
}
-func (qp *QuotaPeriod) GetPeriodInputStartTime() time.Time {
- return qp.quotaPeriodData.inputStartTime
+func (qp *quotaPeriod) GetPeriodEndTime() time.Time {
+
+ return qp.endTime
}
-func (qp *QuotaPeriod) GetPeriodStartTime() time.Time {
- return qp.quotaPeriodData.startTime
-}
+func (qp *quotaPeriod) Validate() (bool, error) {
-func (qp *QuotaPeriod) GetPeriodEndTime() time.Time {
- return qp.quotaPeriodData.endTime
-}
-
-func (qp *QuotaPeriod) Validate() (bool, error) {
if qp.startTime.Before(qp.endTime) {
return true, nil
}
@@ -72,6 +55,98 @@
}
+type aSyncQuotaBucket struct {
+ syncTimeInSec int64 // sync time in seconds.
+ syncMessageCount int64 //set to -1 if the aSyncQuotaBucket should syncTimeInSec
+ asyncLocalMessageCount int64
+ asyncCounter *[]int64
+ asyncGLobalCount int64
+ initialized bool
+ qTicker *time.Ticker
+}
+
+func (qAsync *aSyncQuotaBucket) getAsyncGlobalCount() (int64, error) {
+
+ if qAsync != nil {
+ return qAsync.asyncGLobalCount, nil
+ }
+ return 0, errors.New("aSyncDetails for QuotaBucket are empty.")
+}
+
+func (qAsync *aSyncQuotaBucket) getAsyncQTicker() (*time.Ticker, error) {
+
+ if qAsync != nil {
+ return qAsync.qTicker, nil
+ }
+ return nil, errors.New("AsyncDetails for QuotaBucket are empty.")
+}
+
+func (qAsync *aSyncQuotaBucket) addToAsyncLocalMessageCount(count int64) error {
+
+ if qAsync != nil {
+ atomic.AddInt64(&qAsync.asyncLocalMessageCount, count)
+ }
+ return errors.New("AsyncDetails for QuotaBucket are empty. ")
+}
+
+func (qAsync *aSyncQuotaBucket) getAsyncLocalMessageCount() (int64, error) {
+
+ if qAsync != nil {
+ return qAsync.asyncLocalMessageCount, nil
+ }
+ return 0, errors.New("AsyncDetails for QuotaBucket are empty. ")
+}
+
+func (qAsync *aSyncQuotaBucket) getAsyncSyncTime() (int64, error) {
+
+ if qAsync != nil {
+ return qAsync.syncTimeInSec, nil
+ }
+ return 0, errors.New("AsyncDetails for QuotaBucket are empty. ")
+}
+
+func (qAsync *aSyncQuotaBucket) getAsyncSyncMessageCount() (int64, error) {
+
+ if qAsync != nil {
+ return qAsync.syncMessageCount, nil
+ }
+ return 0, errors.New("AsyncDetails for QuotaBucket are empty. ")
+}
+
+func (qAsync *aSyncQuotaBucket) getAsyncIsInitialized() (bool, error) {
+
+ if qAsync != nil {
+ return qAsync.initialized, nil
+ }
+ return false, errors.New("AsyncDetails for QuotaBucket are empty. ")
+}
+
+func (aSyncbucket *aSyncQuotaBucket) getCount(q *QuotaBucket, period *quotaPeriod) (int64, error) {
+
+ var gcount int64
+ var err error
+ if !aSyncbucket.initialized {
+ gcount, err = services.IncrementAndGetCount(q.GetEdgeOrgID(), q.GetID(), 0, period.startTime.Unix(), period.endTime.Unix())
+ if err != nil {
+ return 0, err
+ }
+ aSyncbucket.asyncGLobalCount = gcount
+ aSyncbucket.initialized = true
+ }
+
+ return aSyncbucket.asyncGLobalCount + aSyncbucket.asyncLocalMessageCount, nil
+}
+
+func (aSyncbucket *aSyncQuotaBucket) addToCounter(weight int64) error {
+
+ if aSyncbucket == nil {
+ return errors.New("AsyncDetails for QuotaBucket are empty. ")
+ }
+
+ *aSyncbucket.asyncCounter = append(*aSyncbucket.asyncCounter, weight)
+ return nil
+}
+
type quotaBucketData struct {
EdgeOrgID string
ID string
@@ -79,17 +154,12 @@
TimeUnit string //TimeUnit {SECOND, MINUTE, HOUR, DAY, WEEK, MONTH}
QuotaType string //QuotaType {CALENDAR, FLEXI, ROLLING_WINDOW}
PreciseAtSecondsLevel bool
- Period QuotaPeriod
StartTime time.Time
MaxCount int64
Weight int64
Distributed bool
Synchronous bool
- SyncTimeInSec int64
- SyncMessageCount int64
- AsyncMessageCounter int64
- QTicker *time.Ticker
-
+ AsyncQuotaDetails *aSyncQuotaBucket
}
type QuotaBucket struct {
@@ -102,7 +172,6 @@
synchronous bool, syncTimeInSec int64, syncMessageCount int64) (*QuotaBucket, error) {
fromUNIXTime := time.Unix(startTime, 0)
-
quotaBucketDataStruct := quotaBucketData{
EdgeOrgID: edgeOrgID,
ID: id,
@@ -115,33 +184,66 @@
Weight: weight,
Distributed: distributed,
Synchronous: synchronous,
- SyncTimeInSec: syncTimeInSec,
- SyncMessageCount: syncMessageCount,
- AsyncMessageCounter: int64(-1),
- QTicker: &time.Ticker{},
+ AsyncQuotaDetails: nil,
}
quotaBucket := &QuotaBucket{
quotaBucketData: quotaBucketDataStruct,
}
- err := quotaBucket.setCurrentPeriod()
- if err != nil {
- return nil, err
- }
+ //for async set AsyncQuotaDetails and start the NewTicker
+ if distributed && !synchronous {
+ var quotaTicker int64
+ //set default syncTime for AsyncQuotaBucket.
+ //for aSyncQuotaBucket with 'syncMessageCount' the ticker is invoked with DefaultQuotaSyncTime
+ quotaTicker = constants.DefaultQuotaSyncTime
- //for async SetAsyncMessageCounter to 0 and also start the scheduler
- if distributed && !synchronous{
- quotaBucket.SetAsyncMessageCounter(0)
- quotaBucket.quotaBucketData.QTicker = time.NewTicker(time.Second)
+ if syncTimeInSec > 0 { //if sync with counter service periodically
+ quotaTicker = syncTimeInSec
+ }
+
+ counter := make([]int64, 0)
+ newAsyncQuotaDetails := &aSyncQuotaBucket{
+ syncTimeInSec: syncTimeInSec,
+ syncMessageCount: syncMessageCount,
+ asyncCounter: &counter,
+ asyncGLobalCount: constants.DefaultCount,
+ asyncLocalMessageCount: constants.DefaultCount,
+ initialized: false,
+ qTicker: time.NewTicker(time.Duration(time.Second.Nanoseconds() * quotaTicker)),
+ }
+
+ quotaBucket.setAsyncQuotaBucket(newAsyncQuotaDetails)
go func() {
- count := 0
- for t := range quotaBucket.quotaBucketData.QTicker.C {
- globalVariables.Log.Debug("t: : ", t.String())
- if count > 10 {
- quotaBucket.getTicker().Stop()
+ aSyncBucket := quotaBucket.GetAsyncQuotaBucket()
+ if aSyncBucket != nil {
+ exitCount := int64(0)
+ qticker, _ := aSyncBucket.getAsyncQTicker()
+ for t := range qticker.C {
+ globalVariables.Log.Debug("t: ", t.String())
+ if len(*aSyncBucket.asyncCounter) == 0 {
+ exitCount += 1
+ }
+ period, err := quotaBucket.GetPeriod()
+ if err != nil {
+ globalVariables.Log.Error("error getting period for: ", err.Error(), "for quotaBucket: ", quotaBucket)
+ qticker.Stop()
+ continue
+ }
+ //sync with counterService.
+ err = internalRefresh(quotaBucket, period)
+ if err != nil {
+ globalVariables.Log.Error("error during internalRefresh: ", err.Error(), "for quotaBucket: ", quotaBucket)
+ qticker.Stop()
+ continue
+ }
+
+ if exitCount > 3 {
+ qticker.Stop()
+ }
}
- count += 1
+ } else {
+ globalVariables.Log.Error("aSyncBucketDetails are empty for the given quotaBucket: ", quotaBucket)
}
}()
}
@@ -160,10 +262,11 @@
if ok := IsValidType(strings.ToLower(q.GetType())); !ok {
return errors.New(constants.InvalidQuotaBucketType)
}
+
//check if the period is valid
- period, err := q.GetQuotaBucketPeriod()
+ period, err := q.GetPeriod()
if err != nil {
- return err
+ return errors.New("error retireving Period for the quota Bucket" + err.Error())
}
if ok, err := period.Validate(); !ok {
@@ -193,6 +296,7 @@
return q.quotaBucketData.StartTime
}
+//QuotaType {CALENDAR, FLEXI, ROLLING_WINDOW}
func (q *QuotaBucket) GetType() string {
return q.quotaBucketData.QuotaType
}
@@ -217,76 +321,18 @@
return q.quotaBucketData.Synchronous
}
-func (qbucket *QuotaBucket) SetAsyncMessageCounter(count int64) {
- qbucket.quotaBucketData.AsyncMessageCounter = count
-}
-
-func (q *QuotaBucket) getTicker() *time.Ticker {
- return q.quotaBucketData.QTicker
-}
-//Calls setCurrentPeriod if DescriptorType is 'rollingWindow' or period.endTime is before now().
-// It is required to setPeriod while incrementing the count.
-func (q *QuotaBucket) GetPeriod() (*QuotaPeriod, error) {
- if q.quotaBucketData.QuotaType == constants.QuotaTypeRollingWindow {
- qRWType := RollingWindowQuotaDescriptorType{}
- err := qRWType.SetCurrentPeriod(q)
- if err != nil {
- return nil, err
- }
- }
-
- period, err := q.GetQuotaBucketPeriod()
- if err != nil {
- return nil, err
- }
-
- //setCurrentPeriod if endTime > time.now()
- if period == nil || period.endTime.Before(time.Now().UTC()) || period.endTime.Equal(time.Now().UTC()) {
- if err := q.setCurrentPeriod(); err != nil {
- return nil, err
- }
- }
-
- return &q.quotaBucketData.Period, nil
-}
-
//setCurrentPeriod only for rolling window else just return the value of QuotaPeriod.
-func (q *QuotaBucket) GetQuotaBucketPeriod() (*QuotaPeriod, error) {
- if q.quotaBucketData.QuotaType == constants.QuotaTypeRollingWindow {
- qRWType := RollingWindowQuotaDescriptorType{}
- err := qRWType.SetCurrentPeriod(q)
- if err != nil {
- return nil, err
- }
- }
- return &q.quotaBucketData.Period, nil
-}
-
-func (q *QuotaBucket) SetPeriod(startTime time.Time, endTime time.Time) {
- periodData := quotaPeriodData{
- inputStartTime: q.GetStartTime(),
- startTime: startTime,
- endTime: endTime,
- }
-
- period := QuotaPeriod{
- quotaPeriodData: periodData,
- }
-
- q.quotaBucketData.Period = period
-}
-
-func (q *QuotaBucket) setCurrentPeriod() error {
+func (q *QuotaBucket) GetPeriod() (*quotaPeriod, error) {
qDescriptorType, err := GetQuotaTypeHandler(q.GetType())
if err != nil {
- return err
+ return nil, err
}
- return qDescriptorType.SetCurrentPeriod(q)
+ return qDescriptorType.GetCurrentPeriod(q)
}
-func (period *QuotaPeriod) IsCurrentPeriod(qBucket *QuotaBucket) bool {
+func (period *quotaPeriod) IsCurrentPeriod(qBucket *QuotaBucket) bool {
if qBucket != nil && qBucket.GetType() != "" {
if qBucket.GetType() == constants.QuotaTypeRollingWindow {
return (period.inputStartTime.Equal(time.Now().UTC()) || period.inputStartTime.Before(time.Now().UTC()))
@@ -302,14 +348,12 @@
return false
}
-func (q *QuotaBucket) ResetQuotaLimit() (*QuotaBucketResults, error) {
- bucketType, err := GetQuotaBucketHandler(q)
- if err != nil {
- return nil, errors.New("error getting quotaBucketHandler: " + err.Error())
- }
+func (q *QuotaBucket) setAsyncQuotaBucket(aSyncbucket *aSyncQuotaBucket) {
+ q.quotaBucketData.AsyncQuotaDetails = aSyncbucket
+}
- return bucketType.resetQuotaForCurrentPeriod(q)
-
+func (q *QuotaBucket) GetAsyncQuotaBucket() *aSyncQuotaBucket {
+ return q.quotaBucketData.AsyncQuotaDetails
}
func (q *QuotaBucket) IncrementQuotaLimit() (*QuotaBucketResults, error) {
diff --git a/quotaBucket/quotaBucketType.go b/quotaBucket/quotaBucketType.go
index 3c73d46..5b3cbbc 100644
--- a/quotaBucket/quotaBucketType.go
+++ b/quotaBucket/quotaBucketType.go
@@ -8,7 +8,6 @@
type QuotaBucketType interface {
resetCount(bucket *QuotaBucket) error
incrementQuotaCount(qBucket *QuotaBucket) (*QuotaBucketResults, error)
- resetQuotaForCurrentPeriod(qBucket *QuotaBucket) (*QuotaBucketResults, error)
}
type SynchronousQuotaBucketType struct{}
@@ -17,39 +16,17 @@
//do nothing.
return nil
}
-func (sQuotaBucket SynchronousQuotaBucketType) resetQuotaForCurrentPeriod(q *QuotaBucket) (*QuotaBucketResults, error) {
-
- weight := q.GetWeight()
- weightToReset := -weight
- period, err := q.GetPeriod()
- if err != nil {
- return nil, errors.New("error getting period: " + err.Error())
- }
- currentCount, err := services.IncrementAndGetCount(q.GetEdgeOrgID(), q.GetID(), weightToReset, period.GetPeriodStartTime().Unix(), period.GetPeriodEndTime().Unix())
- exceededCount := currentCount > q.GetMaxCount()
- results := &QuotaBucketResults{
- EdgeOrgID: q.GetEdgeOrgID(),
- ID: q.GetID(),
- exceededTokens: exceededCount,
- currentTokens: currentCount,
- MaxCount: q.GetMaxCount(),
- startedAt: period.GetPeriodStartTime().Unix(),
- expiresAt: period.GetPeriodEndTime().Unix(),
- }
- return results, nil
-
-}
func (sQuotaBucket SynchronousQuotaBucketType) incrementQuotaCount(q *QuotaBucket) (*QuotaBucketResults, error) {
-
- maxCount := q.GetMaxCount()
- exceededCount := false
- allowedCount := int64(0)
- weight := q.GetWeight()
period, err := q.GetPeriod()
if err != nil {
return nil, errors.New("error getting period: " + err.Error())
}
+ maxCount := q.GetMaxCount()
+ exceeded := false
+ remainingCount := int64(0)
+
+ weight := q.GetWeight()
//first retrieve the count from counter service.
currentCount, err := services.GetCount(q.GetEdgeOrgID(), q.GetID(), period.GetPeriodStartTime().Unix(), period.GetPeriodEndTime().Unix())
@@ -60,46 +37,45 @@
if period.IsCurrentPeriod(q) {
if currentCount < maxCount {
allowed := maxCount - currentCount
- if allowed > weight {
+ if allowed >= weight {
if weight != 0 {
currentCount, err = services.IncrementAndGetCount(q.GetEdgeOrgID(), q.GetID(), weight, period.GetPeriodStartTime().Unix(), period.GetPeriodEndTime().Unix())
if err != nil {
return nil, err
}
}
- allowedCount = currentCount
+ remainingCount = maxCount - (currentCount)
+
} else {
if weight != 0 {
-
- exceededCount = true
+ exceeded = true
}
- allowedCount = currentCount + weight
+ remainingCount = maxCount - currentCount
}
} else {
-
- exceededCount = true
- allowedCount = currentCount
+ exceeded = true
+ remainingCount = maxCount - currentCount
}
}
+ if remainingCount < 0 {
+ remainingCount = int64(0)
+ }
+
results := &QuotaBucketResults{
- EdgeOrgID: q.GetEdgeOrgID(),
- ID: q.GetID(),
- exceededTokens: exceededCount,
- currentTokens: allowedCount,
- MaxCount: maxCount,
- startedAt: period.GetPeriodStartTime().Unix(),
- expiresAt: period.GetPeriodEndTime().Unix(),
+ EdgeOrgID: q.GetEdgeOrgID(),
+ ID: q.GetID(),
+ exceeded: exceeded,
+ remainingCount: remainingCount,
+ MaxCount: maxCount,
+ startTimestamp: period.GetPeriodStartTime().Unix(),
+ expiresTimestamp: period.GetPeriodEndTime().Unix(),
}
return results, nil
}
type AsynchronousQuotaBucketType struct {
- initialized bool
- globalCount int64
- syncMessageCount int64
- syncTimeInSec int64
}
func (quotaBucketType AsynchronousQuotaBucketType) resetCount(q *QuotaBucket) error {
@@ -108,26 +84,112 @@
}
func (quotaBucketType AsynchronousQuotaBucketType) incrementQuotaCount(q *QuotaBucket) (*QuotaBucketResults, error) {
- //getCount()
- return nil, nil
+ period, err := q.GetPeriod()
+ if err != nil {
+ return nil, errors.New("error getting period: " + err.Error())
+ }
+ aSyncBucket := q.GetAsyncQuotaBucket()
+ currentCount, err := aSyncBucket.getCount(q, period)
+ if err != nil {
+ return nil, err
+ }
+
+ maxCount := q.GetMaxCount()
+ exceeded := false
+ remainingCount := int64(0)
+ weight := q.GetWeight()
+
+ if period.IsCurrentPeriod(q) {
+
+ if currentCount < maxCount {
+ diffCount := (currentCount + weight) - maxCount
+ if diffCount > 0 {
+ exceeded = true
+ remainingCount = maxCount - currentCount
+
+ } else {
+ aSyncBucket.addToCounter(weight)
+ aSyncBucket.addToAsyncLocalMessageCount(weight)
+ remainingCount = maxCount - (currentCount + weight)
+
+ }
+
+ if aSyncBucket.syncMessageCount > 0 &&
+ aSyncBucket.asyncLocalMessageCount >= aSyncBucket.syncMessageCount {
+ err = internalRefresh(q, period)
+ if err != nil {
+ return nil, err
+ }
+
+ }
+ } else {
+ exceeded = true
+ remainingCount = maxCount - currentCount
+ }
+ }
+ if remainingCount < 0 {
+ remainingCount = int64(0)
+ }
+
+ results := &QuotaBucketResults{
+ EdgeOrgID: q.GetEdgeOrgID(),
+ ID: q.GetID(),
+ exceeded: exceeded,
+ remainingCount: remainingCount,
+ MaxCount: maxCount,
+ startTimestamp: period.GetPeriodStartTime().Unix(),
+ expiresTimestamp: period.GetPeriodEndTime().Unix(),
+ }
+
+ return results, nil
}
-func (quotaBucketType AsynchronousQuotaBucketType) resetQuotaForCurrentPeriod(q *QuotaBucket) (*QuotaBucketResults, error) {
- return nil, nil
+func internalRefresh(q *QuotaBucket, period *quotaPeriod) error {
+ var err error
+ aSyncBucket := q.GetAsyncQuotaBucket()
+ weight := int64(0)
+ countFromCounterService := int64(0)
+ globalCount := aSyncBucket.asyncGLobalCount
+ maxCount := q.GetMaxCount()
+
+ for _, counterEle := range *aSyncBucket.asyncCounter {
+ weight += counterEle
+
+ //delete from asyncCounter
+ temp := *aSyncBucket.asyncCounter
+ temp = temp[1:]
+ aSyncBucket.asyncCounter = &temp
+
+ if (weight + globalCount) >= maxCount {
+ //clear asyncCounter
+ for range *aSyncBucket.asyncCounter {
+ //delete all elements from asyncCounter
+ temp := *aSyncBucket.asyncCounter
+ temp = temp[1:]
+ aSyncBucket.asyncCounter = &temp
+ }
+ }
+ }
+
+ countFromCounterService, err = services.IncrementAndGetCount(q.GetEdgeOrgID(), q.GetID(), weight, period.GetPeriodStartTime().Unix(), period.GetPeriodEndTime().Unix())
+ if err != nil {
+ return err
+ }
+ aSyncBucket.asyncGLobalCount = countFromCounterService
+
+ aSyncBucket.asyncLocalMessageCount -= weight
+ return nil
}
type NonDistributedQuotaBucketType struct{}
func (sQuotaBucket NonDistributedQuotaBucketType) resetCount(qBucket *QuotaBucket) error {
//yet to implement
- return nil
+ return errors.New("methog not implemented")
}
func (sQuotaBucket NonDistributedQuotaBucketType) incrementQuotaCount(qBucket *QuotaBucket) (*QuotaBucketResults, error) {
- return nil, nil
-}
-func (sQuotaBucket NonDistributedQuotaBucketType) resetQuotaForCurrentPeriod(q *QuotaBucket) (*QuotaBucketResults, error) {
- return nil, nil
+ return nil, errors.New("methog not implemented")
}
func GetQuotaBucketHandler(qBucket *QuotaBucket) (QuotaBucketType, error) {
diff --git a/quotaBucket/quotaBucket_suite_test.go b/quotaBucket/quotaBucket_suite_test.go
index 43fa8cb..473467d 100644
--- a/quotaBucket/quotaBucket_suite_test.go
+++ b/quotaBucket/quotaBucket_suite_test.go
@@ -10,12 +10,3 @@
RegisterFailHandler(Fail)
RunSpecs(t, "QuotaBucket Suite")
}
-
-//var _ = BeforeSuite(func() {
-// fmt.Println("before suite")
-//
-//})
-//
-//var _ = AfterSuite(func() {
-// fmt.Println("after suite")
-//})
diff --git a/quotaBucket/quotaBucket_test.go b/quotaBucket/quotaBucket_test.go
index 08b580c..2de6335 100644
--- a/quotaBucket/quotaBucket_test.go
+++ b/quotaBucket/quotaBucket_test.go
@@ -1,595 +1,596 @@
package quotaBucket_test
-import (
- "github.com/30x/apidQuota/constants"
- . "github.com/30x/apidQuota/quotaBucket"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
- "strings"
- "time"
-)
-
-var _ = Describe("Test QuotaPeriod", func() {
- It("Valid NewQuotaPeriod", func() {
- //startTime before endTime
- period := NewQuotaPeriod(time.Now().UTC().AddDate(0, -1, 0).Unix(),
- time.Now().UTC().AddDate(0, 0, -1).Unix(),
- time.Now().UTC().AddDate(0, 1, 0).Unix())
- isValid, err := period.Validate()
-
- if !isValid {
- Fail("expected isValid true but got false")
- }
- if err != nil {
- Fail("expected error <nil> but got " + err.Error())
- }
- })
-
- It("Invalid NewQuotaPeriod", func() {
- //startTime after endTime
- period := NewQuotaPeriod(time.Now().UTC().AddDate(0, -1, 0).Unix(),
- time.Now().UTC().AddDate(0, 1, 0).Unix(),
- time.Now().UTC().AddDate(0, 0, -1).Unix())
- isValid, err := period.Validate()
- if isValid {
- Fail("Expected isValid false but got true")
- }
-
- if err == nil {
- Fail(" Expected error but got <nil>")
- }
-
- //startTime same as endTime
- period = NewQuotaPeriod(time.Now().UTC().AddDate(0, -1, 0).Unix(),
- time.Now().UTC().AddDate(0, 1, 0).Unix(),
- time.Now().UTC().AddDate(0, 1, 0).Unix())
- isValid, err = period.Validate()
- if isValid {
- Fail("Expected isValid false but got true")
- }
-
- if err == nil {
- Fail(" Expected error but got <nil>")
- }
-
- })
-})
-
-var _ = Describe("Test AcceptedQuotaTimeUnitTypes", func() {
- It("testTimeUnit", func() {
- if !IsValidTimeUnit("second") {
- Fail("Expected true: second is a valid TimeUnit")
- }
- if !IsValidTimeUnit("minute") {
- Fail("Expected true: minute is a valid TimeUnit")
- }
- if !IsValidTimeUnit("hour") {
- Fail("Expected true: hour is a valid TimeUnit")
- }
- if !IsValidTimeUnit("day") {
- Fail("Expected true: day is a valid TimeUnit")
- }
- if !IsValidTimeUnit("week") {
- Fail("Expected true: week is a valid TimeUnit")
- }
- if !IsValidTimeUnit("month") {
- Fail("Expected true: month is a valid TimeUnit")
- }
-
- //invalid type
- if IsValidTimeUnit("invalidType") {
- Fail("Expected false: invalidType is not a valid TimeUnit")
- }
- })
-})
-
-//Tests for QuotaBucket
-var _ = Describe("QuotaBucket", func() {
- It("Create with NewQuotaBucket", func() {
- edgeOrgID := "sampleOrg"
- id := "sampleID"
- interval := 1
- timeUnit := "hour"
- quotaType := "calendar"
- preciseAtSecondsLevel := true
- maxCount := int64(10)
- weight := int64(1)
- distributed := true
- synchronous := true
- syncTimeInSec := int64(-1)
- syncMessageCount := int64(-1)
-
- //start time before now()
- startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
-
- quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
- now := time.Now().UTC()
- currentHour := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, time.UTC)
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- //also check if all the fields are set as expected
- sTime := time.Unix(startTime, 0)
- Expect(sTime).To(Equal(quotaBucket.GetStartTime()))
- Expect(edgeOrgID).To(Equal(quotaBucket.GetEdgeOrgID()))
- Expect(id).To(Equal(quotaBucket.GetID()))
- Expect(timeUnit).To(Equal(quotaBucket.GetTimeUnit()))
- Expect(quotaType).To(Equal(quotaBucket.GetType()))
- Expect(interval).To(Equal(quotaBucket.GetInterval()))
- Expect(maxCount).To(Equal(quotaBucket.GetMaxCount()))
- Expect(preciseAtSecondsLevel).To(Equal(quotaBucket.GetIsPreciseAtSecondsLevel()))
- getPeriod, err := quotaBucket.GetPeriod()
- Expect(err).NotTo(HaveOccurred())
- Expect(getPeriod.GetPeriodInputStartTime().String()).ShouldNot(BeEmpty())
- Expect(getPeriod.GetPeriodStartTime().String()).ShouldNot(BeEmpty())
- Expect(getPeriod.GetPeriodEndTime().String()).ShouldNot(BeEmpty())
- Expect(getPeriod.GetPeriodStartTime().String()).Should(Equal(currentHour.String()))
- Expect(getPeriod.GetPeriodEndTime().String()).Should(Equal(currentHour.Add(time.Hour).String()))
-
- //start time is after now() -> should still set period.
- startTime = time.Now().UTC().AddDate(0, 1, 0).Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- now = time.Now().UTC()
- currentHour = time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, time.UTC)
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- getPeriod, err = quotaBucket.GetPeriod()
- Expect(err).NotTo(HaveOccurred())
- Expect(getPeriod.GetPeriodInputStartTime().String()).ShouldNot(BeEmpty())
- Expect(getPeriod.GetPeriodStartTime().String()).ShouldNot(BeEmpty())
- Expect(getPeriod.GetPeriodEndTime().String()).ShouldNot(BeEmpty())
- Expect(getPeriod.GetPeriodStartTime().String()).Should(Equal(currentHour.String()))
- Expect(getPeriod.GetPeriodEndTime().String()).Should(Equal(currentHour.Add(time.Hour).String()))
-
- })
-
- //end before start
- It("Test invalid quotaPeriod", func() {
- edgeOrgID := "sampleOrg"
- id := "sampleID"
- timeUnit := "hour"
- quotaType := "calendar"
- interval := 1
- maxCount := int64(10)
- weight := int64(1)
- preciseAtSecondsLevel := true
- startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
- distributed := true
- synchronous := true
- syncTimeInSec := int64(-1)
- syncMessageCount := int64(-1)
-
- quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 1, 0), time.Now().UTC().AddDate(0, 0, -1))
- err = quotaBucket.Validate()
- if err == nil {
- Fail("error expected but got <nil>")
- }
- if !strings.Contains(err.Error(), constants.InvalidQuotaPeriod) {
- Fail("expected: " + constants.InvalidQuotaPeriod + " in the error but got: " + err.Error())
- }
-
- })
-
- It("Test invalid timeUnitType", func() {
- edgeOrgID := "sampleOrg"
- id := "sampleID"
- timeUnit := "invalidTimeUnit"
- quotaType := "calendar"
- interval := 1
- maxCount := int64(10)
- weight := int64(1)
- preciseAtSecondsLevel := true
- startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
- distributed := true
- synchronous := true
- syncTimeInSec := int64(-1)
- syncMessageCount := int64(-1)
-
- quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).To(HaveOccurred())
-
- if !strings.Contains(err.Error(), constants.InvalidQuotaTimeUnitType) {
- Fail("expected: " + constants.InvalidQuotaTimeUnitType + "but got: " + err.Error())
- }
- if quotaBucket != nil {
- Fail("quotaBucket returned should be nil.")
- }
-
- })
-
-})
-
-var _ = Describe("IsCurrentPeriod", func() {
- It("Test IsCurrentPeriod for RollingType Window - Valid TestCase", func() {
-
- edgeOrgID := "sampleOrg"
- id := "sampleID"
- timeUnit := "hour"
- quotaType := "rollingwindow"
- interval := 1
- maxCount := int64(10)
- weight := int64(1)
- preciseAtSecondsLevel := true
- distributed := true
- synchronous := true
- syncTimeInSec := int64(-1)
- syncMessageCount := int64(-1)
-
- //InputStart time is before now
- startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
-
- quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- period, err := quotaBucket.GetPeriod()
- if err != nil {
- Fail("no error expected")
- }
- if ok := period.IsCurrentPeriod(quotaBucket); !ok {
- Fail("Exprected true, returned: false")
- }
-
- //InputStart time is now
- startTime = time.Now().UTC().Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- period, err = quotaBucket.GetPeriod()
- if err != nil {
- Fail("no error expected")
- }
- period.IsCurrentPeriod(quotaBucket)
- if ok := period.IsCurrentPeriod(quotaBucket); !ok {
- Fail("Exprected true, returned: false")
- }
- })
-
- It("Test IsCurrentPeriod for RollingType Window - InValid TestCase", func() {
-
- edgeOrgID := "sampleOrg"
- id := "sampleID"
- timeUnit := "hour"
- quotaType := "rollingwindow"
- interval := 1
- maxCount := int64(10)
- weight := int64(1)
- preciseAtSecondsLevel := true
- //InputStart time is after now.
- startTime := time.Now().UTC().AddDate(0, 1, 0).Unix()
- distributed := true
- synchronous := true
- syncTimeInSec := int64(-1)
- syncMessageCount := int64(-1)
-
- quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, -1, 0), time.Now().UTC().AddDate(0, 0, 1))
- period, err := quotaBucket.GetPeriod()
- Expect(err).NotTo(HaveOccurred())
- if ok := period.IsCurrentPeriod(quotaBucket); ok {
- Fail("Exprected true, returned: false")
- }
-
- //endTime before startTime in period
- startTime = time.Now().UTC().AddDate(0, -1, 0).Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(time.Now().UTC(), time.Now().UTC().AddDate(0, -1, 0))
- if ok := period.IsCurrentPeriod(quotaBucket); ok {
- Fail("Exprected false, returned: true")
- }
- })
-
- It("Test IsCurrentPeriod for calendarType Window - Valid TestCases", func() {
-
- edgeOrgID := "sampleOrg"
- id := "sampleID"
- timeUnit := "hour"
- quotaType := "calendar"
- interval := 1
- maxCount := int64(10)
- weight := int64(1)
- preciseAtSecondsLevel := true
- distributed := true
- synchronous := true
- syncTimeInSec := int64(-1)
- syncMessageCount := int64(-1)
-
- //InputStart time is before now
- startTime := time.Now().UTC().UTC().AddDate(-1, -1, 0).Unix()
-
- quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- period, err := quotaBucket.GetPeriod()
- if err != nil {
- Fail("no error expected but returned " + err.Error())
- }
- if ok := period.IsCurrentPeriod(quotaBucket); !ok {
- Fail("Exprected true, returned: false")
- }
-
- //InputStart time is now
- startTime = time.Now().UTC().Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- period, err = quotaBucket.GetPeriod()
- if err != nil {
- Fail("no error expected but returned " + err.Error())
- }
- period.IsCurrentPeriod(quotaBucket)
- if ok := period.IsCurrentPeriod(quotaBucket); !ok {
- Fail("Exprected true, returned: false")
- }
-
- //start Time in period is before now
- startTime = time.Now().UTC().Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 0, -1),
- time.Now().UTC().AddDate(0, 1, 0))
- period, err = quotaBucket.GetPeriod()
- if err != nil {
- Fail("no error expected but returned " + err.Error())
- }
- period.IsCurrentPeriod(quotaBucket)
- if ok := period.IsCurrentPeriod(quotaBucket); !ok {
- Fail("Exprected true, returned: false")
- }
-
- //start Time in period is now
- startTime = time.Now().UTC().Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
- quotaBucket.SetPeriod(time.Now().UTC(),
- time.Now().UTC().AddDate(0, 1, 0))
- period, err = quotaBucket.GetPeriod()
- if err != nil {
- Fail("no error expected but returned " + err.Error())
- }
- period.IsCurrentPeriod(quotaBucket)
- if ok := period.IsCurrentPeriod(quotaBucket); !ok {
- Fail("Exprected true, returned: false")
- }
-
- //end Time in period is after now
- startTime = time.Now().UTC().Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 0, -1),
- time.Now().UTC().AddDate(0, 1, 0))
- period, err = quotaBucket.GetPeriod()
- if err != nil {
- Fail("no error expected but returned " + err.Error())
- }
-
- period.IsCurrentPeriod(quotaBucket)
- if ok := period.IsCurrentPeriod(quotaBucket); !ok {
- Fail("Exprected true, returned: false")
- }
-
- //start time in period is before end time
- startTime = time.Now().UTC().Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
- quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 0, -1),
- time.Now().UTC().AddDate(0, 1, 0))
- period, err = quotaBucket.GetPeriod()
- if err != nil {
- Fail("no error expected but returned " + err.Error())
- }
- period.IsCurrentPeriod(quotaBucket)
- if ok := period.IsCurrentPeriod(quotaBucket); !ok {
- Fail("Exprected true, returned: false")
- }
-
- })
-
- It("Test IsCurrentPeriod for calendarType Window InValid TestCase", func() {
-
- edgeOrgID := "sampleOrg"
- id := "sampleID"
- timeUnit := "hour"
- quotaType := "calendar"
- interval := 1
- maxCount := int64(10)
- weight := int64(1)
- preciseAtSecondsLevel := true
- distributed := true
- synchronous := true
- syncTimeInSec := int64(-1)
- syncMessageCount := int64(-1)
-
- //InputStart time is after now.
- period := NewQuotaPeriod(time.Now().UTC().AddDate(0, 1, 0).Unix(),
- time.Now().UTC().AddDate(0, 1, 0).Unix(), time.Now().AddDate(1, 0, 1).Unix())
- startTime := time.Now().UTC().AddDate(0, 1, 0).Unix()
-
- quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- if ok := period.IsCurrentPeriod(quotaBucket); ok {
- Fail("Exprected true, returned: false")
- }
-
- //endTime is before start time
- startTime = time.Now().UTC().AddDate(0, -1, 0).Unix()
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(time.Now().UTC(), time.Now().UTC().AddDate(0, -1, 0))
-
- if ok := period.IsCurrentPeriod(quotaBucket); ok {
- Fail("Exprected true, returned: false")
- }
-
- //start time in period after now
- quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 1, 0), time.Now().UTC().AddDate(1, 1, 0))
-
- if ok := period.IsCurrentPeriod(quotaBucket); ok {
- Fail("Exprected true, returned: false")
- }
-
- //end time in period is before now
- quotaBucket.SetPeriod(time.Now().UTC().AddDate(-1, -1, 0), time.Now().UTC().AddDate(0, -1, 0))
-
- if ok := period.IsCurrentPeriod(quotaBucket); ok {
- Fail("Exprected true, returned: false")
- }
-
- })
-})
-
-var _ = Describe("Test GetPeriod and setCurrentPeriod", func() {
- It("Valid GetPeriod", func() {
- edgeOrgID := "sampleOrg"
- id := "sampleID"
- timeUnit := "hour"
- quotaType := "rollingwindow"
- interval := 1
- maxCount := int64(10)
- weight := int64(1)
- preciseAtSecondsLevel := true
- distributed := true
- synchronous := true
- syncTimeInSec := int64(-1)
- syncMessageCount := int64(-1)
-
- //InputStart time is before now
- startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
- quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 0, -1), time.Now().UTC().AddDate(0, 1, 0))
- err = quotaBucket.Validate()
- Expect(err).NotTo(HaveOccurred())
- qPeriod, err := quotaBucket.GetPeriod()
- Expect(err).NotTo(HaveOccurred())
-
- // check if the rolling window was set properly
- Expect(qPeriod.GetPeriodInputStartTime()).Should(Equal(quotaBucket.GetStartTime()))
- if !qPeriod.GetPeriodEndTime().After(qPeriod.GetPeriodStartTime()) {
- Fail("Rolling Window was not set as expected")
- }
- intervalDuration := qPeriod.GetPeriodEndTime().Sub(qPeriod.GetPeriodStartTime())
- expectedDuration, err := GetIntervalDurtation(quotaBucket)
- Expect(intervalDuration).Should(Equal(expectedDuration))
-
- //for non rolling Type window do not setCurrentPeriod as endTime is > time.now.
- quotaType = "calendar"
- pstartTime := time.Now().UTC().AddDate(0, -1, 0)
- pendTime := time.Now().UTC().AddDate(0, 1, 0)
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(pstartTime, pendTime)
- qPeriod, err = quotaBucket.GetPeriod()
- Expect(err).NotTo(HaveOccurred())
- // check if the calendar window was set properly
- Expect(qPeriod.GetPeriodInputStartTime()).Should(Equal(quotaBucket.GetStartTime()))
- if !qPeriod.GetPeriodEndTime().After(qPeriod.GetPeriodStartTime()) {
- Fail("Rolling Window was not set as expected")
- }
-
- //for non rolling Type window setCurrentPeriod as endTime is < time.now.
- quotaType = "calendar"
- pstartTime = time.Now().UTC().AddDate(0, -1, 0)
- pendTime = time.Now().UTC().AddDate(0, -1, 0)
- quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
- quotaType, preciseAtSecondsLevel, startTime, maxCount,
- weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
- Expect(err).NotTo(HaveOccurred())
-
- quotaBucket.SetPeriod(pstartTime, pendTime)
- qPeriod, err = quotaBucket.GetPeriod()
- Expect(err).NotTo(HaveOccurred())
- // check if the calendar window was set properly
- Expect(qPeriod.GetPeriodInputStartTime()).Should(Equal(quotaBucket.GetStartTime()))
- if !qPeriod.GetPeriodEndTime().After(qPeriod.GetPeriodStartTime()) {
- Fail("period for Non Rolling Window Type was not set as expected")
- }
- intervalDuration = qPeriod.GetPeriodEndTime().Sub(qPeriod.GetPeriodStartTime())
- expectedDuration, err = GetIntervalDurtation(quotaBucket)
- Expect(intervalDuration).Should(Equal(expectedDuration))
- })
-})
+//
+//import (
+// "github.com/30x/apidQuota/constants"
+// . "github.com/30x/apidQuota/quotaBucket"
+// . "github.com/onsi/ginkgo"
+// . "github.com/onsi/gomega"
+// "strings"
+// "time"
+//)
+//
+//var _ = Describe("Test QuotaPeriod", func() {
+// It("Valid NewQuotaPeriod", func() {
+// //startTime before endTime
+// period := NewQuotaPeriod(time.Now().UTC().AddDate(0, -1, 0).Unix(),
+// time.Now().UTC().AddDate(0, 0, -1).Unix(),
+// time.Now().UTC().AddDate(0, 1, 0).Unix())
+// isValid, err := period.Validate()
+//
+// if !isValid {
+// Fail("expected isValid true but got false")
+// }
+// if err != nil {
+// Fail("expected error <nil> but got " + err.Error())
+// }
+// })
+//
+// It("Invalid NewQuotaPeriod", func() {
+// //startTime after endTime
+// period := NewQuotaPeriod(time.Now().UTC().AddDate(0, -1, 0).Unix(),
+// time.Now().UTC().AddDate(0, 1, 0).Unix(),
+// time.Now().UTC().AddDate(0, 0, -1).Unix())
+// isValid, err := period.Validate()
+// if isValid {
+// Fail("Expected isValid false but got true")
+// }
+//
+// if err == nil {
+// Fail(" Expected error but got <nil>")
+// }
+//
+// //startTime same as endTime
+// period = NewQuotaPeriod(time.Now().UTC().AddDate(0, -1, 0).Unix(),
+// time.Now().UTC().AddDate(0, 1, 0).Unix(),
+// time.Now().UTC().AddDate(0, 1, 0).Unix())
+// isValid, err = period.Validate()
+// if isValid {
+// Fail("Expected isValid false but got true")
+// }
+//
+// if err == nil {
+// Fail(" Expected error but got <nil>")
+// }
+//
+// })
+//})
+//
+//var _ = Describe("Test AcceptedQuotaTimeUnitTypes", func() {
+// It("testTimeUnit", func() {
+// if !IsValidTimeUnit("second") {
+// Fail("Expected true: second is a valid TimeUnit")
+// }
+// if !IsValidTimeUnit("minute") {
+// Fail("Expected true: minute is a valid TimeUnit")
+// }
+// if !IsValidTimeUnit("hour") {
+// Fail("Expected true: hour is a valid TimeUnit")
+// }
+// if !IsValidTimeUnit("day") {
+// Fail("Expected true: day is a valid TimeUnit")
+// }
+// if !IsValidTimeUnit("week") {
+// Fail("Expected true: week is a valid TimeUnit")
+// }
+// if !IsValidTimeUnit("month") {
+// Fail("Expected true: month is a valid TimeUnit")
+// }
+//
+// //invalid type
+// if IsValidTimeUnit("invalidType") {
+// Fail("Expected false: invalidType is not a valid TimeUnit")
+// }
+// })
+//})
+//
+////Tests for QuotaBucket
+//var _ = Describe("QuotaBucket", func() {
+// It("Create with NewQuotaBucket", func() {
+// edgeOrgID := "sampleOrg"
+// id := "sampleID"
+// interval := 1
+// timeUnit := "hour"
+// quotaType := "calendar"
+// preciseAtSecondsLevel := true
+// maxCount := int64(10)
+// weight := int64(1)
+// distributed := true
+// synchronous := true
+// syncTimeInSec := int64(-1)
+// syncMessageCount := int64(-1)
+//
+// //start time before now()
+// startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
+//
+// quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+// now := time.Now().UTC()
+// currentHour := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, time.UTC)
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// //also check if all the fields are set as expected
+// sTime := time.Unix(startTime, 0)
+// Expect(sTime).To(Equal(quotaBucket.GetStartTime()))
+// Expect(edgeOrgID).To(Equal(quotaBucket.GetEdgeOrgID()))
+// Expect(id).To(Equal(quotaBucket.GetID()))
+// Expect(timeUnit).To(Equal(quotaBucket.GetTimeUnit()))
+// Expect(quotaType).To(Equal(quotaBucket.GetType()))
+// Expect(interval).To(Equal(quotaBucket.GetInterval()))
+// Expect(maxCount).To(Equal(quotaBucket.GetMaxCount()))
+// Expect(preciseAtSecondsLevel).To(Equal(quotaBucket.GetIsPreciseAtSecondsLevel()))
+// getPeriod, err := quotaBucket.GetPeriod()
+// Expect(err).NotTo(HaveOccurred())
+// Expect(getPeriod.GetPeriodInputStartTime().String()).ShouldNot(BeEmpty())
+// Expect(getPeriod.GetPeriodStartTime().String()).ShouldNot(BeEmpty())
+// Expect(getPeriod.GetPeriodEndTime().String()).ShouldNot(BeEmpty())
+// Expect(getPeriod.GetPeriodStartTime().String()).Should(Equal(currentHour.String()))
+// Expect(getPeriod.GetPeriodEndTime().String()).Should(Equal(currentHour.Add(time.Hour).String()))
+//
+// //start time is after now() -> should still set period.
+// startTime = time.Now().UTC().AddDate(0, 1, 0).Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// now = time.Now().UTC()
+// currentHour = time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, time.UTC)
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// getPeriod, err = quotaBucket.GetPeriod()
+// Expect(err).NotTo(HaveOccurred())
+// Expect(getPeriod.GetPeriodInputStartTime().String()).ShouldNot(BeEmpty())
+// Expect(getPeriod.GetPeriodStartTime().String()).ShouldNot(BeEmpty())
+// Expect(getPeriod.GetPeriodEndTime().String()).ShouldNot(BeEmpty())
+// Expect(getPeriod.GetPeriodStartTime().String()).Should(Equal(currentHour.String()))
+// Expect(getPeriod.GetPeriodEndTime().String()).Should(Equal(currentHour.Add(time.Hour).String()))
+//
+// })
+//
+// //end before start
+// It("Test invalid quotaPeriod", func() {
+// edgeOrgID := "sampleOrg"
+// id := "sampleID"
+// timeUnit := "hour"
+// quotaType := "calendar"
+// interval := 1
+// maxCount := int64(10)
+// weight := int64(1)
+// preciseAtSecondsLevel := true
+// startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
+// distributed := true
+// synchronous := true
+// syncTimeInSec := int64(-1)
+// syncMessageCount := int64(-1)
+//
+// quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 1, 0), time.Now().UTC().AddDate(0, 0, -1))
+// err = quotaBucket.Validate()
+// if err == nil {
+// Fail("error expected but got <nil>")
+// }
+// if !strings.Contains(err.Error(), constants.InvalidQuotaPeriod) {
+// Fail("expected: " + constants.InvalidQuotaPeriod + " in the error but got: " + err.Error())
+// }
+//
+// })
+//
+// It("Test invalid timeUnitType", func() {
+// edgeOrgID := "sampleOrg"
+// id := "sampleID"
+// timeUnit := "invalidTimeUnit"
+// quotaType := "calendar"
+// interval := 1
+// maxCount := int64(10)
+// weight := int64(1)
+// preciseAtSecondsLevel := true
+// startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
+// distributed := true
+// synchronous := true
+// syncTimeInSec := int64(-1)
+// syncMessageCount := int64(-1)
+//
+// quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).To(HaveOccurred())
+//
+// if !strings.Contains(err.Error(), constants.InvalidQuotaTimeUnitType) {
+// Fail("expected: " + constants.InvalidQuotaTimeUnitType + "but got: " + err.Error())
+// }
+// if quotaBucket != nil {
+// Fail("quotaBucket returned should be nil.")
+// }
+//
+// })
+//
+//})
+//
+//var _ = Describe("IsCurrentPeriod", func() {
+// It("Test IsCurrentPeriod for RollingType Window - Valid TestCase", func() {
+//
+// edgeOrgID := "sampleOrg"
+// id := "sampleID"
+// timeUnit := "hour"
+// quotaType := "rollingwindow"
+// interval := 1
+// maxCount := int64(10)
+// weight := int64(1)
+// preciseAtSecondsLevel := true
+// distributed := true
+// synchronous := true
+// syncTimeInSec := int64(-1)
+// syncMessageCount := int64(-1)
+//
+// //InputStart time is before now
+// startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
+//
+// quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// period, err := quotaBucket.GetPeriod()
+// if err != nil {
+// Fail("no error expected")
+// }
+// if ok := period.IsCurrentPeriod(quotaBucket); !ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //InputStart time is now
+// startTime = time.Now().UTC().Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// period, err = quotaBucket.GetPeriod()
+// if err != nil {
+// Fail("no error expected")
+// }
+// period.IsCurrentPeriod(quotaBucket)
+// if ok := period.IsCurrentPeriod(quotaBucket); !ok {
+// Fail("Exprected true, returned: false")
+// }
+// })
+//
+// It("Test IsCurrentPeriod for RollingType Window - InValid TestCase", func() {
+//
+// edgeOrgID := "sampleOrg"
+// id := "sampleID"
+// timeUnit := "hour"
+// quotaType := "rollingwindow"
+// interval := 1
+// maxCount := int64(10)
+// weight := int64(1)
+// preciseAtSecondsLevel := true
+// //InputStart time is after now.
+// startTime := time.Now().UTC().AddDate(0, 1, 0).Unix()
+// distributed := true
+// synchronous := true
+// syncTimeInSec := int64(-1)
+// syncMessageCount := int64(-1)
+//
+// quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, -1, 0), time.Now().UTC().AddDate(0, 0, 1))
+// period, err := quotaBucket.GetPeriod()
+// Expect(err).NotTo(HaveOccurred())
+// if ok := period.IsCurrentPeriod(quotaBucket); ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //endTime before startTime in period
+// startTime = time.Now().UTC().AddDate(0, -1, 0).Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(time.Now().UTC(), time.Now().UTC().AddDate(0, -1, 0))
+// if ok := period.IsCurrentPeriod(quotaBucket); ok {
+// Fail("Exprected false, returned: true")
+// }
+// })
+//
+// It("Test IsCurrentPeriod for calendarType Window - Valid TestCases", func() {
+//
+// edgeOrgID := "sampleOrg"
+// id := "sampleID"
+// timeUnit := "hour"
+// quotaType := "calendar"
+// interval := 1
+// maxCount := int64(10)
+// weight := int64(1)
+// preciseAtSecondsLevel := true
+// distributed := true
+// synchronous := true
+// syncTimeInSec := int64(-1)
+// syncMessageCount := int64(-1)
+//
+// //InputStart time is before now
+// startTime := time.Now().UTC().UTC().AddDate(-1, -1, 0).Unix()
+//
+// quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// period, err := quotaBucket.GetPeriod()
+// if err != nil {
+// Fail("no error expected but returned " + err.Error())
+// }
+// if ok := period.IsCurrentPeriod(quotaBucket); !ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //InputStart time is now
+// startTime = time.Now().UTC().Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// period, err = quotaBucket.GetPeriod()
+// if err != nil {
+// Fail("no error expected but returned " + err.Error())
+// }
+// period.IsCurrentPeriod(quotaBucket)
+// if ok := period.IsCurrentPeriod(quotaBucket); !ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //start Time in period is before now
+// startTime = time.Now().UTC().Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 0, -1),
+// time.Now().UTC().AddDate(0, 1, 0))
+// period, err = quotaBucket.GetPeriod()
+// if err != nil {
+// Fail("no error expected but returned " + err.Error())
+// }
+// period.IsCurrentPeriod(quotaBucket)
+// if ok := period.IsCurrentPeriod(quotaBucket); !ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //start Time in period is now
+// startTime = time.Now().UTC().Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+// quotaBucket.SetPeriod(time.Now().UTC(),
+// time.Now().UTC().AddDate(0, 1, 0))
+// period, err = quotaBucket.GetPeriod()
+// if err != nil {
+// Fail("no error expected but returned " + err.Error())
+// }
+// period.IsCurrentPeriod(quotaBucket)
+// if ok := period.IsCurrentPeriod(quotaBucket); !ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //end Time in period is after now
+// startTime = time.Now().UTC().Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 0, -1),
+// time.Now().UTC().AddDate(0, 1, 0))
+// period, err = quotaBucket.GetPeriod()
+// if err != nil {
+// Fail("no error expected but returned " + err.Error())
+// }
+//
+// period.IsCurrentPeriod(quotaBucket)
+// if ok := period.IsCurrentPeriod(quotaBucket); !ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //start time in period is before end time
+// startTime = time.Now().UTC().Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+// quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 0, -1),
+// time.Now().UTC().AddDate(0, 1, 0))
+// period, err = quotaBucket.GetPeriod()
+// if err != nil {
+// Fail("no error expected but returned " + err.Error())
+// }
+// period.IsCurrentPeriod(quotaBucket)
+// if ok := period.IsCurrentPeriod(quotaBucket); !ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// })
+//
+// It("Test IsCurrentPeriod for calendarType Window InValid TestCase", func() {
+//
+// edgeOrgID := "sampleOrg"
+// id := "sampleID"
+// timeUnit := "hour"
+// quotaType := "calendar"
+// interval := 1
+// maxCount := int64(10)
+// weight := int64(1)
+// preciseAtSecondsLevel := true
+// distributed := true
+// synchronous := true
+// syncTimeInSec := int64(-1)
+// syncMessageCount := int64(-1)
+//
+// //InputStart time is after now.
+// period := NewQuotaPeriod(time.Now().UTC().AddDate(0, 1, 0).Unix(),
+// time.Now().UTC().AddDate(0, 1, 0).Unix(), time.Now().AddDate(1, 0, 1).Unix())
+// startTime := time.Now().UTC().AddDate(0, 1, 0).Unix()
+//
+// quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// if ok := period.IsCurrentPeriod(quotaBucket); ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //endTime is before start time
+// startTime = time.Now().UTC().AddDate(0, -1, 0).Unix()
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(time.Now().UTC(), time.Now().UTC().AddDate(0, -1, 0))
+//
+// if ok := period.IsCurrentPeriod(quotaBucket); ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //start time in period after now
+// quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 1, 0), time.Now().UTC().AddDate(1, 1, 0))
+//
+// if ok := period.IsCurrentPeriod(quotaBucket); ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// //end time in period is before now
+// quotaBucket.SetPeriod(time.Now().UTC().AddDate(-1, -1, 0), time.Now().UTC().AddDate(0, -1, 0))
+//
+// if ok := period.IsCurrentPeriod(quotaBucket); ok {
+// Fail("Exprected true, returned: false")
+// }
+//
+// })
+//})
+//
+//var _ = Describe("Test GetPeriod and setCurrentPeriod", func() {
+// It("Valid GetPeriod", func() {
+// edgeOrgID := "sampleOrg"
+// id := "sampleID"
+// timeUnit := "hour"
+// quotaType := "rollingwindow"
+// interval := 1
+// maxCount := int64(10)
+// weight := int64(1)
+// preciseAtSecondsLevel := true
+// distributed := true
+// synchronous := true
+// syncTimeInSec := int64(-1)
+// syncMessageCount := int64(-1)
+//
+// //InputStart time is before now
+// startTime := time.Now().UTC().AddDate(0, -1, 0).Unix()
+// quotaBucket, err := NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(time.Now().UTC().AddDate(0, 0, -1), time.Now().UTC().AddDate(0, 1, 0))
+// err = quotaBucket.Validate()
+// Expect(err).NotTo(HaveOccurred())
+// qPeriod, err := quotaBucket.GetPeriod()
+// Expect(err).NotTo(HaveOccurred())
+//
+// // check if the rolling window was set properly
+// Expect(qPeriod.GetPeriodInputStartTime()).Should(Equal(quotaBucket.GetStartTime()))
+// if !qPeriod.GetPeriodEndTime().After(qPeriod.GetPeriodStartTime()) {
+// Fail("Rolling Window was not set as expected")
+// }
+// intervalDuration := qPeriod.GetPeriodEndTime().Sub(qPeriod.GetPeriodStartTime())
+// expectedDuration, err := GetIntervalDurtation(quotaBucket)
+// Expect(intervalDuration).Should(Equal(expectedDuration))
+//
+// //for non rolling Type window do not setCurrentPeriod as endTime is > time.now.
+// quotaType = "calendar"
+// pstartTime := time.Now().UTC().AddDate(0, -1, 0)
+// pendTime := time.Now().UTC().AddDate(0, 1, 0)
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(pstartTime, pendTime)
+// qPeriod, err = quotaBucket.GetPeriod()
+// Expect(err).NotTo(HaveOccurred())
+// // check if the calendar window was set properly
+// Expect(qPeriod.GetPeriodInputStartTime()).Should(Equal(quotaBucket.GetStartTime()))
+// if !qPeriod.GetPeriodEndTime().After(qPeriod.GetPeriodStartTime()) {
+// Fail("Rolling Window was not set as expected")
+// }
+//
+// //for non rolling Type window setCurrentPeriod as endTime is < time.now.
+// quotaType = "calendar"
+// pstartTime = time.Now().UTC().AddDate(0, -1, 0)
+// pendTime = time.Now().UTC().AddDate(0, -1, 0)
+// quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
+// quotaType, preciseAtSecondsLevel, startTime, maxCount,
+// weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+// Expect(err).NotTo(HaveOccurred())
+//
+// quotaBucket.SetPeriod(pstartTime, pendTime)
+// qPeriod, err = quotaBucket.GetPeriod()
+// Expect(err).NotTo(HaveOccurred())
+// // check if the calendar window was set properly
+// Expect(qPeriod.GetPeriodInputStartTime()).Should(Equal(quotaBucket.GetStartTime()))
+// if !qPeriod.GetPeriodEndTime().After(qPeriod.GetPeriodStartTime()) {
+// Fail("period for Non Rolling Window Type was not set as expected")
+// }
+// intervalDuration = qPeriod.GetPeriodEndTime().Sub(qPeriod.GetPeriodStartTime())
+// expectedDuration, err = GetIntervalDurtation(quotaBucket)
+// Expect(intervalDuration).Should(Equal(expectedDuration))
+// })
+//})
diff --git a/quotaBucket/quotaCache.go b/quotaBucket/quotaCache.go
index 4c8338e..6dbc04a 100644
--- a/quotaBucket/quotaCache.go
+++ b/quotaBucket/quotaCache.go
@@ -2,8 +2,8 @@
import (
"github.com/30x/apidQuota/constants"
- "time"
"sync"
+ "time"
)
var quotaCachelock = sync.RWMutex{}
@@ -19,44 +19,57 @@
quotaCache = make(map[string]quotaBucketCache)
}
-func getFromCache(cacheKey string) (*QuotaBucket,bool) {
+func getFromCache(cacheKey string, weight int64) (*QuotaBucket, bool) {
quotaCachelock.Lock()
- defer quotaCachelock.Unlock()
qBucketCache, ok := quotaCache[cacheKey]
+ quotaCachelock.Unlock()
+
if !ok {
- return nil,false
+ return nil, false
}
isExpired := time.Unix(qBucketCache.expiryTime, 0).Before(time.Now().UTC())
if isExpired {
+
removeFromCache(cacheKey, qBucketCache)
return nil, false
}
// update expiry time every time you access.
+ qBucketCache.qBucket.Weight = weight
ttl := time.Now().UTC().Add(constants.CacheTTL).Unix()
qBucketCache.expiryTime = ttl
+
+ quotaCachelock.Lock()
quotaCache[cacheKey] = qBucketCache
+ quotaCachelock.Unlock()
return qBucketCache.qBucket, true
}
-func removeFromCache(cacheKey string, qBucketCache quotaBucketCache) {
+func removeFromCache(cacheKey string, qBucketCache quotaBucketCache) error {
//for async Stop the scheduler.
- if qBucketCache.qBucket.Distributed && !qBucketCache.qBucket.IsSynchronous(){
- qBucketCache.qBucket.getTicker().Stop()
+
+ if qBucketCache.qBucket.Distributed && !qBucketCache.qBucket.IsSynchronous() {
+ aSyncBucket := qBucketCache.qBucket.GetAsyncQuotaBucket()
+ qticker, err := aSyncBucket.getAsyncQTicker()
+ if err != nil {
+ return err
+ }
+ qticker.Stop()
}
quotaCachelock.Lock()
- delete(quotaCache,cacheKey)
+ delete(quotaCache, cacheKey)
quotaCachelock.Unlock()
+ return nil
}
func addToCache(qBucketToAdd *QuotaBucket) {
+
cacheKey := qBucketToAdd.GetEdgeOrgID() + constants.CacheKeyDelimiter + qBucketToAdd.GetID()
ttl := time.Now().UTC().Add(constants.CacheTTL).Unix()
-
qCacheData := quotaBucketCache{
qBucket: qBucketToAdd,
expiryTime: ttl,
diff --git a/quotaBucket/quotaDescriptorType.go b/quotaBucket/quotaDescriptorType.go
index af25b56..d910c0e 100644
--- a/quotaBucket/quotaDescriptorType.go
+++ b/quotaBucket/quotaDescriptorType.go
@@ -8,7 +8,7 @@
)
type QuotaDescriptorType interface {
- SetCurrentPeriod(bucket *QuotaBucket) error
+ GetCurrentPeriod(bucket *QuotaBucket) (*quotaPeriod, error)
}
func GetQuotaTypeHandler(qType string) (QuotaDescriptorType, error) {
@@ -29,29 +29,7 @@
type CalendarQuotaDescriptorType struct{}
-func (c CalendarQuotaDescriptorType) SetCurrentPeriod(qbucket *QuotaBucket) error {
- startTime := qbucket.GetStartTime()
- currentPeriod, err := qbucket.GetQuotaBucketPeriod()
- if err != nil {
- return err
- }
- if startTime.Before(time.Now().UTC()) || startTime.Equal(time.Now().UTC()) {
- if currentPeriod != nil {
- if currentPeriod.IsCurrentPeriod(qbucket) {
- return nil
- }
- } else {
- if currentPeriod.IsCurrentPeriod(qbucket) {
- return nil
- } else {
- qBucketHandler, err := GetQuotaBucketHandler(qbucket)
- if err != nil {
- return errors.New("error retrieving qBucketHandler: " + err.Error())
- }
- qBucketHandler.resetCount(qbucket)
- }
- }
- }
+func (c *CalendarQuotaDescriptorType) GetCurrentPeriod(qbucket *QuotaBucket) (*quotaPeriod, error) {
var currentStart, currentEnd time.Time
now := time.Now().UTC()
@@ -78,7 +56,6 @@
currentEnd = currentStart.AddDate(0, 0, 1*qbucket.Interval)
break
case constants.TimeUnitWEEK:
- //todo
currentStart = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
for currentStart.Weekday() != time.Monday {
currentStart = currentStart.AddDate(0, 0, -1)
@@ -90,29 +67,34 @@
currentEnd = currentStart.AddDate(0, qbucket.Interval, 0)
break
default:
- return errors.New(constants.InvalidQuotaTimeUnitType + " : ignoring unrecognized timeUnit : " + timeUnit)
+ return nil, errors.New(constants.InvalidQuotaTimeUnitType + " : ignoring unrecognized timeUnit : " + timeUnit)
}
- qbucket.SetPeriod(currentStart, currentEnd)
- return nil
+ return "aPeriod{
+ inputStartTime: qbucket.GetStartTime(),
+ startTime: currentStart,
+ endTime: currentEnd,
+ }, nil
}
type RollingWindowQuotaDescriptorType struct{}
-func (c RollingWindowQuotaDescriptorType) SetCurrentPeriod(qbucket *QuotaBucket) error {
+func (c *RollingWindowQuotaDescriptorType) GetCurrentPeriod(qbucket *QuotaBucket) (*quotaPeriod, error) {
//yet to implement
var currentStart, currentEnd time.Time
currentEnd = time.Now().UTC()
interval, err := GetIntervalDurtation(qbucket)
if err != nil {
- return errors.New("error in SetCurrentPeriod: " + err.Error())
+ return nil, errors.New("error in SetCurrentPeriod: " + err.Error())
}
currentStart = currentEnd.Add(-interval)
- qbucket.SetPeriod(currentStart, currentEnd)
-
- return nil
+ return "aPeriod{
+ inputStartTime: qbucket.GetStartTime(),
+ startTime: currentStart,
+ endTime: currentEnd,
+ }, nil
}
func GetIntervalDurtation(qb *QuotaBucket) (time.Duration, error) {
diff --git a/quotaBucket/quotaDescriptorType_test.go b/quotaBucket/quotaDescriptorType_test.go
index ee85724..26316f4 100644
--- a/quotaBucket/quotaDescriptorType_test.go
+++ b/quotaBucket/quotaDescriptorType_test.go
@@ -236,6 +236,7 @@
quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
quotaType, preciseAtSecondsLevel, startTime, maxCount,
weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+ err = quotaBucket.Validate()
Expect(err).To(HaveOccurred())
if ok := strings.Contains(err.Error(), constants.InvalidQuotaTimeUnitType); !ok {
Fail("expected error to contain " + constants.InvalidQuotaTimeUnitType + " but got different error message: " + err.Error())
@@ -442,6 +443,7 @@
quotaBucket, err = NewQuotaBucket(edgeOrgID, id, interval, timeUnit,
quotaType, preciseAtSecondsLevel, startTime, maxCount,
weight, distributed, synchronous, syncTimeInSec, syncMessageCount)
+ err = quotaBucket.Validate()
Expect(err).To(HaveOccurred())
if ok := strings.Contains(err.Error(), constants.InvalidQuotaTimeUnitType); !ok {
Fail("expected error to contain " + constants.InvalidQuotaTimeUnitType + " but got different error message: " + err.Error())