From 1ab29298fc371daffb747752d88f7f23fffe218c Mon Sep 17 00:00:00 2001 From: Vikhyat Bhatnagar <52795644+vikhyat187@users.noreply.github.com> Date: Tue, 3 Oct 2023 00:24:28 +0530 Subject: [PATCH] Adding the utils and constants (#76) * Adding the utils and constants * Stored table name in variable, instead of hardcoding * Adding early return statement in case of failure --------- Co-authored-by: vikhyat --- models/request-quota.go | 6 +++ utils/CheckRequestAllowed.go | 97 ++++++++++++++++++++++++++++++++++++ utils/Constants.go | 1 + 3 files changed, 104 insertions(+) create mode 100644 models/request-quota.go create mode 100644 utils/CheckRequestAllowed.go diff --git a/models/request-quota.go b/models/request-quota.go new file mode 100644 index 0000000..8cc193d --- /dev/null +++ b/models/request-quota.go @@ -0,0 +1,6 @@ +package models + +type RequestLimit struct { + LimitType string `json:"limitType" dynamodbav:"limitType"` + LimitValue int16 `json:"limitValue" dynamodbav:"limitValue"` +} \ No newline at end of file diff --git a/utils/CheckRequestAllowed.go b/utils/CheckRequestAllowed.go new file mode 100644 index 0000000..a2a9794 --- /dev/null +++ b/utils/CheckRequestAllowed.go @@ -0,0 +1,97 @@ +package utils + +import ( + "fmt" + "log" + "os" + + "github.com/Real-Dev-Squad/feature-flag-backend/models" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + lambdaInvoke "github.com/aws/aws-sdk-go/service/lambda" +) + +var raterLimiterFunctionName string +var found bool +var requestLimitTableName = "requestLimit" + +func init() { + raterLimiterFunctionName, found = os.LookupEnv("RateLimiterFunction") + if !found { + log.Println("Rate limiter function name is not found") + } +} + +func CheckRequestAllowed(db *dynamodb.DynamoDB, concurrencyValue int) { + // check the quota values + requestLimitInput := &dynamodb.GetItemInput{ + TableName: aws.String(requestLimitTableName), + Key: map[string]*dynamodb.AttributeValue{ + "limitType": { + S: aws.String("pendingLimit"), + }, + }, + } + + requestLimitResult, err := db.GetItem(requestLimitInput) + if err != nil { + log.Println(err, "is the error in request limit fetching") + } + + requestLimitResponse := new(models.RequestLimit) + err = dynamodbattribute.UnmarshalMap(requestLimitResult.Item, requestLimitResponse) + + if err != nil { + log.Println(err, "is the error") + } + + if requestLimitResponse.LimitValue > 1 { + // reducing the request quota limit + requestLimitUpdateInput := models.RequestLimit{ + LimitType: requestLimitResponse.LimitType, + LimitValue: requestLimitResponse.LimitValue - 1, + } + + marshalledInput, err := dynamodbattribute.MarshalMap(requestLimitUpdateInput) + if err != nil { + log.Println("Error in marshalling the request") + } + + putItemInput := &dynamodb.PutItemInput{ + TableName: aws.String(requestLimitTableName), + Item: marshalledInput, + } + + _, err = db.PutItem(putItemInput) + if err != nil { + log.Println("Error in updating the request limit counters", err) + return + } + log.Println("The updated limit is ", requestLimitUpdateInput.LimitValue) + } else { + //mark the concurrency of all the other lambdas to zero + sess, err := session.NewSession() + + if err != nil { + log.Println("Error in creating AWS session to access any service") + ServerError(err) + } + lambdaClient := lambdaInvoke.New(sess) + + concurrencyValue := 0 + lambdaInvokeInput := lambdaInvoke.InvokeInput{ + FunctionName: aws.String(raterLimiterFunctionName), + Payload: []byte(fmt.Sprintf(`{"intValue" : %d}`, concurrencyValue)), + } + result, err := lambdaClient.Invoke(&lambdaInvokeInput) + if err != nil { + log.Println("There is some error in calling the new lambda created") + ServerError(err) + } + + log.Println("The result of the invocation of the another lambda is ", result) + + } +} diff --git a/utils/Constants.go b/utils/Constants.go index c4a14aa..d18bcab 100644 --- a/utils/Constants.go +++ b/utils/Constants.go @@ -19,4 +19,5 @@ const ( UpdatedAt = "updatedAt" UserId = "userId" FlagId = "flagId" + ConcurrencyDisablingLambda = 0 )