Skip to content

Commit

Permalink
Add SetQueueAttributesV1 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 8f356e7 commit b3d5762
Show file tree
Hide file tree
Showing 29 changed files with 848 additions and 158 deletions.
35 changes: 33 additions & 2 deletions app/fixtures/sqs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,46 @@ package fixtures

import (
"fmt"
"time"

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

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

var QueueName = "new-queue-1"
var QueueUrl = fmt.Sprintf("%s/%s", BASE_URL, QueueName)
var DeadLetterQueueName = "dead-letter-queue-1"

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

var CreateQueueRequest = models.CreateQueueRequest{
QueueName: QueueName,
Attributes: CreateQueueAttributes,
Attributes: QueueAttributes,
Tags: map[string]string{"my": "tag"},
}

var CreateQueueAttributes = models.Attributes{
var QueueAttributes = models.Attributes{
DelaySeconds: 1,
MaximumMessageSize: 2,
MessageRetentionPeriod: 3,
Expand Down Expand Up @@ -90,3 +116,8 @@ var GetQueueAttributesResponse = models.GetQueueAttributesResponse{
}},
Metadata: models.BASE_RESPONSE_METADATA,
}

var SetQueueAttributesRequest = models.SetQueueAttributesRequest{
QueueUrl: fmt.Sprintf("%s/%s", BASE_URL, "unit-queue1"),
Attributes: QueueAttributes,
}
2 changes: 1 addition & 1 deletion app/gosqs/change_message_visibility.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

func ChangeMessageVisibilityV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
requestBody := models.NewChangeMessageVisibilityRequest()
ok := utils.REQUEST_TRANSFORMER(requestBody, req)
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
if !ok {
log.Error("Invalid Request - ChangeMessageVisibilityV1")
return createErrorResponseV1(ErrInvalidParameterValue.Type)
Expand Down
2 changes: 1 addition & 1 deletion app/gosqs/create_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

func CreateQueueV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
requestBody := models.NewCreateQueueRequest()
ok := utils.REQUEST_TRANSFORMER(requestBody, req)
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
if !ok {
log.Error("Invalid Request - CreateQueueV1")
return createErrorResponseV1(ErrInvalidParameterValue.Type)
Expand Down
38 changes: 8 additions & 30 deletions app/gosqs/create_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,20 @@ func TestCreateQueueV1_success(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (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)
assert.Equal(t, fixtures.FullyPopulatedQueue, actualQueue)
}

func TestCreateQueueV1_success_with_redrive_policy(t *testing.T) {
Expand All @@ -67,7 +45,7 @@ func TestCreateQueueV1_success_with_redrive_policy(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
dupe, _ := copystructure.Copy(fixtures.CreateQueueRequest)
c, _ := dupe.(models.CreateQueueRequest)
c.Attributes.RedrivePolicy = models.RedrivePolicy{
Expand Down Expand Up @@ -126,7 +104,7 @@ func TestCreateQueueV1_success_with_existing_queue(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.CreateQueueRequest)
*v = fixtures.CreateQueueRequest
return true
Expand Down Expand Up @@ -154,7 +132,7 @@ func TestCreateQueueV1_success_with_no_request_attributes_falls_back_to_default(
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
dupe, _ := copystructure.Copy(fixtures.CreateQueueRequest)
c, _ := dupe.(models.CreateQueueRequest)
c.Attributes = models.Attributes{}
Expand Down Expand Up @@ -204,7 +182,7 @@ func TestCreateQueueV1_success_no_configured_region_for_queue_url(t *testing.T)
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
dupe, _ := copystructure.Copy(fixtures.CreateQueueRequest)
c, _ := dupe.(models.CreateQueueRequest)
c.Attributes = models.Attributes{}
Expand Down Expand Up @@ -238,7 +216,7 @@ func TestCreateQueueV1_request_transformer_error(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

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

Expand All @@ -255,7 +233,7 @@ func TestCreateQueueV1_invalid_dead_letter_queue_error(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
dupe, _ := copystructure.Copy(fixtures.CreateQueueRequest)
c, _ := dupe.(models.CreateQueueRequest)
c.Attributes.RedrivePolicy = models.RedrivePolicy{
Expand Down
2 changes: 1 addition & 1 deletion app/gosqs/delete_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

func DeleteMessageV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
requestBody := models.NewDeleteMessageRequest()
ok := utils.REQUEST_TRANSFORMER(requestBody, req)
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
if !ok {
log.Error("Invalid Request - DeleteMessageV1")
return createErrorResponseV1(ErrInvalidParameterValue.Type)
Expand Down
2 changes: 1 addition & 1 deletion app/gosqs/get_queue_attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (

func GetQueueAttributesV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
requestBody := models.NewGetQueueAttributesRequest()
ok := utils.REQUEST_TRANSFORMER(requestBody, req)
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
if !ok {
log.Error("Invalid Request - GetQueueAttributesV1")
return createErrorResponseV1(ErrInvalidParameterValue.Type)
Expand Down
14 changes: 7 additions & 7 deletions app/gosqs/get_queue_attributes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestGetQueueAttributesV1_success_all(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.GetQueueAttributesRequest)
*v = fixtures.GetQueueAttributesRequest
return true
Expand All @@ -43,7 +43,7 @@ func TestGetQueueAttributesV1_success_no_request_attrs_returns_all(t *testing.T)
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.GetQueueAttributesRequest)
*v = models.GetQueueAttributesRequest{
QueueUrl: "unit-queue1",
Expand All @@ -65,7 +65,7 @@ func TestGetQueueAttributesV1_success_all_with_redrive_queue(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.GetQueueAttributesRequest)
*v = models.GetQueueAttributesRequest{
QueueUrl: "unit-queue2",
Expand Down Expand Up @@ -98,7 +98,7 @@ func TestGetQueueAttributesV1_success_specific_fields(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.GetQueueAttributesRequest)
*v = models.GetQueueAttributesRequest{
QueueUrl: fmt.Sprintf("%s/unit-queue1", fixtures.BASE_URL),
Expand Down Expand Up @@ -130,7 +130,7 @@ func TestGetQueueAttributesV1_request_transformer_error(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

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

Expand All @@ -145,7 +145,7 @@ func TestGetQueueAttributesV1_missing_queue_url_in_request_returns_error(t *test
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.GetQueueAttributesRequest)
*v = models.GetQueueAttributesRequest{
QueueUrl: "",
Expand All @@ -165,7 +165,7 @@ func TestGetQueueAttributesV1_missing_queue_returns_error(t *testing.T) {
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) {
utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.GetQueueAttributesRequest)
*v = fixtures.GetQueueAttributesRequest
return true
Expand Down
37 changes: 0 additions & 37 deletions app/gosqs/gosqs.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,43 +415,6 @@ func GetQueueUrl(w http.ResponseWriter, req *http.Request) {
}
}

func SetQueueAttributes(w http.ResponseWriter, req *http.Request) {
// Sent response type
w.Header().Set("Content-Type", "application/xml")

queueUrl := getQueueFromPath(req.FormValue("QueueUrl"), req.URL.String())

queueName := ""
if queueUrl == "" {
vars := mux.Vars(req)
queueName = vars["queueName"]
} else {
uriSegments := strings.Split(queueUrl, "/")
queueName = uriSegments[len(uriSegments)-1]
}

log.Println("Set Queue Attributes:", queueName)
app.SyncQueues.Lock()
if queue, ok := app.SyncQueues.Queues[queueName]; ok {
if err := validateAndSetQueueAttributesFromForm(queue, req.Form); err != nil {
createErrorResponse(w, req, err.Error())
app.SyncQueues.Unlock()
return
}

respStruct := app.SetQueueAttributesResponse{"http://queue.amazonaws.com/doc/2012-11-05/", app.ResponseMetadata{RequestId: "00000000-0000-0000-0000-000000000000"}}
enc := xml.NewEncoder(w)
enc.Indent(" ", " ")
if err := enc.Encode(respStruct); err != nil {
log.Printf("error: %v\n", err)
}
} else {
log.Println("Get Queue URL:", queueName, ", queue does not exist!!!")
createErrorResponse(w, req, "QueueNotFound")
}
app.SyncQueues.Unlock()
}

func getQueueFromPath(formVal string, theUrl string) string {
if formVal != "" {
return formVal
Expand Down
34 changes: 0 additions & 34 deletions app/gosqs/gosqs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,40 +600,6 @@ func TestDeadLetterQueue(t *testing.T) {
}
}

func TestSetQueueAttributes_POST_QueueNotFound(t *testing.T) {
req, err := http.NewRequest("POST", "/", nil)
if err != nil {
t.Fatal(err)
}

form := url.Values{}
form.Add("Action", "SetQueueAttributes")
form.Add("QueueUrl", "http://localhost:4100/queue/not-existing")
form.Add("Version", "2012-11-05")
req.PostForm = form

// We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
rr := httptest.NewRecorder()
handler := http.HandlerFunc(SetQueueAttributes)

// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
// directly and pass in our Request and ResponseRecorder.
handler.ServeHTTP(rr, req)

// Check the status code is what we expect.
if status := rr.Code; status != http.StatusBadRequest {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusBadRequest)
}

// Check the response body is what we expect.
expected := "NonExistentQueue"
if !strings.Contains(rr.Body.String(), expected) {
t.Errorf("handler returned unexpected body: got %v want %v",
rr.Body.String(), expected)
}
}

func TestSendingAndReceivingFromFIFOQueueReturnsSameMessageOnError(t *testing.T) {
done := make(chan struct{}, 0)
go PeriodicTasks(1*time.Second, done)
Expand Down
2 changes: 1 addition & 1 deletion app/gosqs/list_queues.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
// https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ListQueues.html
func ListQueuesV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
requestBody := models.NewListQueuesRequest()
ok := utils.REQUEST_TRANSFORMER(requestBody, req)
ok := utils.REQUEST_TRANSFORMER(requestBody, req, true)
if !ok {
log.Error("Invalid Request - ListQueuesV1")
return createErrorResponseV1(ErrInvalidParameterValue.Type)
Expand Down
Loading

0 comments on commit b3d5762

Please sign in to comment.