Merge lp:~prudhvikrishna/goamz/sqs into lp:~gophers/goamz/trunk
- sqs
- Merge into trunk
Proposed by
Prudhvi Surapaneni
Status: | Needs review |
---|---|
Proposed branch: | lp:~prudhvikrishna/goamz/sqs |
Merge into: | lp:~gophers/goamz/trunk |
Diff against target: |
1304 lines (+1280/-0) 5 files modified
response_test.go (+238/-0) sign.go (+35/-0) sqs.go (+581/-0) sqs_test.go (+306/-0) suite_test.go (+120/-0) |
To merge this branch: | bzr merge lp:~prudhvikrishna/goamz/sqs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
The Go Language Gophers | Pending | ||
Review via email: mp+107309@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Unmerged revisions
- 3. By Prudhvi Surapaneni
-
Fix Attribute Names
- 2. By Prudhvi Surapaneni
-
Use different Path's basing on access
- 1. By Prudhvi Surapaneni
-
Import SQS
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'response_test.go' | |||
2 | --- response_test.go 1970-01-01 00:00:00 +0000 | |||
3 | +++ response_test.go 2012-05-25 00:21:19 +0000 | |||
4 | @@ -0,0 +1,238 @@ | |||
5 | 1 | package sqs_test | ||
6 | 2 | |||
7 | 3 | var TestCreateQueueXmlOK = ` | ||
8 | 4 | <CreateQueueResponse> | ||
9 | 5 | <CreateQueueResult> | ||
10 | 6 | <QueueUrl>http://sqs.us-east-1.amazonaws.com/123456789012/testQueue</QueueUrl> | ||
11 | 7 | </CreateQueueResult> | ||
12 | 8 | <ResponseMetadata> | ||
13 | 9 | <RequestId>7a62c49f-347e-4fc4-9331-6e8e7a96aa73</RequestId> | ||
14 | 10 | </ResponseMetadata> | ||
15 | 11 | </CreateQueueResponse> | ||
16 | 12 | ` | ||
17 | 13 | |||
18 | 14 | var TestListQueuesXmlOK = ` | ||
19 | 15 | <ListQueuesResponse> | ||
20 | 16 | <ListQueuesResult> | ||
21 | 17 | <QueueUrl>http://sqs.us-east-1.amazonaws.com/123456789012/testQueue</QueueUrl> | ||
22 | 18 | </ListQueuesResult> | ||
23 | 19 | <ResponseMetadata> | ||
24 | 20 | <RequestId>725275ae-0b9b-4762-b238-436d7c65a1ac</RequestId> | ||
25 | 21 | </ResponseMetadata> | ||
26 | 22 | </ListQueuesResponse> | ||
27 | 23 | ` | ||
28 | 24 | |||
29 | 25 | var TestGetQueueUrlXmlOK = ` | ||
30 | 26 | <GetQueueUrlResponse> | ||
31 | 27 | <GetQueueUrlResult> | ||
32 | 28 | <QueueUrl>http://sqs.us-east-1.amazonaws.com/123456789012/testQueue</QueueUrl> | ||
33 | 29 | </GetQueueUrlResult> | ||
34 | 30 | <ResponseMetadata> | ||
35 | 31 | <RequestId>470a6f13-2ed9-4181-ad8a-2fdea142988e</RequestId> | ||
36 | 32 | </ResponseMetadata> | ||
37 | 33 | </GetQueueUrlResponse> | ||
38 | 34 | ` | ||
39 | 35 | |||
40 | 36 | var TestChangeMessageVisibilityXmlOK = ` | ||
41 | 37 | <ChangeMessageVisibilityResponse> | ||
42 | 38 | <ResponseMetadata> | ||
43 | 39 | <RequestId>6a7a282a-d013-4a59-aba9-335b0fa48bed</RequestId> | ||
44 | 40 | </ResponseMetadata> | ||
45 | 41 | </ChangeMessageVisibilityResponse> | ||
46 | 42 | ` | ||
47 | 43 | |||
48 | 44 | var TestChangeMessaveVisibilityBatchXmlOK = ` | ||
49 | 45 | <ChangeMessageVisibilityBatchResponse> | ||
50 | 46 | <ChangeMessageVisibilityBatchResult> | ||
51 | 47 | <ChangeMessageVisibilityBatchResultEntry> | ||
52 | 48 | <Id>change_visibility_msg_2</Id> | ||
53 | 49 | </ChangeMessageVisibilityBatchResultEntry> | ||
54 | 50 | <ChangeMessageVisibilityBatchResultEntry> | ||
55 | 51 | <Id>change_visibility_msg_3</Id> | ||
56 | 52 | </ChangeMessageVisibilityBatchResultEntry> | ||
57 | 53 | </ChangeMessageVisibilityBatchResult> | ||
58 | 54 | <ResponseMetadata> | ||
59 | 55 | <RequestId>ca9668f7-ab1b-4f7a-8859-f15747ab17a7</RequestId> | ||
60 | 56 | </ResponseMetadata> | ||
61 | 57 | </ChangeMessageVisibilityBatchResponse> | ||
62 | 58 | ` | ||
63 | 59 | |||
64 | 60 | var TestReceiveMessageXmlOK = ` | ||
65 | 61 | <ReceiveMessageResponse> | ||
66 | 62 | <ReceiveMessageResult> | ||
67 | 63 | <Message> | ||
68 | 64 | <MessageId>5fea7756-0ea4-451a-a703-a558b933e274</MessageId> | ||
69 | 65 | <ReceiptHandle>MbZj6wDWli+JvwwJaBV+3dcjk2YW2vA3+STFFljTM8tJJg6HRG6PYSasuWXPJB+CwLj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ+QEauMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=</ReceiptHandle> | ||
70 | 66 | <MD5OfBody>fafb00f5732ab283681e124bf8747ed1</MD5OfBody> | ||
71 | 67 | <Body>This is a test message</Body> | ||
72 | 68 | <Attribute> | ||
73 | 69 | <Name>SenderId</Name> | ||
74 | 70 | <Value>195004372649</Value> | ||
75 | 71 | </Attribute> | ||
76 | 72 | <Attribute> | ||
77 | 73 | <Name>SentTimestamp</Name> | ||
78 | 74 | <Value>1238099229000</Value> | ||
79 | 75 | </Attribute> | ||
80 | 76 | <Attribute> | ||
81 | 77 | <Name>ApproximateReceiveCount</Name> | ||
82 | 78 | <Value>5</Value> | ||
83 | 79 | </Attribute> | ||
84 | 80 | <Attribute> | ||
85 | 81 | <Name>ApproximateFirstReceiveTimestamp</Name> | ||
86 | 82 | <Value>1250700979248</Value> | ||
87 | 83 | </Attribute> | ||
88 | 84 | </Message> | ||
89 | 85 | </ReceiveMessageResult> | ||
90 | 86 | <ResponseMetadata> | ||
91 | 87 | <RequestId>b6633655-283d-45b4-aee4-4e84e0ae6afa</RequestId> | ||
92 | 88 | </ResponseMetadata> | ||
93 | 89 | </ReceiveMessageResponse> | ||
94 | 90 | ` | ||
95 | 91 | |||
96 | 92 | var TestDeleteMessageXmlOK = ` | ||
97 | 93 | <DeleteQueueResponse> | ||
98 | 94 | <ResponseMetadata> | ||
99 | 95 | <RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId> | ||
100 | 96 | </ResponseMetadata> | ||
101 | 97 | </DeleteQueueResponse> | ||
102 | 98 | ` | ||
103 | 99 | |||
104 | 100 | var TestSendMessageXmlOK = ` | ||
105 | 101 | <SendMessageResponse> | ||
106 | 102 | <SendMessageResult> | ||
107 | 103 | <MD5OfMessageBody>fafb00f5732ab283681e124bf8747ed1</MD5OfMessageBody> | ||
108 | 104 | <MessageId>5fea7756-0ea4-451a-a703-a558b933e274</MessageId> | ||
109 | 105 | </SendMessageResult> | ||
110 | 106 | <ResponseMetadata> | ||
111 | 107 | <RequestId>27daac76-34dd-47df-bd01-1f6e873584a0</RequestId> | ||
112 | 108 | </ResponseMetadata> | ||
113 | 109 | </SendMessageResponse> | ||
114 | 110 | ` | ||
115 | 111 | |||
116 | 112 | var TestSendMessageBatchXmlOK = ` | ||
117 | 113 | <SendMessageBatchResponse> | ||
118 | 114 | <SendMessageBatchResult> | ||
119 | 115 | <SendMessageBatchResultEntry> | ||
120 | 116 | <Id>test_msg_001</Id> | ||
121 | 117 | <MessageId>0a5231c7-8bff-4955-be2e-8dc7c50a25fa</MessageId> | ||
122 | 118 | <MD5OfMessageBody>0e024d309850c78cba5eabbeff7cae71</MD5OfMessageBody> | ||
123 | 119 | </SendMessageBatchResultEntry> | ||
124 | 120 | <SendMessageBatchResultEntry> | ||
125 | 121 | <Id>test_msg_002</Id> | ||
126 | 122 | <MessageId>15ee1ed3-87e7-40c1-bdaa-2e49968ea7e9</MessageId> | ||
127 | 123 | <MD5OfMessageBody>7fb8146a82f95e0af155278f406862c2</MD5OfMessageBody> | ||
128 | 124 | </SendMessageBatchResultEntry> | ||
129 | 125 | </SendMessageBatchResult> | ||
130 | 126 | <ResponseMetadata> | ||
131 | 127 | <RequestId>ca1ad5d0-8271-408b-8d0f-1351bf547e74</RequestId> | ||
132 | 128 | </ResponseMetadata> | ||
133 | 129 | </SendMessageBatchResponse> | ||
134 | 130 | ` | ||
135 | 131 | |||
136 | 132 | var TestGetQueueAttributesAllXmlOK = ` | ||
137 | 133 | <GetQueueAttributesResponse> | ||
138 | 134 | <GetQueueAttributesResult> | ||
139 | 135 | <Attribute> | ||
140 | 136 | <Name>VisibilityTimeout</Name> | ||
141 | 137 | <Value>30</Value> | ||
142 | 138 | </Attribute> | ||
143 | 139 | <Attribute> | ||
144 | 140 | <Name>ApproximateNumberOfMessages</Name> | ||
145 | 141 | <Value>0</Value> | ||
146 | 142 | </Attribute> | ||
147 | 143 | <Attribute> | ||
148 | 144 | <Name>ApproximateNumberOfMessagesNotVisible</Name> | ||
149 | 145 | <Value>0</Value> | ||
150 | 146 | </Attribute> | ||
151 | 147 | <Attribute> | ||
152 | 148 | <Name>CreatedTimestamp</Name> | ||
153 | 149 | <Value>1286771522</Value> | ||
154 | 150 | </Attribute> | ||
155 | 151 | <Attribute> | ||
156 | 152 | <Name>LastModifiedTimestamp</Name> | ||
157 | 153 | <Value>1286771522</Value> | ||
158 | 154 | </Attribute> | ||
159 | 155 | <Attribute> | ||
160 | 156 | <Name>QueueArn</Name> | ||
161 | 157 | <Value>arn:aws:sqs:us-east-1:123456789012:qfoo</Value> | ||
162 | 158 | </Attribute> | ||
163 | 159 | <Attribute> | ||
164 | 160 | <Name>MaximumMessageSize</Name> | ||
165 | 161 | <Value>8192</Value> | ||
166 | 162 | </Attribute> | ||
167 | 163 | <Attribute> | ||
168 | 164 | <Name>MessageRetentionPeriod</Name> | ||
169 | 165 | <Value>345600</Value> | ||
170 | 166 | </Attribute> | ||
171 | 167 | </GetQueueAttributesResult> | ||
172 | 168 | <ResponseMetadata> | ||
173 | 169 | <RequestId>1ea71be5-b5a2-4f9d-b85a-945d8d08cd0b</RequestId> | ||
174 | 170 | </ResponseMetadata> | ||
175 | 171 | </GetQueueAttributesResponse> | ||
176 | 172 | ` | ||
177 | 173 | |||
178 | 174 | var TestGetQueueAttributesSelectiveXmlOK = ` | ||
179 | 175 | <GetQueueAttributesResponse> | ||
180 | 176 | <GetQueueAttributesResult> | ||
181 | 177 | <Attribute> | ||
182 | 178 | <Name>VisibilityTimeout</Name> | ||
183 | 179 | <Value>30</Value> | ||
184 | 180 | </Attribute> | ||
185 | 181 | <Attribute> | ||
186 | 182 | <Name>DelaySeconds</Name> | ||
187 | 183 | <Value>0</Value> | ||
188 | 184 | </Attribute> | ||
189 | 185 | </GetQueueAttributesResult> | ||
190 | 186 | <ResponseMetadata> | ||
191 | 187 | <RequestId>1ea71be5-b5a2-4f9d-b85a-945d8d08cd0b</RequestId> | ||
192 | 188 | </ResponseMetadata> | ||
193 | 189 | </GetQueueAttributesResponse> | ||
194 | 190 | ` | ||
195 | 191 | |||
196 | 192 | var TestDeleteMessageBatchXmlOK = ` | ||
197 | 193 | <DeleteMessageBatchResponse> | ||
198 | 194 | <DeleteMessageBatchResult> | ||
199 | 195 | <DeleteMessageBatchResultEntry> | ||
200 | 196 | <Id>msg1</Id> | ||
201 | 197 | </DeleteMessageBatchResultEntry> | ||
202 | 198 | <DeleteMessageBatchResultEntry> | ||
203 | 199 | <Id>msg2</Id> | ||
204 | 200 | </DeleteMessageBatchResultEntry> | ||
205 | 201 | </DeleteMessageBatchResult> | ||
206 | 202 | <ResponseMetadata> | ||
207 | 203 | <RequestId>d6f86b7a-74d1-4439-b43f-196a1e29cd85</RequestId> | ||
208 | 204 | </ResponseMetadata> | ||
209 | 205 | </DeleteMessageBatchResponse> | ||
210 | 206 | ` | ||
211 | 207 | |||
212 | 208 | var TestAddPermissionXmlOK = ` | ||
213 | 209 | <AddPermissionResponse> | ||
214 | 210 | <ResponseMetadata> | ||
215 | 211 | <RequestId>9a285199-c8d6-47c2-bdb2-314cb47d599d</RequestId> | ||
216 | 212 | </ResponseMetadata> | ||
217 | 213 | </AddPermissionResponse> | ||
218 | 214 | ` | ||
219 | 215 | |||
220 | 216 | var TestRemovePermissionXmlOK = ` | ||
221 | 217 | <RemovePermissionResponse> | ||
222 | 218 | <ResponseMetadata> | ||
223 | 219 | <RequestId>f8bdb362-6616-42c0-977a-ce9a8bcce3bb</RequestId> | ||
224 | 220 | </ResponseMetadata> | ||
225 | 221 | </RemovePermissionResponse> | ||
226 | 222 | ` | ||
227 | 223 | |||
228 | 224 | var TestDeleteQueueXmlOK = ` | ||
229 | 225 | <DeleteQueueResponse> | ||
230 | 226 | <ResponseMetadata> | ||
231 | 227 | <RequestId>6fde8d1e-52cd-4581-8cd9-c512f4c64223</RequestId> | ||
232 | 228 | </ResponseMetadata> | ||
233 | 229 | </DeleteQueueResponse> | ||
234 | 230 | ` | ||
235 | 231 | |||
236 | 232 | var TestSetQueueAttributesXmlOK = ` | ||
237 | 233 | <SetQueueAttributesResponse> | ||
238 | 234 | <ResponseMetadata> | ||
239 | 235 | <RequestId>e5cca473-4fc0-4198-a451-8abb94d02c75</RequestId> | ||
240 | 236 | </ResponseMetadata> | ||
241 | 237 | </SetQueueAttributesResponse> | ||
242 | 238 | ` | ||
243 | 0 | 239 | ||
244 | === added file 'sign.go' | |||
245 | --- sign.go 1970-01-01 00:00:00 +0000 | |||
246 | +++ sign.go 2012-05-25 00:21:19 +0000 | |||
247 | @@ -0,0 +1,35 @@ | |||
248 | 1 | package sqs | ||
249 | 2 | |||
250 | 3 | import ( | ||
251 | 4 | "crypto/hmac" | ||
252 | 5 | "crypto/sha256" | ||
253 | 6 | "encoding/base64" | ||
254 | 7 | "launchpad.net/goamz/aws" | ||
255 | 8 | "sort" | ||
256 | 9 | "strings" | ||
257 | 10 | ) | ||
258 | 11 | |||
259 | 12 | // ---------------------------------------------------------------------------- | ||
260 | 13 | // EC2 signing (http://goo.gl/fQmAN) | ||
261 | 14 | |||
262 | 15 | var b64 = base64.StdEncoding | ||
263 | 16 | |||
264 | 17 | func sign(auth aws.Auth, method, path string, params map[string]string, host string) { | ||
265 | 18 | params["AWSAccessKeyId"] = auth.AccessKey | ||
266 | 19 | params["SignatureVersion"] = "2" | ||
267 | 20 | params["SignatureMethod"] = "HmacSHA256" | ||
268 | 21 | |||
269 | 22 | var sarray []string | ||
270 | 23 | for k, v := range params { | ||
271 | 24 | sarray = append(sarray, aws.Encode(k)+"="+aws.Encode(v)) | ||
272 | 25 | } | ||
273 | 26 | sort.StringSlice(sarray).Sort() | ||
274 | 27 | joined := strings.Join(sarray, "&") | ||
275 | 28 | payload := method + "\n" + host + "\n" + path + "\n" + joined | ||
276 | 29 | hash := hmac.New(sha256.New, []byte(auth.SecretKey)) | ||
277 | 30 | hash.Write([]byte(payload)) | ||
278 | 31 | signature := make([]byte, b64.EncodedLen(hash.Size())) | ||
279 | 32 | b64.Encode(signature, hash.Sum(nil)) | ||
280 | 33 | |||
281 | 34 | params["Signature"] = string(signature) | ||
282 | 35 | } | ||
283 | 0 | 36 | ||
284 | === added file 'sqs.go' | |||
285 | --- sqs.go 1970-01-01 00:00:00 +0000 | |||
286 | +++ sqs.go 2012-05-25 00:21:19 +0000 | |||
287 | @@ -0,0 +1,581 @@ | |||
288 | 1 | // | ||
289 | 2 | // goamz - Go packages to interact with the Amazon Web Services. | ||
290 | 3 | // | ||
291 | 4 | // https://wiki.ubuntu.com/goamz | ||
292 | 5 | // | ||
293 | 6 | // Copyright (c) 2012 Memeo Inc. | ||
294 | 7 | // | ||
295 | 8 | // Written by Prudhvi Krishna Surapaneni <me@prudhvi.net> | ||
296 | 9 | // | ||
297 | 10 | package sqs | ||
298 | 11 | |||
299 | 12 | import ( | ||
300 | 13 | "encoding/xml" | ||
301 | 14 | "fmt" | ||
302 | 15 | "launchpad.net/goamz/aws" | ||
303 | 16 | "log" | ||
304 | 17 | "net/http" | ||
305 | 18 | "net/http/httputil" | ||
306 | 19 | "net/url" | ||
307 | 20 | "strconv" | ||
308 | 21 | "time" | ||
309 | 22 | ) | ||
310 | 23 | |||
311 | 24 | // The SQS type encapsulates operations with specific SQS region | ||
312 | 25 | type SQS struct { | ||
313 | 26 | aws.Auth | ||
314 | 27 | aws.Region | ||
315 | 28 | private byte // Reserve the right of using private data. | ||
316 | 29 | } | ||
317 | 30 | |||
318 | 31 | const debug = false | ||
319 | 32 | |||
320 | 33 | // New creates a new SQS handle | ||
321 | 34 | func New(auth aws.Auth, region aws.Region) *SQS { | ||
322 | 35 | return &SQS{auth, region, 0} | ||
323 | 36 | } | ||
324 | 37 | |||
325 | 38 | // Queue type encapsulates operations on a SQS Queue | ||
326 | 39 | type Queue struct { | ||
327 | 40 | *SQS | ||
328 | 41 | Url string | ||
329 | 42 | } | ||
330 | 43 | |||
331 | 44 | // Response to a CreateQueue request. | ||
332 | 45 | // | ||
333 | 46 | // See http://goo.gl/sVUjF for more details | ||
334 | 47 | type CreateQueueResponse struct { | ||
335 | 48 | QueueUrl string `xml:"CreateQueueResult>QueueUrl"` | ||
336 | 49 | ResponseMetadata | ||
337 | 50 | } | ||
338 | 51 | |||
339 | 52 | // Response to a ListQueues request. | ||
340 | 53 | // | ||
341 | 54 | // See http://goo.gl/RPRWr for more details | ||
342 | 55 | type ListQueuesResponse struct { | ||
343 | 56 | QueueUrl []string `xml:"ListQueuesResult>QueueUrl"` | ||
344 | 57 | ResponseMetadata | ||
345 | 58 | } | ||
346 | 59 | |||
347 | 60 | // Response to a GetQueueUrl request. | ||
348 | 61 | // | ||
349 | 62 | // See http://goo.gl/hk7Iu for more details | ||
350 | 63 | type GetQueueUrlResponse struct { | ||
351 | 64 | QueueUrl string `xml:"GetQueueUrlResult>QueueUrl"` | ||
352 | 65 | ResponseMetadata | ||
353 | 66 | } | ||
354 | 67 | |||
355 | 68 | // Response to a ChangeMessageVisibility request. | ||
356 | 69 | // | ||
357 | 70 | // See http://goo.gl/EyJKF for more details | ||
358 | 71 | type ChangeMessageVisibilityResponse struct { | ||
359 | 72 | ResponseMetadata | ||
360 | 73 | } | ||
361 | 74 | |||
362 | 75 | // See http://goo.gl/XTo0s for more details | ||
363 | 76 | type ResponseMetadata struct { | ||
364 | 77 | RequestId string `xml:"ResponseMetadata>RequestId"` | ||
365 | 78 | } | ||
366 | 79 | |||
367 | 80 | // Error represents an error in an operation with SQS | ||
368 | 81 | type Error struct { | ||
369 | 82 | StatusCode int // HTTP Status Code (200, 403, ... ) | ||
370 | 83 | Code string // SQS Error Code | ||
371 | 84 | Message string // The human-oriented error message | ||
372 | 85 | RequestId string `xml:"RequestID"` | ||
373 | 86 | } | ||
374 | 87 | |||
375 | 88 | func (err *Error) Error() string { | ||
376 | 89 | if err.Code != "" { | ||
377 | 90 | return err.Message | ||
378 | 91 | } | ||
379 | 92 | |||
380 | 93 | return fmt.Sprintf("%s (%s)", err.Message, err.Code) | ||
381 | 94 | } | ||
382 | 95 | |||
383 | 96 | // For now a single error inst is being exposed. In the future it may be useful | ||
384 | 97 | // to provide access to all of them, but rather than doing it as an array/slice, | ||
385 | 98 | // use a *next pointer, so that it's backward compatible and it continues to be | ||
386 | 99 | // easy to handle the first error, which is what most people will want. | ||
387 | 100 | type xmlErrors struct { | ||
388 | 101 | RequestId string | ||
389 | 102 | Errors []Error `xml:"Errors>Error"` | ||
390 | 103 | } | ||
391 | 104 | |||
392 | 105 | // Attribute represents an instance of a SQS Queue Attribute. | ||
393 | 106 | type Attribute struct { | ||
394 | 107 | Name string | ||
395 | 108 | Value string | ||
396 | 109 | } | ||
397 | 110 | |||
398 | 111 | // See http://goo.gl/pgffn for more details. | ||
399 | 112 | type ChangeMessageVisibilityBatchEntry struct { | ||
400 | 113 | Id string | ||
401 | 114 | ReceiptHandle string | ||
402 | 115 | VisibilityTimeout int | ||
403 | 116 | } | ||
404 | 117 | |||
405 | 118 | // ReceiveMessageResponse holds the results of ReceiveMessage | ||
406 | 119 | type ReceiveMessageResponse struct { | ||
407 | 120 | Messages []Message `xml:"ReceiveMessageResult>Message"` | ||
408 | 121 | ResponseMetadata | ||
409 | 122 | } | ||
410 | 123 | |||
411 | 124 | type DeleteMessageResponse struct { | ||
412 | 125 | ResponseMetadata | ||
413 | 126 | } | ||
414 | 127 | |||
415 | 128 | type SendMessageResponse struct { | ||
416 | 129 | SendMessageResult | ||
417 | 130 | ResponseMetadata | ||
418 | 131 | } | ||
419 | 132 | |||
420 | 133 | type SendMessageBatchResponse struct { | ||
421 | 134 | SendMessageBatchResult | ||
422 | 135 | ResponseMetadata | ||
423 | 136 | } | ||
424 | 137 | |||
425 | 138 | // SendMessageBatchResult holds the results of SendMessageBatch | ||
426 | 139 | type SendMessageBatchResult struct { | ||
427 | 140 | Entries []SendMessageBatchResultEntry `xml:"SendMessageBatchResult>SendMessageBatchResultEntry"` | ||
428 | 141 | } | ||
429 | 142 | |||
430 | 143 | type SendMessageBatchResultEntry struct { | ||
431 | 144 | MD5OfMessageBody string `xml:"MD5OfMessageBody"` | ||
432 | 145 | MessageId string `xml:"MessageId"` | ||
433 | 146 | Id string `xml:"Id"` | ||
434 | 147 | } | ||
435 | 148 | |||
436 | 149 | type SendMessageBatchRequestEntry struct { | ||
437 | 150 | Id string | ||
438 | 151 | MessageBody string | ||
439 | 152 | DelaySeconds int | ||
440 | 153 | } | ||
441 | 154 | |||
442 | 155 | type SendMessageResult struct { | ||
443 | 156 | MD5OfMessageBody string `xml:"SendMessageResult>MD5OfMessageBody"` | ||
444 | 157 | MessageId string `xml:"SendMessageResult>MessageId"` | ||
445 | 158 | } | ||
446 | 159 | |||
447 | 160 | // Represents an instance of a SQS Message | ||
448 | 161 | type Message struct { | ||
449 | 162 | MessageId string `xml:"MessageId"` | ||
450 | 163 | Body string `xml:"Body"` | ||
451 | 164 | MD5OfBody string `xml:"MD5OfBody"` | ||
452 | 165 | ReceiptHandle string `xml:"ReceiptHandle"` | ||
453 | 166 | Attribute []Attribute `xml:"Attribute"` | ||
454 | 167 | } | ||
455 | 168 | |||
456 | 169 | type ChangeMessageVisibilityBatchResponse struct { | ||
457 | 170 | Id []string `xml:"ChangeMessageVisibilityBatchResult>ChangeMessageVisibilityBatchResultEntry>Id"` | ||
458 | 171 | ResponseMetadata | ||
459 | 172 | } | ||
460 | 173 | |||
461 | 174 | type GetQueueAttributesResponse struct { | ||
462 | 175 | Attributes []Attribute `xml:"GetQueueAttributesResult>Attribute"` | ||
463 | 176 | ResponseMetadata | ||
464 | 177 | } | ||
465 | 178 | |||
466 | 179 | type DeleteMessageBatchResult struct { | ||
467 | 180 | Ids []string `xml:"DeleteMessageBatchResult>DeleteMessageBatchResultEntry>Id"` | ||
468 | 181 | } | ||
469 | 182 | |||
470 | 183 | type DeleteMessageBatchResponse struct { | ||
471 | 184 | DeleteMessageBatchResult `xml:"DeleteMessageBatchResponse>DeleteMessageBatchResult"` | ||
472 | 185 | ResponseMetadata | ||
473 | 186 | } | ||
474 | 187 | |||
475 | 188 | type DeleteMessageBatch struct { | ||
476 | 189 | Id string | ||
477 | 190 | ReceiptHandle string | ||
478 | 191 | } | ||
479 | 192 | |||
480 | 193 | type AccountPermission struct { | ||
481 | 194 | AWSAccountId string | ||
482 | 195 | ActionName string | ||
483 | 196 | } | ||
484 | 197 | |||
485 | 198 | type AddPermissionResponse struct { | ||
486 | 199 | ResponseMetadata | ||
487 | 200 | } | ||
488 | 201 | |||
489 | 202 | type RemovePermissionResponse struct { | ||
490 | 203 | ResponseMetadata | ||
491 | 204 | } | ||
492 | 205 | |||
493 | 206 | type SetQueueAttributesResponse struct { | ||
494 | 207 | ResponseMetadata | ||
495 | 208 | } | ||
496 | 209 | |||
497 | 210 | type DeleteQueueResponse struct { | ||
498 | 211 | ResponseMetadata | ||
499 | 212 | } | ||
500 | 213 | |||
501 | 214 | // CreateQueue action creates a new queue. | ||
502 | 215 | // | ||
503 | 216 | // See http://goo.gl/sVUjF for more details | ||
504 | 217 | func (s *SQS) CreateQueue(name string, attributes []Attribute) (queue *Queue, err error) { | ||
505 | 218 | resp := &CreateQueueResponse{} | ||
506 | 219 | params := makeParams("CreateQueue") | ||
507 | 220 | queue = nil | ||
508 | 221 | |||
509 | 222 | for i, attribute := range attributes { | ||
510 | 223 | params["AttributeName."+strconv.Itoa(i+1)+".Name"] = attribute.Name | ||
511 | 224 | params["AttributeName."+strconv.Itoa(i+1)+".Value"] = attribute.Value | ||
512 | 225 | } | ||
513 | 226 | |||
514 | 227 | params["QueueName"] = name | ||
515 | 228 | err = s.query("", params, resp) | ||
516 | 229 | if err != nil { | ||
517 | 230 | return nil, err | ||
518 | 231 | } | ||
519 | 232 | queue = &Queue{s, resp.QueueUrl} | ||
520 | 233 | return queue, err | ||
521 | 234 | } | ||
522 | 235 | |||
523 | 236 | // AddPermission action adds a permission to a queue for a specific principal. | ||
524 | 237 | // | ||
525 | 238 | // See http://goo.gl/8WBp8 for more details | ||
526 | 239 | func (q *Queue) AddPermission(label string, accountPermissions []AccountPermission) (resp *AddPermissionResponse, err error) { | ||
527 | 240 | resp = &AddPermissionResponse{} | ||
528 | 241 | params := makeParams("AddPermission") | ||
529 | 242 | |||
530 | 243 | params["Label"] = label | ||
531 | 244 | for i, accountPermission := range accountPermissions { | ||
532 | 245 | params["AWSAccountId."+strconv.Itoa(i+1)] = accountPermission.AWSAccountId | ||
533 | 246 | params["ActionName."+strconv.Itoa(i+1)] = accountPermission.ActionName | ||
534 | 247 | } | ||
535 | 248 | |||
536 | 249 | err = q.SQS.query(q.Url, params, resp) | ||
537 | 250 | return | ||
538 | 251 | } | ||
539 | 252 | |||
540 | 253 | // RemovePermission action revokes any permissions in the queue policy that matches the Label parameter. | ||
541 | 254 | // | ||
542 | 255 | // See http://goo.gl/YLOe8 for more details | ||
543 | 256 | func (q *Queue) RemovePermission(label string) (resp *RemovePermissionResponse, err error) { | ||
544 | 257 | resp = &RemovePermissionResponse{} | ||
545 | 258 | params := makeParams("RemovePermission") | ||
546 | 259 | |||
547 | 260 | params["Label"] = label | ||
548 | 261 | err = q.SQS.query(q.Url, params, resp) | ||
549 | 262 | return | ||
550 | 263 | } | ||
551 | 264 | |||
552 | 265 | // GetQueueAttributes action returns one or all attributes of a queue. | ||
553 | 266 | // | ||
554 | 267 | // See http://goo.gl/WejDu for more details | ||
555 | 268 | func (q *Queue) GetQueueAttributes(attributes []string) (resp *GetQueueAttributesResponse, err error) { | ||
556 | 269 | resp = &GetQueueAttributesResponse{} | ||
557 | 270 | params := makeParams("GetQueueAttributes") | ||
558 | 271 | |||
559 | 272 | for i, attribute := range attributes { | ||
560 | 273 | params["AttributeName."+strconv.Itoa(i+1)] = attribute | ||
561 | 274 | } | ||
562 | 275 | |||
563 | 276 | err = q.SQS.query(q.Url, params, resp) | ||
564 | 277 | return | ||
565 | 278 | } | ||
566 | 279 | |||
567 | 280 | // ChangeMessageVisibility action changes the visibility timeout of a specified message in a queue to a new value. | ||
568 | 281 | // | ||
569 | 282 | // See http://goo.gl/EyJKF for more details | ||
570 | 283 | func (q *Queue) ChangeMessageVisibility(receiptHandle string, visibilityTimeout int) (resp *ChangeMessageVisibilityResponse, err error) { | ||
571 | 284 | resp = &ChangeMessageVisibilityResponse{} | ||
572 | 285 | params := makeParams("ChangeMessageVisibility") | ||
573 | 286 | |||
574 | 287 | params["VisibilityTimeout"] = strconv.Itoa(visibilityTimeout) | ||
575 | 288 | params["ReceiptHandle"] = receiptHandle | ||
576 | 289 | |||
577 | 290 | err = q.SQS.query(q.Url, params, resp) | ||
578 | 291 | return | ||
579 | 292 | } | ||
580 | 293 | |||
581 | 294 | // ChangeMessageVisibilityBatch action is a batch version of the ChangeMessageVisibility action. | ||
582 | 295 | // | ||
583 | 296 | // See http://goo.gl/pgffn for more details | ||
584 | 297 | func (q *Queue) ChangeMessageVisibilityBatch(messageVisibilityBatch []ChangeMessageVisibilityBatchEntry) (resp *ChangeMessageVisibilityBatchResponse, err error) { | ||
585 | 298 | resp = &ChangeMessageVisibilityBatchResponse{} | ||
586 | 299 | params := makeParams("ChangeMessageVisibilityBatch") | ||
587 | 300 | |||
588 | 301 | for i, messageVisibility := range messageVisibilityBatch { | ||
589 | 302 | params["ChangeMessageVisibilityBatchRequestEntry."+strconv.Itoa(i+1)+".Id"] = messageVisibility.Id | ||
590 | 303 | params["ChangeMessageVisibilityBatchRequestEntry."+strconv.Itoa(i+1)+".ReceiptHandle"] = messageVisibility.ReceiptHandle | ||
591 | 304 | params["ChangeMessageVisibilityBatchRequestEntry."+strconv.Itoa(i+1)+".VisibilityTimeout"] = strconv.Itoa(messageVisibility.VisibilityTimeout) | ||
592 | 305 | } | ||
593 | 306 | |||
594 | 307 | err = q.SQS.query(q.Url, params, resp) | ||
595 | 308 | return | ||
596 | 309 | } | ||
597 | 310 | |||
598 | 311 | // ReceiveMessage action retrieves one or more messages from the specified queue. | ||
599 | 312 | // | ||
600 | 313 | // See http://goo.gl/ThPrF for more details | ||
601 | 314 | func (q *Queue) ReceiveMessage(attributes []string, maxNumberOfMessages int, visibilityTimeout int) (resp *ReceiveMessageResponse, err error) { | ||
602 | 315 | resp = &ReceiveMessageResponse{} | ||
603 | 316 | params := makeParams("ReceiveMessage") | ||
604 | 317 | |||
605 | 318 | for i, attribute := range attributes { | ||
606 | 319 | params["AttributeName."+strconv.Itoa(i+1)] = attribute | ||
607 | 320 | } | ||
608 | 321 | |||
609 | 322 | params["MaxNumberOfMessages"] = strconv.Itoa(maxNumberOfMessages) | ||
610 | 323 | params["VisibilityTimeout"] = strconv.Itoa(visibilityTimeout) | ||
611 | 324 | |||
612 | 325 | err = q.SQS.query(q.Url, params, resp) | ||
613 | 326 | return | ||
614 | 327 | } | ||
615 | 328 | |||
616 | 329 | // DeleteMessage action deletes the specified message from the specified queue. | ||
617 | 330 | // | ||
618 | 331 | // See http://goo.gl/6XBv7 for more details | ||
619 | 332 | func (q *Queue) DeleteMessage(receiptHandle string) (resp *DeleteMessageResponse, err error) { | ||
620 | 333 | resp = &DeleteMessageResponse{} | ||
621 | 334 | params := makeParams("DeleteMessage") | ||
622 | 335 | |||
623 | 336 | params["ReceiptHandle"] = receiptHandle | ||
624 | 337 | |||
625 | 338 | err = q.SQS.query(q.Url, params, resp) | ||
626 | 339 | return | ||
627 | 340 | } | ||
628 | 341 | |||
629 | 342 | // DeleteMessageBatch action is a batch version of the DeleteMessage action. | ||
630 | 343 | // | ||
631 | 344 | // See http://goo.gl/y1ehG for more details | ||
632 | 345 | func (q *Queue) DeleteMessageBatch(deleteMessageBatch []DeleteMessageBatch) (resp *DeleteMessageBatchResponse, err error) { | ||
633 | 346 | resp = &DeleteMessageBatchResponse{} | ||
634 | 347 | params := makeParams("DeleteMessageBatch") | ||
635 | 348 | |||
636 | 349 | for i, deleteMessage := range deleteMessageBatch { | ||
637 | 350 | params["DeleteMessageBatchRequestEntry."+strconv.Itoa(i+1)+".Id"] = deleteMessage.Id | ||
638 | 351 | params["DeleteMessageBatchRequestEntry."+strconv.Itoa(i+1)+".ReceiptHandle"] = deleteMessage.ReceiptHandle | ||
639 | 352 | } | ||
640 | 353 | |||
641 | 354 | err = q.SQS.query(q.Url, params, resp) | ||
642 | 355 | return | ||
643 | 356 | } | ||
644 | 357 | |||
645 | 358 | // SendMessage action delivers a message to the specified queue. | ||
646 | 359 | // The maximum allowed size is 64KB | ||
647 | 360 | // | ||
648 | 361 | // See http://goo.gl/7OnPb for more details | ||
649 | 362 | func (q *Queue) SendMessage(messageBody string) (resp *SendMessageResponse, err error) { | ||
650 | 363 | resp = &SendMessageResponse{} | ||
651 | 364 | params := makeParams("SendMessage") | ||
652 | 365 | |||
653 | 366 | params["MessageBody"] = messageBody | ||
654 | 367 | err = q.SQS.query(q.Url, params, resp) | ||
655 | 368 | return | ||
656 | 369 | } | ||
657 | 370 | |||
658 | 371 | // SendMessageWithDelay is a helper function for SendMessage action which delivers a message to the specified queue | ||
659 | 372 | // with a delay. | ||
660 | 373 | // | ||
661 | 374 | // See http://goo.gl/7OnPb for more details | ||
662 | 375 | func (q *Queue) SendMessageWithDelay(messageBody string, delaySeconds int) (resp *SendMessageResponse, err error) { | ||
663 | 376 | resp = &SendMessageResponse{} | ||
664 | 377 | params := makeParams("SendMessage") | ||
665 | 378 | |||
666 | 379 | params["MessageBody"] = messageBody | ||
667 | 380 | params["DelaySeconds"] = strconv.Itoa(delaySeconds) | ||
668 | 381 | err = q.SQS.query(q.Url, params, resp) | ||
669 | 382 | return | ||
670 | 383 | } | ||
671 | 384 | |||
672 | 385 | // SendMessageBatch action delivers up to ten messages to the specified queue. | ||
673 | 386 | // | ||
674 | 387 | // See http://goo.gl/mNytv for more details | ||
675 | 388 | func (q *Queue) SendMessageBatch(sendMessageBatchRequests []SendMessageBatchRequestEntry) (resp *SendMessageBatchResponse, err error) { | ||
676 | 389 | resp = &SendMessageBatchResponse{} | ||
677 | 390 | params := makeParams("SendMessageBatch") | ||
678 | 391 | |||
679 | 392 | for i, sendMessageBatchRequest := range sendMessageBatchRequests { | ||
680 | 393 | params["SendMessageBatchRequestEntry."+strconv.Itoa(i+1)+".Id"] = sendMessageBatchRequest.Id | ||
681 | 394 | params["SendMessageBatchRequestEntry."+strconv.Itoa(i+1)+".MessageBody"] = sendMessageBatchRequest.MessageBody | ||
682 | 395 | params["SendMessageBatchRequestEntry."+strconv.Itoa(i+1)+".DelaySeconds"] = strconv.Itoa(sendMessageBatchRequest.DelaySeconds) | ||
683 | 396 | } | ||
684 | 397 | |||
685 | 398 | err = q.SQS.query(q.Url, params, resp) | ||
686 | 399 | return | ||
687 | 400 | } | ||
688 | 401 | |||
689 | 402 | // Delete action deletes the queue specified by the queue URL, regardless of whether the queue is empty. | ||
690 | 403 | // | ||
691 | 404 | // See http://goo.gl/c3YCr for more details | ||
692 | 405 | func (q *Queue) Delete() (resp *DeleteQueueResponse, err error) { | ||
693 | 406 | resp = &DeleteQueueResponse{} | ||
694 | 407 | params := makeParams("Delete") | ||
695 | 408 | |||
696 | 409 | err = q.SQS.query(q.Url, params, resp) | ||
697 | 410 | return | ||
698 | 411 | } | ||
699 | 412 | |||
700 | 413 | // SetQueueAttributes action sets one attribute of a queue per request. | ||
701 | 414 | // | ||
702 | 415 | // See http://goo.gl/LyZnj for more details | ||
703 | 416 | func (q *Queue) SetQueueAttributes(attribute Attribute) (resp *SetQueueAttributesResponse, err error) { | ||
704 | 417 | resp = &SetQueueAttributesResponse{} | ||
705 | 418 | params := makeParams("SetQueueAttributes") | ||
706 | 419 | |||
707 | 420 | params["Attribute.Name"] = attribute.Name | ||
708 | 421 | params["Attribute.Value"] = attribute.Value | ||
709 | 422 | |||
710 | 423 | err = q.SQS.query(q.Url, params, resp) | ||
711 | 424 | return | ||
712 | 425 | } | ||
713 | 426 | |||
714 | 427 | // ListQueues action returns a list of your queues. | ||
715 | 428 | // | ||
716 | 429 | // See http://goo.gl/RPRWr for more details | ||
717 | 430 | |||
718 | 431 | func (s *SQS) ListQueues() (resp *ListQueuesResponse, err error) { | ||
719 | 432 | resp = &ListQueuesResponse{} | ||
720 | 433 | params := makeParams("ListQueues") | ||
721 | 434 | |||
722 | 435 | err = s.query("", params, resp) | ||
723 | 436 | return | ||
724 | 437 | } | ||
725 | 438 | |||
726 | 439 | // ListQueuesWithPrefix action returns only a list of queues with a name beginning with the specified value are returned | ||
727 | 440 | // | ||
728 | 441 | // See http://goo.gl/RPRWr for more details | ||
729 | 442 | func (s *SQS) ListQueuesWithPrefix(queueNamePrefix string) (resp *ListQueuesResponse, err error) { | ||
730 | 443 | resp = &ListQueuesResponse{} | ||
731 | 444 | params := makeParams("ListQueues") | ||
732 | 445 | |||
733 | 446 | if queueNamePrefix != "" { | ||
734 | 447 | params["QueueNamePrefix"] = queueNamePrefix | ||
735 | 448 | } | ||
736 | 449 | |||
737 | 450 | err = s.query("", params, resp) | ||
738 | 451 | return | ||
739 | 452 | } | ||
740 | 453 | |||
741 | 454 | // GetQueue is a helper function for GetQueueUrl action that returns an instance of a queue with specified name. | ||
742 | 455 | // | ||
743 | 456 | // See http://goo.gl/hk7Iu for more details | ||
744 | 457 | func (s *SQS) GetQueue(queueName string) (queue *Queue, err error) { | ||
745 | 458 | resp, err := s.GetQueueUrl(queueName) | ||
746 | 459 | if err != nil { | ||
747 | 460 | return nil, err | ||
748 | 461 | } | ||
749 | 462 | |||
750 | 463 | queue = &Queue{s, resp.QueueUrl} | ||
751 | 464 | return | ||
752 | 465 | } | ||
753 | 466 | |||
754 | 467 | // GetQueueOfOwner is a helper function for GetQueueUrl action that returns an instance of a queue with specified name | ||
755 | 468 | // and belongs to the specified AWS Account Id. | ||
756 | 469 | // | ||
757 | 470 | // See http://goo.gl/hk7Iu for more details | ||
758 | 471 | func (s *SQS) GetQueueOfOwner(queueName, queueOwnerAWSAccountId string) (queue *Queue, err error) { | ||
759 | 472 | resp, err := s.GetQueueUrlOfOwner(queueName, queueOwnerAWSAccountId) | ||
760 | 473 | if err != nil { | ||
761 | 474 | return nil, err | ||
762 | 475 | } | ||
763 | 476 | |||
764 | 477 | queue = &Queue{s, resp.QueueUrl} | ||
765 | 478 | return | ||
766 | 479 | |||
767 | 480 | } | ||
768 | 481 | |||
769 | 482 | // GetQueueUrl action returns the Uniform Resource Locater (URL) of a queue. | ||
770 | 483 | // | ||
771 | 484 | // See http://goo.gl/hk7Iu for more details | ||
772 | 485 | func (s *SQS) GetQueueUrl(queueName string) (resp *GetQueueUrlResponse, err error) { | ||
773 | 486 | resp = &GetQueueUrlResponse{} | ||
774 | 487 | params := makeParams("GetQueueUrl") | ||
775 | 488 | |||
776 | 489 | params["QueueName"] = queueName | ||
777 | 490 | |||
778 | 491 | err = s.query("", params, resp) | ||
779 | 492 | return | ||
780 | 493 | } | ||
781 | 494 | |||
782 | 495 | // GetQueueUrlOfOwner is a helper function for GetQueueUrl action that returns the URL of a queue with specified name | ||
783 | 496 | // and belongs to the specified AWS Account Id. | ||
784 | 497 | // | ||
785 | 498 | // See http://goo.gl/hk7Iu for more details for more details | ||
786 | 499 | func (s *SQS) GetQueueUrlOfOwner(queueName, queueOwnerAWSAccountId string) (resp *GetQueueUrlResponse, err error) { | ||
787 | 500 | resp = &GetQueueUrlResponse{} | ||
788 | 501 | params := makeParams("GetQueueUrl") | ||
789 | 502 | |||
790 | 503 | params["QueueName"] = queueName | ||
791 | 504 | |||
792 | 505 | if queueOwnerAWSAccountId != "" { | ||
793 | 506 | params["QueueOwnerAWSAccountId"] = queueOwnerAWSAccountId | ||
794 | 507 | } | ||
795 | 508 | |||
796 | 509 | err = s.query("", params, resp) | ||
797 | 510 | return | ||
798 | 511 | } | ||
799 | 512 | |||
800 | 513 | func (s *SQS) query(queueUrl string, params map[string]string, resp interface{}) error { | ||
801 | 514 | params["Version"] = "2011-10-01" | ||
802 | 515 | params["Timestamp"] = time.Now().In(time.UTC).Format(time.RFC3339) | ||
803 | 516 | var endpoint *url.URL | ||
804 | 517 | var path string | ||
805 | 518 | var err error | ||
806 | 519 | if queueUrl != "" { | ||
807 | 520 | endpoint, err = url.Parse(queueUrl) | ||
808 | 521 | path = queueUrl[len(s.Region.SQSEndpoint):] | ||
809 | 522 | } else { | ||
810 | 523 | endpoint, err = url.Parse(s.Region.SQSEndpoint) | ||
811 | 524 | path = "/" | ||
812 | 525 | } | ||
813 | 526 | if err != nil { | ||
814 | 527 | return err | ||
815 | 528 | } | ||
816 | 529 | |||
817 | 530 | sign(s.Auth, "GET", path, params, endpoint.Host) | ||
818 | 531 | endpoint.RawQuery = multimap(params).Encode() | ||
819 | 532 | if debug { | ||
820 | 533 | log.Printf("get { %v } -> {\n", endpoint.String()) | ||
821 | 534 | } | ||
822 | 535 | |||
823 | 536 | r, err := http.Get(endpoint.String()) | ||
824 | 537 | if err != nil { | ||
825 | 538 | return err | ||
826 | 539 | } | ||
827 | 540 | defer r.Body.Close() | ||
828 | 541 | |||
829 | 542 | if debug { | ||
830 | 543 | dump, _ := httputil.DumpResponse(r, true) | ||
831 | 544 | log.Printf("response:\n") | ||
832 | 545 | log.Printf("%v\n}\n", string(dump)) | ||
833 | 546 | } | ||
834 | 547 | if r.StatusCode != 200 { | ||
835 | 548 | return buildError(r) | ||
836 | 549 | } | ||
837 | 550 | err = xml.NewDecoder(r.Body).Decode(resp) | ||
838 | 551 | return err | ||
839 | 552 | } | ||
840 | 553 | |||
841 | 554 | func multimap(p map[string]string) url.Values { | ||
842 | 555 | q := make(url.Values, len(p)) | ||
843 | 556 | for k, v := range p { | ||
844 | 557 | q[k] = []string{v} | ||
845 | 558 | } | ||
846 | 559 | return q | ||
847 | 560 | } | ||
848 | 561 | |||
849 | 562 | func buildError(r *http.Response) error { | ||
850 | 563 | errors := xmlErrors{} | ||
851 | 564 | xml.NewDecoder(r.Body).Decode(&errors) | ||
852 | 565 | var err Error | ||
853 | 566 | if len(errors.Errors) > 0 { | ||
854 | 567 | err = errors.Errors[0] | ||
855 | 568 | } | ||
856 | 569 | err.RequestId = errors.RequestId | ||
857 | 570 | err.StatusCode = r.StatusCode | ||
858 | 571 | if err.Message == "" { | ||
859 | 572 | err.Message = r.Status | ||
860 | 573 | } | ||
861 | 574 | return &err | ||
862 | 575 | } | ||
863 | 576 | |||
864 | 577 | func makeParams(action string) map[string]string { | ||
865 | 578 | params := make(map[string]string) | ||
866 | 579 | params["Action"] = action | ||
867 | 580 | return params | ||
868 | 581 | } | ||
869 | 0 | 582 | ||
870 | === added file 'sqs_test.go' | |||
871 | --- sqs_test.go 1970-01-01 00:00:00 +0000 | |||
872 | +++ sqs_test.go 2012-05-25 00:21:19 +0000 | |||
873 | @@ -0,0 +1,306 @@ | |||
874 | 1 | package sqs_test | ||
875 | 2 | |||
876 | 3 | import ( | ||
877 | 4 | "../sqs" | ||
878 | 5 | "launchpad.net/goamz/aws" | ||
879 | 6 | . "launchpad.net/gocheck" | ||
880 | 7 | ) | ||
881 | 8 | |||
882 | 9 | var _ = Suite(&S{}) | ||
883 | 10 | |||
884 | 11 | type S struct { | ||
885 | 12 | //testServer.PrepareResponse(200, nil, TestChangeMessageVisibilityXmlOK) | ||
886 | 13 | HTTPSuite | ||
887 | 14 | sqs *sqs.SQS | ||
888 | 15 | } | ||
889 | 16 | |||
890 | 17 | func (s *S) SetUpSuite(c *C) { | ||
891 | 18 | s.HTTPSuite.SetUpSuite(c) | ||
892 | 19 | auth := aws.Auth{"abc", "123"} | ||
893 | 20 | s.sqs = sqs.New(auth, aws.Region{SQSEndpoint: testServer.URL}) | ||
894 | 21 | } | ||
895 | 22 | |||
896 | 23 | func (s *S) TestCreateQueue(c *C) { | ||
897 | 24 | testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK) | ||
898 | 25 | |||
899 | 26 | timeOutAttribute := sqs.Attribute{"VisibilityTimeout", "60"} | ||
900 | 27 | maxMessageSizeAttribute := sqs.Attribute{"MaximumMessageSize", "65536"} | ||
901 | 28 | messageRetentionAttribute := sqs.Attribute{"MessageRetentionPeriod", "345600"} | ||
902 | 29 | q, err := s.sqs.CreateQueue("testQueue", []sqs.Attribute{timeOutAttribute, maxMessageSizeAttribute, messageRetentionAttribute}) | ||
903 | 30 | req := testServer.WaitRequest() | ||
904 | 31 | |||
905 | 32 | c.Assert(req.Method, Equals, "GET") | ||
906 | 33 | c.Assert(req.URL.Path, Equals, "/") | ||
907 | 34 | c.Assert(req.Header["Date"], Not(Equals), "") | ||
908 | 35 | c.Assert(q.Url, Equals, "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue") | ||
909 | 36 | c.Assert(err, IsNil) | ||
910 | 37 | } | ||
911 | 38 | |||
912 | 39 | func (s *S) TestListQueues(c *C) { | ||
913 | 40 | testServer.PrepareResponse(200, nil, TestListQueuesXmlOK) | ||
914 | 41 | |||
915 | 42 | resp, err := s.sqs.ListQueues() | ||
916 | 43 | req := testServer.WaitRequest() | ||
917 | 44 | |||
918 | 45 | c.Assert(req.Method, Equals, "GET") | ||
919 | 46 | c.Assert(req.URL.Path, Equals, "/") | ||
920 | 47 | c.Assert(req.Header["Date"], Not(Equals), "") | ||
921 | 48 | c.Assert(len(resp.QueueUrl), Not(Equals), 0) | ||
922 | 49 | c.Assert(resp.QueueUrl[0], Equals, "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue") | ||
923 | 50 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "725275ae-0b9b-4762-b238-436d7c65a1ac") | ||
924 | 51 | c.Assert(err, IsNil) | ||
925 | 52 | } | ||
926 | 53 | |||
927 | 54 | func (s *S) TestGetQueueUrl(c *C) { | ||
928 | 55 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
929 | 56 | |||
930 | 57 | resp, err := s.sqs.GetQueueUrl("testQueue") | ||
931 | 58 | req := testServer.WaitRequest() | ||
932 | 59 | |||
933 | 60 | c.Assert(req.Method, Equals, "GET") | ||
934 | 61 | c.Assert(req.URL.Path, Equals, "/") | ||
935 | 62 | c.Assert(req.Header["Date"], Not(Equals), "") | ||
936 | 63 | c.Assert(resp.QueueUrl, Equals, "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue") | ||
937 | 64 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "470a6f13-2ed9-4181-ad8a-2fdea142988e") | ||
938 | 65 | c.Assert(err, IsNil) | ||
939 | 66 | } | ||
940 | 67 | |||
941 | 68 | func (s *S) TestChangeMessageVisibility(c *C) { | ||
942 | 69 | //testServer.PrepareResponse(200, nil, TestChangeMessageVisibilityXmlOK) | ||
943 | 70 | testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK) | ||
944 | 71 | |||
945 | 72 | timeOutAttribute := sqs.Attribute{"VisibilityTimeout", "60"} | ||
946 | 73 | maxMessageSizeAttribute := sqs.Attribute{"MaximumMessageSize", "65536"} | ||
947 | 74 | messageRetentionAttribute := sqs.Attribute{"MessageRetentionPeriod", "345600"} | ||
948 | 75 | q, err := s.sqs.CreateQueue("testQueue", []sqs.Attribute{timeOutAttribute, maxMessageSizeAttribute, messageRetentionAttribute}) | ||
949 | 76 | req := testServer.WaitRequest() | ||
950 | 77 | |||
951 | 78 | c.Assert(req.Method, Equals, "GET") | ||
952 | 79 | testServer.PrepareResponse(200, nil, TestChangeMessageVisibilityXmlOK) | ||
953 | 80 | resp, err := q.ChangeMessageVisibility("MbZj6wDWli%2BJvwwJaBV%2B3dcjk2YW2vA3%2BSTFFljT", 0) | ||
954 | 81 | testServer.WaitRequest() | ||
955 | 82 | c.Assert(err, IsNil) | ||
956 | 83 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "6a7a282a-d013-4a59-aba9-335b0fa48bed") | ||
957 | 84 | } | ||
958 | 85 | |||
959 | 86 | func (s *S) TestChangeMessageVisibilityBatch(c *C) { | ||
960 | 87 | testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK) | ||
961 | 88 | |||
962 | 89 | timeOutAttribute := sqs.Attribute{"VisibilityTimeout", "60"} | ||
963 | 90 | maxMessageSizeAttribute := sqs.Attribute{"MaximumMessageSize", "65536"} | ||
964 | 91 | messageRetentionAttribute := sqs.Attribute{"MessageRetentionPeriod", "345600"} | ||
965 | 92 | q, err := s.sqs.CreateQueue("testQueue", []sqs.Attribute{timeOutAttribute, maxMessageSizeAttribute, messageRetentionAttribute}) | ||
966 | 93 | testServer.WaitRequest() | ||
967 | 94 | |||
968 | 95 | testServer.PrepareResponse(200, nil, TestChangeMessaveVisibilityBatchXmlOK) | ||
969 | 96 | |||
970 | 97 | messageVisibilityBatch := []sqs.ChangeMessageVisibilityBatchEntry{sqs.ChangeMessageVisibilityBatchEntry{"change_visibility_msg_2", "gfk0T0R0waama4fVFffkjKzmhMCymjQvfTFk2LxT33G4ms5subrE0deLKWSscPU1oD3J9zgeS4PQQ3U30qOumIE6AdAv3w%2F%2Fa1IXW6AqaWhGsEPaLm3Vf6IiWqdM8u5imB%2BNTwj3tQRzOWdTOePjOjPcTpRxBtXix%2BEvwJOZUma9wabv%2BSw6ZHjwmNcVDx8dZXJhVp16Bksiox%2FGrUvrVTCJRTWTLc59oHLLF8sEkKzRmGNzTDGTiV%2BYjHfQj60FD3rVaXmzTsoNxRhKJ72uIHVMGVQiAGgBX6HGv9LDmYhPXw4hy%2FNgIg%3D%3D", 45}, sqs.ChangeMessageVisibilityBatchEntry{"change_visibility_msg_3", "gfk0T0R0waama4fVFffkjKzmhMCymjQvfTFk2LxT33FUgBz3%2BnougdeLKWSscPU1%2FXgx%2BxcNnjnQQ3U30qOumIE6AdAv3w%2F%2Fa1IXW6AqaWhGsEPaLm3Vf6IiWqdM8u5imB%2BNTwj3tQRzOWdTOePjOsogjZM%2F7kzn4Ew27XLU9I%2FYaWYmKvDbq%2Fk3HKVB9HfB43kE49atP2aWrzNL4yunG41Q4cfRRtfJdcGQGNHQ2%2Byd0Usf5qR1dZr1iDo5xk946eQat83AxTRP%2BY4Qi0V7FAeSLH9su9xpX6HGv9LDmYhPXw4hy%2FNgIg%3D%3D", 45}} | ||
971 | 98 | resp, err := q.ChangeMessageVisibilityBatch(messageVisibilityBatch) | ||
972 | 99 | testServer.WaitRequest() | ||
973 | 100 | c.Assert(err, IsNil) | ||
974 | 101 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "ca9668f7-ab1b-4f7a-8859-f15747ab17a7") | ||
975 | 102 | c.Assert(resp.Id[0], Equals, "change_visibility_msg_2") | ||
976 | 103 | c.Assert(resp.Id[1], Equals, "change_visibility_msg_3") | ||
977 | 104 | } | ||
978 | 105 | |||
979 | 106 | func (s *S) TestReceiveMessage(c *C) { | ||
980 | 107 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
981 | 108 | |||
982 | 109 | q, err := s.sqs.GetQueue("testQueue") | ||
983 | 110 | testServer.WaitRequest() | ||
984 | 111 | |||
985 | 112 | testServer.PrepareResponse(200, nil, TestReceiveMessageXmlOK) | ||
986 | 113 | |||
987 | 114 | resp, err := q.ReceiveMessage([]string{"All"}, 5, 15) | ||
988 | 115 | testServer.WaitRequest() | ||
989 | 116 | c.Assert(err, IsNil) | ||
990 | 117 | c.Assert(len(resp.Messages), Not(Equals), 0) | ||
991 | 118 | } | ||
992 | 119 | |||
993 | 120 | func (s *S) TestDeleteMessage(c *C) { | ||
994 | 121 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
995 | 122 | |||
996 | 123 | q, err := s.sqs.GetQueue("testQueue") | ||
997 | 124 | testServer.WaitRequest() | ||
998 | 125 | |||
999 | 126 | testServer.PrepareResponse(200, nil, TestDeleteMessageXmlOK) | ||
1000 | 127 | |||
1001 | 128 | resp, err := q.DeleteMessage("MbZj6wDWli%2BJvwwJaBV%2B3dcjk2YW2vA3%2BSTFFljTM8tJJg6HRG6PYSasuWXPJB%2BCwLj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ%2BQEauMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=") | ||
1002 | 129 | testServer.WaitRequest() | ||
1003 | 130 | c.Assert(err, IsNil) | ||
1004 | 131 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "b5293cb5-d306-4a17-9048-b263635abe42") | ||
1005 | 132 | } | ||
1006 | 133 | |||
1007 | 134 | func (s *S) TestDeleteMessageBatch(c *C) { | ||
1008 | 135 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1009 | 136 | |||
1010 | 137 | q, err := s.sqs.GetQueue("testQueue") | ||
1011 | 138 | testServer.WaitRequest() | ||
1012 | 139 | |||
1013 | 140 | testServer.PrepareResponse(200, nil, TestDeleteMessageBatchXmlOK) | ||
1014 | 141 | |||
1015 | 142 | deleteMessageBatch := []sqs.DeleteMessageBatch{sqs.DeleteMessageBatch{Id: "msg1", ReceiptHandle: "gfk0T0R0waama4fVFffkjPQrrvzMrOg0fTFk2LxT33EuB8wR0ZCFgKWyXGWFoqqpCIiprQUEhir%2F5LeGPpYTLzjqLQxyQYaQALeSNHb0us3uE84uujxpBhsDkZUQkjFFkNqBXn48xlMcVhTcI3YLH%2Bd%2BIqetIOHgBCZAPx6r%2B09dWaBXei6nbK5Ygih21DCDdAwFV68Jo8DXhb3ErEfoDqx7vyvC5nCpdwqv%2BJhU%2FTNGjNN8t51v5c%2FAXvQsAzyZVNapxUrHIt4NxRhKJ72uICcxruyE8eRXlxIVNgeNP8ZEDcw7zZU1Zw%3D%3D"}, sqs.DeleteMessageBatch{Id: "msg2", ReceiptHandle: "gfk0T0R0waama4fVFffkjKzmhMCymjQvfTFk2LxT33G4ms5subrE0deLKWSscPU1oD3J9zgeS4PQQ3U30qOumIE6AdAv3w%2F%2Fa1IXW6AqaWhGsEPaLm3Vf6IiWqdM8u5imB%2BNTwj3tQRzOWdTOePjOjPcTpRxBtXix%2BEvwJOZUma9wabv%2BSw6ZHjwmNcVDx8dZXJhVp16Bksiox%2FGrUvrVTCJRTWTLc59oHLLF8sEkKzRmGNzTDGTiV%2BYjHfQj60FD3rVaXmzTsoNxRhKJ72uIHVMGVQiAGgB%2BqAbSqfKHDQtVOmJJgkHug%3D%3D"}} | ||
1016 | 143 | resp, err := q.DeleteMessageBatch(deleteMessageBatch) | ||
1017 | 144 | testServer.WaitRequest() | ||
1018 | 145 | |||
1019 | 146 | c.Assert(err, IsNil) | ||
1020 | 147 | c.Assert(len(resp.DeleteMessageBatchResult.Ids), Equals, 2) | ||
1021 | 148 | c.Assert(resp.DeleteMessageBatchResult.Ids[0], Equals, "msg1") | ||
1022 | 149 | c.Assert(resp.DeleteMessageBatchResult.Ids[1], Equals, "msg2") | ||
1023 | 150 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "d6f86b7a-74d1-4439-b43f-196a1e29cd85") | ||
1024 | 151 | } | ||
1025 | 152 | |||
1026 | 153 | func (s *S) TestAddPermission(c *C) { | ||
1027 | 154 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1028 | 155 | |||
1029 | 156 | q, err := s.sqs.GetQueue("testQueue") | ||
1030 | 157 | testServer.WaitRequest() | ||
1031 | 158 | |||
1032 | 159 | testServer.PrepareResponse(200, nil, TestAddPermissionXmlOK) | ||
1033 | 160 | resp, err := q.AddPermission("testLabel", []sqs.AccountPermission{sqs.AccountPermission{"125074342641", "SendMessage"}, sqs.AccountPermission{"125074342642", "ReceiveMessage"}}) | ||
1034 | 161 | testServer.WaitRequest() | ||
1035 | 162 | |||
1036 | 163 | c.Assert(err, IsNil) | ||
1037 | 164 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "9a285199-c8d6-47c2-bdb2-314cb47d599d") | ||
1038 | 165 | } | ||
1039 | 166 | |||
1040 | 167 | func (s *S) TestRemovePermission(c *C) { | ||
1041 | 168 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1042 | 169 | |||
1043 | 170 | q, err := s.sqs.GetQueue("testQueue") | ||
1044 | 171 | testServer.WaitRequest() | ||
1045 | 172 | |||
1046 | 173 | testServer.PrepareResponse(200, nil, TestRemovePermissionXmlOK) | ||
1047 | 174 | resp, err := q.RemovePermission("testLabel") | ||
1048 | 175 | testServer.WaitRequest() | ||
1049 | 176 | |||
1050 | 177 | c.Assert(err, IsNil) | ||
1051 | 178 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "f8bdb362-6616-42c0-977a-ce9a8bcce3bb") | ||
1052 | 179 | } | ||
1053 | 180 | |||
1054 | 181 | func (s *S) TestSendMessage(c *C) { | ||
1055 | 182 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1056 | 183 | |||
1057 | 184 | q, err := s.sqs.GetQueue("testQueue") | ||
1058 | 185 | testServer.WaitRequest() | ||
1059 | 186 | |||
1060 | 187 | testServer.PrepareResponse(200, nil, TestSendMessageXmlOK) | ||
1061 | 188 | |||
1062 | 189 | resp, err := q.SendMessage("This is a Message") | ||
1063 | 190 | testServer.WaitRequest() | ||
1064 | 191 | c.Assert(err, IsNil) | ||
1065 | 192 | c.Assert(resp.SendMessageResult.MD5OfMessageBody, Equals, "fafb00f5732ab283681e124bf8747ed1") | ||
1066 | 193 | c.Assert(resp.SendMessageResult.MessageId, Equals, "5fea7756-0ea4-451a-a703-a558b933e274") | ||
1067 | 194 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "27daac76-34dd-47df-bd01-1f6e873584a0") | ||
1068 | 195 | } | ||
1069 | 196 | |||
1070 | 197 | func (s *S) TestSendMessageWithDelay(c *C) { | ||
1071 | 198 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1072 | 199 | |||
1073 | 200 | q, err := s.sqs.GetQueue("testQueue") | ||
1074 | 201 | testServer.WaitRequest() | ||
1075 | 202 | |||
1076 | 203 | testServer.PrepareResponse(200, nil, TestSendMessageXmlOK) | ||
1077 | 204 | |||
1078 | 205 | resp, err := q.SendMessageWithDelay("This is a Message", 60) | ||
1079 | 206 | testServer.WaitRequest() | ||
1080 | 207 | c.Assert(err, IsNil) | ||
1081 | 208 | c.Assert(resp.SendMessageResult.MD5OfMessageBody, Equals, "fafb00f5732ab283681e124bf8747ed1") | ||
1082 | 209 | c.Assert(resp.SendMessageResult.MessageId, Equals, "5fea7756-0ea4-451a-a703-a558b933e274") | ||
1083 | 210 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "27daac76-34dd-47df-bd01-1f6e873584a0") | ||
1084 | 211 | } | ||
1085 | 212 | |||
1086 | 213 | func (s *S) TestSendMessageBatch(c *C) { | ||
1087 | 214 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1088 | 215 | |||
1089 | 216 | q, err := s.sqs.GetQueue("testQueue") | ||
1090 | 217 | testServer.WaitRequest() | ||
1091 | 218 | |||
1092 | 219 | testServer.PrepareResponse(200, nil, TestSendMessageBatchXmlOK) | ||
1093 | 220 | |||
1094 | 221 | sendMessageBatchRequests := []sqs.SendMessageBatchRequestEntry{sqs.SendMessageBatchRequestEntry{Id: "test_msg_001", MessageBody: "test message body 1", DelaySeconds: 30}} | ||
1095 | 222 | resp, err := q.SendMessageBatch(sendMessageBatchRequests) | ||
1096 | 223 | testServer.WaitRequest() | ||
1097 | 224 | c.Assert(err, IsNil) | ||
1098 | 225 | c.Assert(len(resp.SendMessageBatchResult.Entries), Equals, 2) | ||
1099 | 226 | c.Assert(resp.SendMessageBatchResult.Entries[0].Id, Equals, "test_msg_001") | ||
1100 | 227 | } | ||
1101 | 228 | |||
1102 | 229 | func (s *S) TestGetQueueAttributes(c *C) { | ||
1103 | 230 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1104 | 231 | |||
1105 | 232 | q, err := s.sqs.GetQueue("testQueue") | ||
1106 | 233 | testServer.WaitRequest() | ||
1107 | 234 | |||
1108 | 235 | testServer.PrepareResponse(200, nil, TestGetQueueAttributesAllXmlOK) | ||
1109 | 236 | |||
1110 | 237 | resp, err := q.GetQueueAttributes([]string{"ALL"}) | ||
1111 | 238 | testServer.WaitRequest() | ||
1112 | 239 | |||
1113 | 240 | c.Assert(err, IsNil) | ||
1114 | 241 | c.Assert(len(resp.Attributes), Equals, 8) | ||
1115 | 242 | c.Assert(resp.Attributes[0].Name, Equals, "VisibilityTimeout") | ||
1116 | 243 | c.Assert(resp.Attributes[0].Value, Equals, "30") | ||
1117 | 244 | } | ||
1118 | 245 | |||
1119 | 246 | func (s *S) TestGetQueueAttributesSelective(c *C) { | ||
1120 | 247 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1121 | 248 | |||
1122 | 249 | q, err := s.sqs.GetQueue("testQueue") | ||
1123 | 250 | testServer.WaitRequest() | ||
1124 | 251 | |||
1125 | 252 | testServer.PrepareResponse(200, nil, TestGetQueueAttributesSelectiveXmlOK) | ||
1126 | 253 | |||
1127 | 254 | resp, err := q.GetQueueAttributes([]string{"VisibilityTimeout", "DelaySeconds"}) | ||
1128 | 255 | testServer.WaitRequest() | ||
1129 | 256 | |||
1130 | 257 | c.Assert(err, IsNil) | ||
1131 | 258 | c.Assert(len(resp.Attributes), Equals, 2) | ||
1132 | 259 | c.Assert(resp.Attributes[0].Name, Equals, "VisibilityTimeout") | ||
1133 | 260 | c.Assert(resp.Attributes[0].Value, Equals, "30") | ||
1134 | 261 | c.Assert(resp.Attributes[1].Name, Equals, "DelaySeconds") | ||
1135 | 262 | c.Assert(resp.Attributes[1].Value, Equals, "0") | ||
1136 | 263 | } | ||
1137 | 264 | |||
1138 | 265 | func (s *S) TestDeleteQueue(c *C) { | ||
1139 | 266 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1140 | 267 | |||
1141 | 268 | q, err := s.sqs.GetQueue("testQueue") | ||
1142 | 269 | testServer.WaitRequest() | ||
1143 | 270 | |||
1144 | 271 | testServer.PrepareResponse(200, nil, TestDeleteQueueXmlOK) | ||
1145 | 272 | resp, err := q.Delete() | ||
1146 | 273 | testServer.WaitRequest() | ||
1147 | 274 | |||
1148 | 275 | c.Assert(err, IsNil) | ||
1149 | 276 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "6fde8d1e-52cd-4581-8cd9-c512f4c64223") | ||
1150 | 277 | } | ||
1151 | 278 | |||
1152 | 279 | func (s *S) TestSetQueueAttributes(c *C) { | ||
1153 | 280 | testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK) | ||
1154 | 281 | |||
1155 | 282 | q, err := s.sqs.GetQueue("testQueue") | ||
1156 | 283 | testServer.WaitRequest() | ||
1157 | 284 | |||
1158 | 285 | testServer.PrepareResponse(200, nil, TestSetQueueAttributesXmlOK) | ||
1159 | 286 | var policyStr = ` | ||
1160 | 287 | { | ||
1161 | 288 | "Version":"2008-10-17", | ||
1162 | 289 | "Id":"/123456789012/testQueue/SQSDefaultPolicy", | ||
1163 | 290 | "Statement": [ | ||
1164 | 291 | { | ||
1165 | 292 | "Sid":"Queue1ReceiveMessage", | ||
1166 | 293 | "Effect":"Allow", | ||
1167 | 294 | "Principal":{"AWS":"*"}, | ||
1168 | 295 | "Action":"SQS:ReceiveMessage", | ||
1169 | 296 | "Resource":"arn:aws:sqs:us-east-1:123456789012:testQueue" | ||
1170 | 297 | } | ||
1171 | 298 | ] | ||
1172 | 299 | } | ||
1173 | 300 | ` | ||
1174 | 301 | resp, err := q.SetQueueAttributes(sqs.Attribute{"Policy", policyStr}) | ||
1175 | 302 | testServer.WaitRequest() | ||
1176 | 303 | |||
1177 | 304 | c.Assert(err, IsNil) | ||
1178 | 305 | c.Assert(resp.ResponseMetadata.RequestId, Equals, "e5cca473-4fc0-4198-a451-8abb94d02c75") | ||
1179 | 306 | } | ||
1180 | 0 | 307 | ||
1181 | === added file 'suite_test.go' | |||
1182 | --- suite_test.go 1970-01-01 00:00:00 +0000 | |||
1183 | +++ suite_test.go 2012-05-25 00:21:19 +0000 | |||
1184 | @@ -0,0 +1,120 @@ | |||
1185 | 1 | package sqs_test | ||
1186 | 2 | |||
1187 | 3 | import ( | ||
1188 | 4 | "fmt" | ||
1189 | 5 | . "launchpad.net/gocheck" | ||
1190 | 6 | "net/http" | ||
1191 | 7 | "net/url" | ||
1192 | 8 | "os" | ||
1193 | 9 | "testing" | ||
1194 | 10 | "time" | ||
1195 | 11 | ) | ||
1196 | 12 | |||
1197 | 13 | func Test(t *testing.T) { | ||
1198 | 14 | TestingT(t) | ||
1199 | 15 | } | ||
1200 | 16 | |||
1201 | 17 | type HTTPSuite struct{} | ||
1202 | 18 | |||
1203 | 19 | var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second) | ||
1204 | 20 | |||
1205 | 21 | func (s *HTTPSuite) SetUpSuite(c *C) { | ||
1206 | 22 | testServer.Start() | ||
1207 | 23 | } | ||
1208 | 24 | |||
1209 | 25 | func (s *HTTPSuite) TearDownTest(c *C) { | ||
1210 | 26 | testServer.FlushRequests() | ||
1211 | 27 | } | ||
1212 | 28 | |||
1213 | 29 | type TestHTTPServer struct { | ||
1214 | 30 | URL string | ||
1215 | 31 | Timeout time.Duration | ||
1216 | 32 | started bool | ||
1217 | 33 | request chan *http.Request | ||
1218 | 34 | response chan *testResponse | ||
1219 | 35 | pending chan bool | ||
1220 | 36 | } | ||
1221 | 37 | |||
1222 | 38 | type testResponse struct { | ||
1223 | 39 | Status int | ||
1224 | 40 | Headers map[string]string | ||
1225 | 41 | Body string | ||
1226 | 42 | } | ||
1227 | 43 | |||
1228 | 44 | func NewTestHTTPServer(url string, timeout time.Duration) *TestHTTPServer { | ||
1229 | 45 | return &TestHTTPServer{URL: url, Timeout: timeout} | ||
1230 | 46 | } | ||
1231 | 47 | |||
1232 | 48 | func (s *TestHTTPServer) Start() { | ||
1233 | 49 | if s.started { | ||
1234 | 50 | return | ||
1235 | 51 | } | ||
1236 | 52 | s.started = true | ||
1237 | 53 | |||
1238 | 54 | s.request = make(chan *http.Request, 64) | ||
1239 | 55 | s.response = make(chan *testResponse, 64) | ||
1240 | 56 | s.pending = make(chan bool, 64) | ||
1241 | 57 | |||
1242 | 58 | url, _ := url.Parse(s.URL) | ||
1243 | 59 | go http.ListenAndServe(url.Host, s) | ||
1244 | 60 | |||
1245 | 61 | s.PrepareResponse(202, nil, "Nothing.") | ||
1246 | 62 | for { | ||
1247 | 63 | // Wait for it to be up. | ||
1248 | 64 | resp, err := http.Get(s.URL) | ||
1249 | 65 | if err == nil && resp.StatusCode == 202 { | ||
1250 | 66 | break | ||
1251 | 67 | } | ||
1252 | 68 | fmt.Fprintf(os.Stderr, "\nWaiting for fake server to be up... ") | ||
1253 | 69 | time.Sleep(1e8) | ||
1254 | 70 | } | ||
1255 | 71 | fmt.Fprintf(os.Stderr, "done\n\n") | ||
1256 | 72 | s.WaitRequest() // Consume dummy request | ||
1257 | 73 | } | ||
1258 | 74 | |||
1259 | 75 | // FulshRequests discards requests which were not yet consumed by WaitRequest | ||
1260 | 76 | func (s *TestHTTPServer) FlushRequests() { | ||
1261 | 77 | for { | ||
1262 | 78 | select { | ||
1263 | 79 | case <-s.request: | ||
1264 | 80 | default: | ||
1265 | 81 | return | ||
1266 | 82 | } | ||
1267 | 83 | } | ||
1268 | 84 | } | ||
1269 | 85 | |||
1270 | 86 | func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { | ||
1271 | 87 | s.request <- req | ||
1272 | 88 | var resp *testResponse | ||
1273 | 89 | select { | ||
1274 | 90 | case resp = <-s.response: | ||
1275 | 91 | case <-time.After(s.Timeout): | ||
1276 | 92 | fmt.Fprintf(os.Stderr, "ERROR: Timeout waiting for test to provide response\n") | ||
1277 | 93 | resp = &testResponse{500, nil, ""} | ||
1278 | 94 | } | ||
1279 | 95 | if resp.Headers != nil { | ||
1280 | 96 | h := w.Header() | ||
1281 | 97 | for k, v := range resp.Headers { | ||
1282 | 98 | h.Set(k, v) | ||
1283 | 99 | } | ||
1284 | 100 | } | ||
1285 | 101 | if resp.Status != 0 { | ||
1286 | 102 | w.WriteHeader(resp.Status) | ||
1287 | 103 | } | ||
1288 | 104 | w.Write([]byte(resp.Body)) | ||
1289 | 105 | } | ||
1290 | 106 | |||
1291 | 107 | func (s *TestHTTPServer) WaitRequest() *http.Request { | ||
1292 | 108 | select { | ||
1293 | 109 | case req := <-s.request: | ||
1294 | 110 | req.ParseForm() | ||
1295 | 111 | return req | ||
1296 | 112 | case <-time.After(s.Timeout): | ||
1297 | 113 | panic("Timeout waiting for goamz request") | ||
1298 | 114 | } | ||
1299 | 115 | panic("unreached") | ||
1300 | 116 | } | ||
1301 | 117 | |||
1302 | 118 | func (s *TestHTTPServer) PrepareResponse(status int, headers map[string]string, body string) { | ||
1303 | 119 | s.response <- &testResponse{status, headers, body} | ||
1304 | 120 | } |