Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 338 lines (295 sloc) 8.591 kb
4187044 @edsrzf First commit
edsrzf authored
1 //
2 // goamz - Go packages to interact with the Amazon Web Services.
3 //
4 // https://wiki.ubuntu.com/goamz
5 //
6 // Copyright (c) 2011 Iron.io
7 //
8 // Written by Evan Shaw <evan@iron.io>
9 //
10 package sqs
11
12 import (
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
13 "encoding/xml"
4187044 @edsrzf First commit
edsrzf authored
14 "fmt"
15 "io/ioutil"
16 "launchpad.net/goamz/aws"
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
17 "net/http"
18 "net/url"
4187044 @edsrzf First commit
edsrzf authored
19 "path"
20 "strconv"
21 "strings"
22 "time"
23 )
24
25 // The SQS type encapsulates operations with a specific SQS region.
26 type SQS struct {
27 aws.Auth
28 aws.Region
29 private byte // Reserve the right of using private data.
30 }
31
32 // The Queue type encapsulates operations with an SQS queue.
33 type Queue struct {
34 *SQS
35 path string
36 }
37
38 // An Attribute specifies which attribute of a message to set or receive.
39 type Attribute string
40
41 const (
42 All Attribute = "All"
43 ApproximateNumberOfMessages Attribute = "ApproximateNumberOfMessages"
44 ApproximateNumberOfMessagesNotVisible Attribute = "ApproximateNumberOfMessagesNotVisible"
45 VisibilityTimeout Attribute = "VisibilityTimeout"
46 CreatedTimestamp Attribute = "CreatedTimestamp"
47 LastModifiedTimestamp Attribute = "LastModifiedTimestamp"
48 Policy Attribute = "Policy"
49 MaximumMessageSize Attribute = "MaximumMessageSize"
50 MessageRetentionPeriod Attribute = "MessageRetentionPeriod"
51 QueueArn Attribute = "QueueArn"
52 )
53
54 // New creates a new SQS.
55 func New(auth aws.Auth, region aws.Region) *SQS {
56 return &SQS{auth, region, 0}
57 }
58
59 type ResponseMetadata struct {
60 RequestId string
61 }
62
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
63 func (sqs *SQS) Queue(name string) (*Queue, error) {
4187044 @edsrzf First commit
edsrzf authored
64 qs, err := sqs.ListQueues(name)
65 if err != nil {
66 return nil, err
67 }
68 for _, q := range qs {
69 if q.Name() == name {
70 return q, nil
71 }
72 }
73 // TODO: return error
74 return nil, nil
75 }
76
77 type listQueuesResponse struct {
78 Queues []string `xml:"ListQueuesResult>QueueUrl"`
79 ResponseMetadata
80 }
81
82 // ListQueues returns a list of your queues.
83 //
84 // See http://goo.gl/q1ue9 for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
85 func (sqs *SQS) ListQueues(namePrefix string) ([]*Queue, error) {
eee2ff5 @treeder gofixed
treeder authored
86 params := url.Values{}
4187044 @edsrzf First commit
edsrzf authored
87 if namePrefix != "" {
88 params.Set("QueueNamePrefix", namePrefix)
89 }
90 var resp listQueuesResponse
91 if err := sqs.get("ListQueues", "/", params, &resp); err != nil {
92 return nil, err
93 }
94 queues := make([]*Queue, len(resp.Queues))
95 for i, queue := range resp.Queues {
eee2ff5 @treeder gofixed
treeder authored
96 u, err := url.Parse(queue)
4187044 @edsrzf First commit
edsrzf authored
97 if err != nil {
98 return nil, err
99 }
100 queues[i] = &Queue{sqs, u.Path}
101 }
102 return queues, nil
103 }
104
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
105 func (sqs *SQS) newRequest(method, action, url_ string, params url.Values) (*http.Request, error) {
eee2ff5 @treeder gofixed
treeder authored
106 req, err := http.NewRequest("GET", url_, nil)
4187044 @edsrzf First commit
edsrzf authored
107 if err != nil {
108 return nil, err
109 }
110
111 params["Action"] = []string{action}
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
112 params["Timestamp"] = []string{time.Now().UTC().Format(time.RFC3339)}
4187044 @edsrzf First commit
edsrzf authored
113 params["Version"] = []string{"2009-02-01"}
114
115 req.Header.Set("Host", req.Host)
116
117 sign(sqs.Auth, method, req.URL.Path, params, req.Header)
118 return req, nil
119 }
120
121 // Error encapsulates an error returned by SDB.
122 type Error struct {
123 StatusCode int // HTTP status code (200, 403, ...)
124 StatusMsg string // HTTP status message ("Service Unavailable", "Bad Request", ...)
125 Type string // Whether the error was a receiver or sender error
126 Code string // SQS error code ("InvalidParameterValue", ...)
127 Message string // The human-oriented error message
128 RequestId string // A unique ID for this request
129 }
130
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
131 func (err *Error) Error() string {
4187044 @edsrzf First commit
edsrzf authored
132 return err.Message
133 }
134
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
135 func buildError(r *http.Response) error {
4187044 @edsrzf First commit
edsrzf authored
136 err := Error{}
137 err.StatusCode = r.StatusCode
138 err.StatusMsg = r.Status
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
139 body, _ := ioutil.ReadAll(r.Body)
140 xml.Unmarshal(body, &err)
4187044 @edsrzf First commit
edsrzf authored
141 return &err
142 }
143
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
144 func (sqs *SQS) doRequest(req *http.Request, resp interface{}) error {
4187044 @edsrzf First commit
edsrzf authored
145 /*dump, _ := http.DumpRequest(req, true)
146 println("req DUMP:\n", string(dump))*/
147
148 r, err := http.DefaultClient.Do(req)
149 if err != nil {
150 return err
151 }
152
153 defer r.Body.Close()
154 /*str, _ := http.DumpResponse(r, true)
155 fmt.Printf("response text: %s\n", str)
156 fmt.Printf("response struct: %+v\n", resp)*/
157 if r.StatusCode != 200 {
158 return buildError(r)
159 }
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
160 body, _ := ioutil.ReadAll(r.Body)
161 return xml.Unmarshal(body, resp)
4187044 @edsrzf First commit
edsrzf authored
162 }
163
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
164 func (sqs *SQS) post(action, path string, params url.Values, body []byte, resp interface{}) error {
d6462d8 @edsrzf Hack so it doesn't require changes to goamz/aws
edsrzf authored
165 endpoint := strings.Replace(sqs.Region.EC2Endpoint, "ec2", "sqs", 1) + path
166 req, err := sqs.newRequest("POST", action, endpoint, params)
4187044 @edsrzf First commit
edsrzf authored
167 if err != nil {
168 return err
169 }
170 req.Header.Set("Content-Type", "x-www-form-urlencoded")
171
172 encodedParams := params.Encode()
173 req.Body = ioutil.NopCloser(strings.NewReader(encodedParams))
174 req.ContentLength = int64(len(encodedParams))
175
176 return sqs.doRequest(req, resp)
177 }
178
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
179 func (sqs *SQS) get(action, path string, params url.Values, resp interface{}) error {
4187044 @edsrzf First commit
edsrzf authored
180 if params == nil {
eee2ff5 @treeder gofixed
treeder authored
181 params = url.Values{}
4187044 @edsrzf First commit
edsrzf authored
182 }
d6462d8 @edsrzf Hack so it doesn't require changes to goamz/aws
edsrzf authored
183 endpoint := strings.Replace(sqs.Region.EC2Endpoint, "ec2", "sqs", 1) + path
184 req, err := sqs.newRequest("GET", action, endpoint, params)
4187044 @edsrzf First commit
edsrzf authored
185 if err != nil {
186 return err
187 }
188
189 if len(params) > 0 {
190 req.URL.RawQuery = params.Encode()
191 }
192
193 return sqs.doRequest(req, resp)
194 }
195
196 func (q *Queue) Name() string {
197 return path.Base(q.path)
198 }
199
200 // AddPermission adds a permission to a queue for a specific principal.
201 //
202 // See http://goo.gl/vG4CP for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
203 func (q *Queue) AddPermission() error {
4187044 @edsrzf First commit
edsrzf authored
204 return nil
205 }
206
207 // ChangeMessageVisibility changes the visibility timeout of a specified message
208 // in a queue to a new value.
209 //
210 // See http://goo.gl/tORrh for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
211 func (q *Queue) ChangeMessageVisibility() error {
4187044 @edsrzf First commit
edsrzf authored
212 return nil
213 }
214
215 type CreateQueueOpt struct {
216 DefaultVisibilityTimeout int
217 }
218
219 type createQueuesResponse struct {
220 QueueUrl string `xml:"CreateQueueResult>QueueUrl"`
221 ResponseMetadata
222 }
223
224 // CreateQueue creates a new queue.
225 //
226 // See http://goo.gl/EwNUK for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
227 func (sqs *SQS) CreateQueue(name string, opt *CreateQueueOpt) (*Queue, error) {
eee2ff5 @treeder gofixed
treeder authored
228 params := url.Values{
4187044 @edsrzf First commit
edsrzf authored
229 "QueueName": []string{name},
230 }
231 if opt != nil {
232 dvt := strconv.Itoa(opt.DefaultVisibilityTimeout)
233 params["DefaultVisibilityTimeout"] = []string{dvt}
234 }
235 var resp createQueuesResponse
236 if err := sqs.get("CreateQueue", "/", params, &resp); err != nil {
237 return nil, err
238 }
eee2ff5 @treeder gofixed
treeder authored
239 u, err := url.Parse(resp.QueueUrl)
4187044 @edsrzf First commit
edsrzf authored
240 if err != nil {
241 return nil, err
242 }
243 return &Queue{sqs, u.Path}, nil
244 }
245
246 // DeleteQueue deletes a queue.
247 //
248 // See http://goo.gl/zc45Q for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
249 func (q *Queue) DeleteQueue() error {
eee2ff5 @treeder gofixed
treeder authored
250 params := url.Values{}
4187044 @edsrzf First commit
edsrzf authored
251 var resp ResponseMetadata
252 if err := q.SQS.get("DeleteQueue", q.path, params, &resp); err != nil {
253 return err
254 }
255 return nil
256 }
257
258 // DeleteMessage deletes a message from the queue.
259 //
260 // See http://goo.gl/t8jnk for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
261 func (q *Queue) DeleteMessage() error {
4187044 @edsrzf First commit
edsrzf authored
262 return nil
263 }
264
265 type QueueAttributes struct {
266 Attributes []struct {
eee2ff5 @treeder gofixed
treeder authored
267 Name string
4187044 @edsrzf First commit
edsrzf authored
268 Value string
269 }
270 ResponseMetadata
271 }
272
273 // GetQueueAttributes returns one or all attributes of a queue.
274 //
275 // See http://goo.gl/X01zD for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
276 func (q *Queue) GetQueueAttributes(attrs ...Attribute) (*QueueAttributes, error) {
eee2ff5 @treeder gofixed
treeder authored
277 params := url.Values{}
4187044 @edsrzf First commit
edsrzf authored
278 for i, attr := range attrs {
279 key := fmt.Sprintf("Attribute.%d", i)
280 params[key] = []string{string(attr)}
281 }
282 var resp QueueAttributes
283 if err := q.get("GetQueueAttributes", q.path, params, &resp); err != nil {
284 return nil, err
285 }
286 return &resp, nil
287 }
288
289 type Message struct {
290 Id string `xml:"ReceiveMessageResult>Message>MessageId"`
291 Body string `xml:"ReceiveMessageResult>Message>Body"`
292 }
293
294 // ReceiveMessage retrieves one or more messages from the queue.
295 //
296 // See http://goo.gl/8RLI4 for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
297 func (q *Queue) ReceiveMessage() (*Message, error) {
4187044 @edsrzf First commit
edsrzf authored
298 var resp Message
299 if err := q.get("ReceiveMessage", q.path, nil, &resp); err != nil {
300 return nil, err
301 }
302 return &resp, nil
303 }
304
305 // RemovePermission removes a permission from a queue for a specific principal.
306 //
307 // See http://goo.gl/5QB9W for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
308 func (q *Queue) RemovePermission() error {
4187044 @edsrzf First commit
edsrzf authored
309 return nil
310 }
311
312 type sendMessageResponse struct {
313 Id string `xml:"SendMessageResult>MessageId"`
314 ResponseMetadata
315 }
316
317 // SendMessage delivers a message to the specified queue.
d6462d8 @edsrzf Hack so it doesn't require changes to goamz/aws
edsrzf authored
318 // It returns the sent message's ID.
4187044 @edsrzf First commit
edsrzf authored
319 //
320 // See http://goo.gl/ThjJG for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
321 func (q *Queue) SendMessage(body string) (string, error) {
eee2ff5 @treeder gofixed
treeder authored
322 params := url.Values{
4187044 @edsrzf First commit
edsrzf authored
323 "MessageBody": []string{body},
324 }
325 var resp sendMessageResponse
326 if err := q.get("SendMessage", q.path, params, &resp); err != nil {
327 return "", err
328 }
329 return resp.Id, nil
330 }
331
332 // SetQueueAttributes sets one attribute of a queue.
333 //
334 // See http://goo.gl/YtIjs for more details.
d87f5f1 Updated to go weekly 2012-01-27
Jonathan Siegel authored
335 func (q *Queue) SetQueueAttributes() error {
4187044 @edsrzf First commit
edsrzf authored
336 return nil
337 }
Something went wrong with that request. Please try again.