Skip to content

Commit

Permalink
Add ListQueuesV1 for JSON support
Browse files Browse the repository at this point in the history
  • Loading branch information
dhumphreys01 authored and Admiral-Piett committed Sep 20, 2024
1 parent a86ab6c commit da44977
Show file tree
Hide file tree
Showing 20 changed files with 869 additions and 479 deletions.
13 changes: 13 additions & 0 deletions app/conf/mock-data/mock-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,16 @@ NoQueueAttributeDefaults:
- Name: local-queue1
- Name: local-queue2
ReceiveMessageWaitTimeSeconds: 20

BaseUnitTests:
# (i.e.: ./goaws [Local | Dev] -- defaults to 'Local')
Host: host # hostname of the goaws system (for docker-compose this is the tag name of the container)
Port: port # port to listen on.
Region: region
AccountId: accountID
LogMessages: true # Log messages (true/false)
LogFile: ./goaws_messages.log # Log filename (for message logging
Queues: # List of queues to create at startup
- Name: unit-queue1 # Queue name
- Name: unit-queue2 # Queue name
- Name: other-queue1 # Queue name
1 change: 0 additions & 1 deletion app/fixtures/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ package fixtures
var BASE_URL = "http://region.host:port/accountID"
var BASE_ARN = "arn:aws:sqs:region:accountID"

var XMLNS = "http://queue.amazonaws.com/doc/2012-11-05/"
var REQUEST_ID = "request-id"
21 changes: 15 additions & 6 deletions app/fixtures/sqs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package fixtures
import (
"fmt"

"github.com/Admiral-Piett/goaws/app"

"github.com/Admiral-Piett/goaws/app/models"
)

Expand Down Expand Up @@ -36,9 +34,20 @@ var CreateQueueResult = models.CreateQueueResult{
}

var CreateQueueResponse = models.CreateQueueResponse{
Xmlns: "http://queue.amazonaws.com/doc/2012-11-05/",
Result: CreateQueueResult,
Metadata: app.ResponseMetadata{
RequestId: "00000000-0000-0000-0000-000000000000",
Xmlns: models.BASE_XMLNS,
Result: CreateQueueResult,
Metadata: models.BASE_RESPONSE_METADATA,
}

var ListQueuesResult = models.ListQueuesResult{
QueueUrls: []string{
fmt.Sprintf("%s/%s", BASE_URL, "unit-queue1"),
fmt.Sprintf("%s/%s", BASE_URL, "unit-queue2"),
},
}

var ListQueuesResponse = models.ListQueuesResponse{
Xmlns: models.BASE_XMLNS,
Result: ListQueuesResult,
Metadata: models.BASE_RESPONSE_METADATA,
}
55 changes: 55 additions & 0 deletions app/gosqs/create_queue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package gosqs

import (
"net/http"
"time"

"github.com/Admiral-Piett/goaws/app"
"github.com/Admiral-Piett/goaws/app/interfaces"
"github.com/Admiral-Piett/goaws/app/models"
"github.com/Admiral-Piett/goaws/app/utils"
log "github.com/sirupsen/logrus"
)

func CreateQueueV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
requestBody := models.NewCreateQueueRequest()
ok := utils.REQUEST_TRANSFORMER(requestBody, req)
if !ok {
log.Error("Invalid Request - CreateQueueV1")
return createErrorResponseV1(ErrInvalidParameterValue.Type)
}
queueName := requestBody.QueueName

queueUrl := "http://" + app.CurrentEnvironment.Host + ":" + app.CurrentEnvironment.Port +
"/" + app.CurrentEnvironment.AccountID + "/" + queueName
if app.CurrentEnvironment.Region != "" {
queueUrl = "http://" + app.CurrentEnvironment.Region + "." + app.CurrentEnvironment.Host + ":" +
app.CurrentEnvironment.Port + "/" + app.CurrentEnvironment.AccountID + "/" + queueName
}
queueArn := "arn:aws:sqs:" + app.CurrentEnvironment.Region + ":" + app.CurrentEnvironment.AccountID + ":" + queueName

if _, ok := app.SyncQueues.Queues[queueName]; !ok {
log.Println("Creating Queue:", queueName)
queue := &app.Queue{
Name: queueName,
URL: queueUrl,
Arn: queueArn,
IsFIFO: app.HasFIFOQueueName(queueName),
EnableDuplicates: app.CurrentEnvironment.EnableDuplicates,
Duplicates: make(map[string]time.Time),
}
if err := setQueueAttributesV1(queue, requestBody.Attributes); err != nil {
return createErrorResponseV1(err.Error())
}
app.SyncQueues.Lock()
app.SyncQueues.Queues[queueName] = queue
app.SyncQueues.Unlock()
}

respStruct := models.CreateQueueResponse{
Xmlns: models.BASE_XMLNS,
Result: models.CreateQueueResult{QueueUrl: queueUrl},
Metadata: models.BASE_RESPONSE_METADATA,
}
return http.StatusOK, respStruct
}
280 changes: 280 additions & 0 deletions app/gosqs/create_queue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
package gosqs

