Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Here is a list of the APIs:
- [x] GetQueueAttributes (Always returns all attributes - depth and arn are set correctly others are mocked)
- [x] GetQueueUrl
- [x] SendMessage
- [ ] SendMessageBatch
- [x] ReceiveMessage
- [x] DeleteMessage
- [x] PurgeQueue
Expand Down
91 changes: 85 additions & 6 deletions app/gosqs/gosqs.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ type Message struct {
ReceiptTime time.Time
}

type BatchMessage struct {
Message
Id string
}

type Queue struct {
Name string
URL string
Expand Down Expand Up @@ -145,6 +150,80 @@ func SendMessage(w http.ResponseWriter, req *http.Request) {
}
}

func SendMessageBatch(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/xml")
messageBody := req.FormValue("MessageBody")
entries := extractSendBatchRequestEntries(req)

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]
}

if _, ok := SyncQueues.Queues[queueName]; !ok {
// Queue does not exists
createErrorResponse(w, req, "QueueNotFound")
return
}

log.Println("Putting Batch Messages in Queue:", queueName)
resultEntries := []app.SendMessageBatchResultEntry{}
for _, entry := range entries {
entry.MD5OfMessageBody = common.GetMD5Hash(messageBody)
entry.Uuid, _ = common.NewUUID()
resultEntries = append(resultEntries, app.SendMessageBatchResultEntry{
Id: entry.Id,
MessageId: entry.Uuid,
MD5OfMessageBody: entry.MD5OfMessageBody,
})
}
SyncQueues.Lock()
for _, entry := range entries {
msg := entry.Message
SyncQueues.Queues[queueName].Messages = append(SyncQueues.Queues[queueName].Messages, msg)
common.LogMessage(fmt.Sprintf("%s: Queue: %s, Batch Message: %s\n", time.Now().Format("2006-01-02 15:04:05"), queueName, msg.MessageBody))
}
SyncQueues.Unlock()

respStruct := app.SendMessageBatchResponse{
Xmlns: "http://queue.amazonaws.com/doc/2012-11-05/",
Result: resultEntries,
Metadata: 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)
}
}

func extractSendBatchRequestEntries(req *http.Request) []BatchMessage {
entries := []BatchMessage{}

for i := 1; true; i++ {
Id := req.FormValue(fmt.Sprintf("SendMessageBatchRequestEntry.%d.Id", i))
if Id == "" {
break
}

messageBody := req.FormValue(fmt.Sprintf("SendMessageBatchRequestEntry.%d.MessageBody", i))
entries = append(entries, BatchMessage{
Id: Id,
Message: Message{
MessageBody: []byte(messageBody),
},
})
}

return entries
}

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

Expand Down Expand Up @@ -236,10 +315,10 @@ func numberOfHiddenMessagesInQueue(queue Queue) int {
}

type DeleteEntry struct {
Id string
Id string
ReceiptHandle string
Error string
Deleted bool
Error string
Deleted bool
}

func DeleteMessageBatch(w http.ResponseWriter, req *http.Request) {
Expand Down Expand Up @@ -306,9 +385,9 @@ func DeleteMessageBatch(w http.ResponseWriter, req *http.Request) {
for _, deleteEntry := range deleteEntries {
if deleteEntry.Deleted == false {
notFoundEntries = append(notFoundEntries, app.BatchResultErrorEntry{
Code: "1",
Id: deleteEntry.Id,
Message: "Message not found",
Code: "1",
Id: deleteEntry.Id,
Message: "Message not found",
SenderFault: true})
}
}
Expand Down
1 change: 1 addition & 0 deletions app/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var routingTable = map[string]http.HandlerFunc{
"GetQueueAttributes": sqs.GetQueueAttributes,
"SetQueueAttributes": sqs.SetQueueAttributes,
"SendMessage": sqs.SendMessage,
"SendMessageBatch": sqs.SendMessageBatch,
"ReceiveMessage": sqs.ReceiveMessage,
"DeleteMessage": sqs.DeleteMessage,
"DeleteMessageBatch": sqs.DeleteMessageBatch,
Expand Down
14 changes: 14 additions & 0 deletions app/sqs.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ type SendMessageResponse struct {
Metadata ResponseMetadata `xml:"ResponseMetadata"`
}

/*** Send Message Batch Response */

type SendMessageBatchResultEntry struct {
Id string `xml:"Id"`
MessageId string `xml:"MessageId"`
MD5OfMessageBody string `xml:"MD5OfMessageBody"`
}

type SendMessageBatchResponse struct {
Xmlns string `xml:"xmlns,attr"`
Result []SendMessageBatchResultEntry `xml:"SendMessageBatchResult"`
Metadata ResponseMetadata `xml:"ResponseMetadata"`
}

/*** Receive Message Response */

type ResultMessage struct {
Expand Down