import (
"fmt"
"net/http"
"testing"
"time"

"github.com/mitchellh/copystructure"

"github.com/Admiral-Piett/goaws/app/models"

"github.com/Admiral-Piett/goaws/app/interfaces"

"github.com/Admiral-Piett/goaws/app/utils"
"github.com/stretchr/testify/assert"

"github.com/Admiral-Piett/goaws/app/fixtures"

"github.com/Admiral-Piett/goaws/app"
)

func TestCreateQueueV1_success(t *testing.T) {
app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT
defer func() {
utils.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
v := resultingStruct.(*models.CreateQueueRequest)
*v = fixtures.CreateQueueRequest
return true
}

expectedQueue := &app.Queue{
Name: fixtures.QueueName,
URL: fmt.Sprintf("http://%s.%s:%s/%s/%s",
fixtures.LOCAL_ENVIRONMENT.Region,
fixtures.LOCAL_ENVIRONMENT.Host,
fixtures.LOCAL_ENVIRONMENT.Port,
fixtures.LOCAL_ENVIRONMENT.AccountID,
fixtures.QueueName,
),
Arn: fmt.Sprintf("arn:aws:sqs:%s:%s:%s",
fixtures.LOCAL_ENVIRONMENT.Region,
fixtures.LOCAL_ENVIRONMENT.AccountID,
fixtures.QueueName,
),
VisibilityTimeout: 5,
ReceiveMessageWaitTimeSeconds: 4,
DelaySeconds: 1,
MaximumMessageSize: 2,
MessageRetentionPeriod: 3,
Duplicates: make(map[string]time.Time),
}

_, r := utils.GenerateRequestInfo("POST", "/", nil, true)
code, response := CreateQueueV1(r)

assert.Equal(t, http.StatusOK, code)
assert.Equal(t, fixtures.CreateQueueResponse, response)

actualQueue := app.SyncQueues.Queues[fixtures.QueueName]
assert.Equal(t, expectedQueue, actualQueue)
}

func TestCreateQueueV1_success_with_redrive_policy(t *testing.T) {
app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT
defer func() {
utils.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
dupe, _ := copystructure.Copy(fixtures.CreateQueueRequest)
c, _ := dupe.(models.CreateQueueRequest)
c.Attributes.RedrivePolicy = models.RedrivePolicy{
MaxReceiveCount: 100,
DeadLetterTargetArn: fmt.Sprintf("arn:aws:sqs:us-east-1:100010001000:%s", fixtures.DeadLetterQueueName),
}

v := resultingStruct.(*models.CreateQueueRequest)
*v = c
return true
}

dlq := &app.Queue{
Name: fixtures.DeadLetterQueueName,
}
app.SyncQueues.Queues[fixtures.DeadLetterQueueName] = dlq

expectedQueue := &app.Queue{
Name: fixtures.QueueName,
URL: fmt.Sprintf("http://%s.%s:%s/%s/%s",
fixtures.LOCAL_ENVIRONMENT.Region,
fixtures.LOCAL_ENVIRONMENT.Host,
fixtures.LOCAL_ENVIRONMENT.Port,
fixtures.LOCAL_ENVIRONMENT.AccountID,
fixtures.QueueName,
),
Arn: fmt.Sprintf("arn:aws:sqs:%s:%s:%s",
fixtures.LOCAL_ENVIRONMENT.Region,
fixtures.LOCAL_ENVIRONMENT.AccountID,
fixtures.QueueName,
),
VisibilityTimeout: 5,
ReceiveMessageWaitTimeSeconds: 4,
DelaySeconds: 1,
MaximumMessageSize: 2,
MessageRetentionPeriod: 3,
DeadLetterQueue: dlq,
MaxReceiveCount: 100,
Duplicates: make(map[string]time.Time),
}

_, r := utils.GenerateRequestInfo("POST", "/", nil, true)
code, response := CreateQueueV1(r)

assert.Equal(t, http.StatusOK, code)
assert.Equal(t, fixtures.CreateQueueResponse, response)

actualQueue := app.SyncQueues.Queues[fixtures.QueueName]
assert.Equal(t, expectedQueue, actualQueue)
}

func TestCreateQueueV1_success_with_existing_queue(t *testing.T) {
app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT
defer func() {
utils.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
v := resultingStruct.(*models.CreateQueueRequest)
*v = fixtures.CreateQueueRequest
return true
}

q := &app.Queue{
Name: fixtures.QueueName,
}
app.SyncQueues.Queues[fixtures.QueueName] = q

_, r := utils.GenerateRequestInfo("POST", "/", nil, true)
code, response := CreateQueueV1(r)

assert.Equal(t, http.StatusOK, code)
assert.Equal(t, fixtures.CreateQueueResponse, response)

actualQueue := app.SyncQueues.Queues[fixtures.QueueName]
assert.Equal(t, q, actualQueue)
}

func TestCreateQueueV1_success_with_no_request_attributes_falls_back_to_default(t *testing.T) {
app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT
defer func() {
utils.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
dupe, _ := copystructure.Copy(fixtures.CreateQueueRequest)
c, _ := dupe.(models.CreateQueueRequest)
c.Attributes = models.Attributes{}

v := resultingStruct.(*models.CreateQueueRequest)
*v = c
return true
}

expectedQueue := &app.Queue{
Name: fixtures.QueueName,
URL: fmt.Sprintf("http://%s.%s:%s/%s/%s",
fixtures.LOCAL_ENVIRONMENT.Region,
fixtures.LOCAL_ENVIRONMENT.Host,
fixtures.LOCAL_ENVIRONMENT.Port,
fixtures.LOCAL_ENVIRONMENT.AccountID,
fixtures.QueueName,
),
Arn: fmt.Sprintf("arn:aws:sqs:%s:%s:%s",
fixtures.LOCAL_ENVIRONMENT.Region,
fixtures.LOCAL_ENVIRONMENT.AccountID,
fixtures.QueueName,
),
VisibilityTimeout: 0,
ReceiveMessageWaitTimeSeconds: 0,
DelaySeconds: 0,
MaximumMessageSize: 0,
MessageRetentionPeriod: 0,
Duplicates: make(map[string]time.Time),
}

_, r := utils.GenerateRequestInfo("POST", "/", nil, true)
code, response := CreateQueueV1(r)

assert.Equal(t, http.StatusOK, code)
assert.Equal(t, fixtures.CreateQueueResponse, response)

actualQueue := app.SyncQueues.Queues[fixtures.QueueName]
assert.Equal(t, expectedQueue, actualQueue)
}

func TestCreateQueueV1_success_no_configured_region_for_queue_url(t *testing.T) {
app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT
app.CurrentEnvironment.Region = ""
defer func() {
utils.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
dupe, _ := copystructure.Copy(fixtures.CreateQueueRequest)
c, _ := dupe.(models.CreateQueueRequest)
c.Attributes = models.Attributes{}

v := resultingStruct.(*models.CreateQueueRequest)
*v = c
return true
}

_, r := utils.GenerateRequestInfo("POST", "/", nil, true)
code, _ := CreateQueueV1(r)

assert.Equal(t, http.StatusOK, code)

actualQueue := app.SyncQueues.Queues[fixtures.QueueName]
assert.Equal(t,
fmt.Sprintf("http://%s:%s/%s/%s",
fixtures.LOCAL_ENVIRONMENT.Host,
fixtures.LOCAL_ENVIRONMENT.Port,
fixtures.LOCAL_ENVIRONMENT.AccountID,
fixtures.QueueName,
),
actualQueue.URL,
)
}

func TestCreateQueueV1_request_transformer_error(t *testing.T) {
app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT
defer func() {
utils.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
return false
}

_, r := utils.GenerateRequestInfo("POST", "/", nil, true)
code, _ := CreateQueueV1(r)

assert.Equal(t, http.StatusBadRequest, code)
}

func TestCreateQueueV1_invalid_dead_letter_queue_error(t *testing.T) {
app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT
defer func() {
utils.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
dupe, _ := copystructure.Copy(fixtures.CreateQueueRequest)
c, _ := dupe.(models.CreateQueueRequest)
c.Attributes.RedrivePolicy = models.RedrivePolicy{
MaxReceiveCount: 100,
DeadLetterTargetArn: fmt.Sprintf("arn:aws:sqs:us-east-1:100010001000:%s", "garbage"),
}

v := resultingStruct.(*models.CreateQueueRequest)
*v = c
return true
}

_, r := utils.GenerateRequestInfo("POST", "/", nil, true)
code, _ := CreateQueueV1(r)

assert.Equal(t, http.StatusBadRequest, code)
}
Loading

0 comments on commit da44977

Please sign in to comment.