1 /*
2  * Copyright 2012-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */

15
16 package com.amazonaws.services.sqs.buffered;
17
18 import java.util.LinkedHashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.concurrent.Future;
22
23 import com.amazonaws.AmazonClientException;
24 import com.amazonaws.AmazonServiceException;
25 import com.amazonaws.AmazonWebServiceRequest;
26 import com.amazonaws.ResponseMetadata;
27 import com.amazonaws.handlers.AsyncHandler;
28 import com.amazonaws.regions.Region;
29 import com.amazonaws.services.sqs.AmazonSQSAsync;
30 import com.amazonaws.services.sqs.model.AddPermissionRequest;
31 import com.amazonaws.services.sqs.model.AddPermissionResult;
32 import com.amazonaws.services.sqs.model.ChangeMessageVisibilityBatchRequest;
33 import com.amazonaws.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry;
34 import com.amazonaws.services.sqs.model.ChangeMessageVisibilityBatchResult;
35 import com.amazonaws.services.sqs.model.ChangeMessageVisibilityRequest;
36 import com.amazonaws.services.sqs.model.ChangeMessageVisibilityResult;
37 import com.amazonaws.services.sqs.model.CreateQueueRequest;
38 import com.amazonaws.services.sqs.model.CreateQueueResult;
39 import com.amazonaws.services.sqs.model.DeleteMessageBatchRequest;
40 import com.amazonaws.services.sqs.model.DeleteMessageBatchRequestEntry;
41 import com.amazonaws.services.sqs.model.DeleteMessageBatchResult;
42 import com.amazonaws.services.sqs.model.DeleteMessageRequest;
43 import com.amazonaws.services.sqs.model.DeleteMessageResult;
44 import com.amazonaws.services.sqs.model.DeleteQueueRequest;
45 import com.amazonaws.services.sqs.model.DeleteQueueResult;
46 import com.amazonaws.services.sqs.model.GetQueueAttributesRequest;
47 import com.amazonaws.services.sqs.model.GetQueueAttributesResult;
48 import com.amazonaws.services.sqs.model.GetQueueUrlRequest;
49 import com.amazonaws.services.sqs.model.GetQueueUrlResult;
50 import com.amazonaws.services.sqs.model.ListDeadLetterSourceQueuesRequest;
51 import com.amazonaws.services.sqs.model.ListDeadLetterSourceQueuesResult;
52 import com.amazonaws.services.sqs.model.ListQueueTagsRequest;
53 import com.amazonaws.services.sqs.model.ListQueueTagsResult;
54 import com.amazonaws.services.sqs.model.ListQueuesRequest;
55 import com.amazonaws.services.sqs.model.ListQueuesResult;
56 import com.amazonaws.services.sqs.model.PurgeQueueRequest;
57 import com.amazonaws.services.sqs.model.PurgeQueueResult;
58 import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
59 import com.amazonaws.services.sqs.model.ReceiveMessageResult;
60 import com.amazonaws.services.sqs.model.RemovePermissionRequest;
61 import com.amazonaws.services.sqs.model.RemovePermissionResult;
62 import com.amazonaws.services.sqs.model.SendMessageBatchRequest;
63 import com.amazonaws.services.sqs.model.SendMessageBatchRequestEntry;
64 import com.amazonaws.services.sqs.model.SendMessageBatchResult;
65 import com.amazonaws.services.sqs.model.SendMessageRequest;
66 import com.amazonaws.services.sqs.model.SendMessageResult;
67 import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
68 import com.amazonaws.services.sqs.model.SetQueueAttributesResult;
69 import com.amazonaws.services.sqs.model.TagQueueRequest;
70 import com.amazonaws.services.sqs.model.TagQueueResult;
71 import com.amazonaws.services.sqs.model.UntagQueueRequest;
72 import com.amazonaws.services.sqs.model.UntagQueueResult;
73 import com.amazonaws.util.VersionInfoUtils;
74
75 /**
76  * AmazonSQSBufferedAsyncClient provides client-side batching of outgoing sendMessage, deleteMessage
77  * and changeMessageVisibility calls. <br>
78  * After receiving a call, rather than executing it right away, this client waits for a configurable
79  * period of time ( default=200ms) for other calls of the same type to come in; if such calls do
80  * come in, they are also not executed immediately, but instead are added to the batch. When the
81  * batch becomes full or the timeout period expires, the entire batch is executed at once and the
82  * results are returned to the callers. This method of operation leads to reduced operating costs
83  * (since SQS charges per call and fewer calls are made) and increased overall throughput (since
84  * more work is performed per call, and all fixed costs of making a call are amortized over a
85  * greater amount of work). The cost of this method is increased latency for individual calls, since
86  * calls spend some time waiting on the client side for the potential batch-mates to appear before
87  * they are actually executed. <br>
88  * This client also performs pre-fetching of messages from SQS. After the first receiveMessage call
89  * is made, the client attempts not only to satisfy that call, but also pre-fetch extra messages to
90  * store in a temporary buffer. Future receiveMessage calls will be satisfied from the buffer, and
91  * only if the buffer is empty will the calling thread have to wait for the messages to be fetched.
92  * The size of the buffer and the maximum number of threads used for prefetching are configurable. <br>
93  * AmazonSQSBufferedAsyncClient is thread-safe.<br>
94  */

95 public class AmazonSQSBufferedAsyncClient implements AmazonSQSAsync {
96
97     public static final String USER_AGENT = AmazonSQSBufferedAsyncClient.class.getSimpleName() + "/"
98             + VersionInfoUtils.getVersion();
99
100     private final CachingMap buffers = new CachingMap(16, (float) 0.75, true);
101     private final AmazonSQSAsync realSQS;
102     private final QueueBufferConfig bufferConfigExemplar;
103
104     public AmazonSQSBufferedAsyncClient(AmazonSQSAsync paramRealSQS) {
105         this(paramRealSQS, new QueueBufferConfig());
106     }
107
108     // route all future constructors to the most general one, because validation
109     // happens here
110     public AmazonSQSBufferedAsyncClient(AmazonSQSAsync paramRealSQS, QueueBufferConfig config) {
111         config.validate();
112         realSQS = paramRealSQS;
113         bufferConfigExemplar = config;
114     }
115
116     /*
117      * (non-Javadoc)
118      * @see com.amazonaws.services.sqs.AmazonSQS#setRegion(com.amazonaws.regions.Region)
119      */

120     @Override
121     public void setRegion(Region region) throws IllegalArgumentException {
122         realSQS.setRegion(region);
123     }
124
125     public SetQueueAttributesResult setQueueAttributes(SetQueueAttributesRequest setQueueAttributesRequest) throws AmazonServiceException,
126             AmazonClientException {
127         ResultConverter.appendUserAgent(setQueueAttributesRequest, USER_AGENT);
128         return realSQS.setQueueAttributes(setQueueAttributesRequest);
129     }
130
131     public ChangeMessageVisibilityBatchResult changeMessageVisibilityBatch(ChangeMessageVisibilityBatchRequest changeMessageVisibilityBatchRequest)
132             throws AmazonServiceException, AmazonClientException {
133         ResultConverter.appendUserAgent(changeMessageVisibilityBatchRequest, USER_AGENT);
134         return realSQS.changeMessageVisibilityBatch(changeMessageVisibilityBatchRequest);
135     }
136
137     public ChangeMessageVisibilityResult changeMessageVisibility(ChangeMessageVisibilityRequest changeMessageVisibilityRequest)
138             throws AmazonServiceException, AmazonClientException {
139         ResultConverter.appendUserAgent(changeMessageVisibilityRequest, USER_AGENT);
140         QueueBuffer buffer = getQBuffer(changeMessageVisibilityRequest.getQueueUrl());
141         return buffer.changeMessageVisibilitySync(changeMessageVisibilityRequest);
142     }
143
144     public SendMessageBatchResult sendMessageBatch(SendMessageBatchRequest sendMessageBatchRequest)
145             throws AmazonServiceException, AmazonClientException {
146         ResultConverter.appendUserAgent(sendMessageBatchRequest, USER_AGENT);
147         return realSQS.sendMessageBatch(sendMessageBatchRequest);
148     }
149
150     public SendMessageResult sendMessage(SendMessageRequest sendMessageRequest) throws AmazonServiceException,
151             AmazonClientException {
152         QueueBuffer buffer = getQBuffer(sendMessageRequest.getQueueUrl());
153         ResultConverter.appendUserAgent(sendMessageRequest, USER_AGENT);
154         return buffer.sendMessageSync(sendMessageRequest);
155     }
156
157     public ReceiveMessageResult receiveMessage(ReceiveMessageRequest receiveMessageRequest)
158             throws AmazonServiceException, AmazonClientException {
159         ResultConverter.appendUserAgent(receiveMessageRequest, USER_AGENT);
160         QueueBuffer buffer = getQBuffer(receiveMessageRequest.getQueueUrl());
161         return buffer.receiveMessageSync(receiveMessageRequest);
162     }
163
164     public DeleteMessageBatchResult deleteMessageBatch(DeleteMessageBatchRequest deleteMessageBatchRequest)
165             throws AmazonServiceException, AmazonClientException {
166         ResultConverter.appendUserAgent(deleteMessageBatchRequest, USER_AGENT);
167         QueueBuffer buffer = getQBuffer(deleteMessageBatchRequest.getQueueUrl());
168         return buffer.deleteMessageBatchSync(deleteMessageBatchRequest);
169     }
170
171     public DeleteMessageResult deleteMessage(DeleteMessageRequest deleteMessageRequest) throws AmazonServiceException,
172             AmazonClientException {
173         ResultConverter.appendUserAgent(deleteMessageRequest, USER_AGENT);
174         QueueBuffer buffer = getQBuffer(deleteMessageRequest.getQueueUrl());
175         return buffer.deleteMessageSync(deleteMessageRequest);
176     }
177
178     public void shutdown() {
179         for (QueueBuffer buffer : buffers.values()) {
180             buffer.shutdown();
181         }
182         realSQS.shutdown();
183     }
184
185     /**
186      * Flushes all outstanding outbound requests. Calling this method will wait for
187      * the pending outbound tasks in the {@link QueueBuffer} to finish.
188      */

189     public void flush() {
190         for (QueueBuffer buffer : buffers.values()) {
191             buffer.flush();
192         }
193     }
194
195     public Future<ChangeMessageVisibilityBatchResult> changeMessageVisibilityBatchAsync(ChangeMessageVisibilityBatchRequest changeMessageVisibilityBatchRequest)
196             throws AmazonServiceException, AmazonClientException {
197         ResultConverter.appendUserAgent(changeMessageVisibilityBatchRequest, USER_AGENT);
198         return realSQS.changeMessageVisibilityBatchAsync(changeMessageVisibilityBatchRequest);
199     }
200
201     public Future<ChangeMessageVisibilityResult> changeMessageVisibilityAsync(ChangeMessageVisibilityRequest changeMessageVisibilityRequest)
202             throws AmazonServiceException, AmazonClientException {
203         ResultConverter.appendUserAgent(changeMessageVisibilityRequest, USER_AGENT);
204         QueueBuffer buffer = getQBuffer(changeMessageVisibilityRequest.getQueueUrl());
205         return buffer.changeMessageVisibility(changeMessageVisibilityRequest, null);
206
207     }
208
209     public Future<SendMessageBatchResult> sendMessageBatchAsync(SendMessageBatchRequest sendMessageBatchRequest)
210             throws AmazonServiceException, AmazonClientException {
211         ResultConverter.appendUserAgent(sendMessageBatchRequest, USER_AGENT);
212         return realSQS.sendMessageBatchAsync(sendMessageBatchRequest);
213     }
214
215     public Future<SendMessageResult> sendMessageAsync(SendMessageRequest sendMessageRequest)
216             throws AmazonServiceException, AmazonClientException {
217         ResultConverter.appendUserAgent(sendMessageRequest, USER_AGENT);
218         QueueBuffer buffer = getQBuffer(sendMessageRequest.getQueueUrl());
219         return buffer.sendMessage(sendMessageRequest, null);
220
221     }
222
223     public Future<ReceiveMessageResult> receiveMessageAsync(ReceiveMessageRequest receiveMessageRequest)
224             throws AmazonServiceException, AmazonClientException {
225         ResultConverter.appendUserAgent(receiveMessageRequest, USER_AGENT);
226         QueueBuffer buffer = getQBuffer(receiveMessageRequest.getQueueUrl());
227         return buffer.receiveMessage(receiveMessageRequest, null);
228     }
229
230     public Future<DeleteMessageBatchResult> deleteMessageBatchAsync(DeleteMessageBatchRequest deleteMessageBatchRequest)
231             throws AmazonServiceException, AmazonClientException {
232         ResultConverter.appendUserAgent(deleteMessageBatchRequest, USER_AGENT);
233         return realSQS.deleteMessageBatchAsync(deleteMessageBatchRequest);
234     }
235
236     public void setEndpoint(String endpoint) throws IllegalArgumentException {
237         realSQS.setEndpoint(endpoint);
238     }
239
240     public Future<SetQueueAttributesResult> setQueueAttributesAsync(SetQueueAttributesRequest setQueueAttributesRequest)
241             throws AmazonServiceException, AmazonClientException {
242         ResultConverter.appendUserAgent(setQueueAttributesRequest, USER_AGENT);
243         return realSQS.setQueueAttributesAsync(setQueueAttributesRequest);
244     }
245
246     public Future<GetQueueUrlResult> getQueueUrlAsync(GetQueueUrlRequest getQueueUrlRequest)
247             throws AmazonServiceException, AmazonClientException {
248         ResultConverter.appendUserAgent(getQueueUrlRequest, USER_AGENT);
249         return realSQS.getQueueUrlAsync(getQueueUrlRequest);
250     }
251
252     public Future<RemovePermissionResult> removePermissionAsync(RemovePermissionRequest removePermissionRequest)
253             throws AmazonServiceException, AmazonClientException {
254         ResultConverter.appendUserAgent(removePermissionRequest, USER_AGENT);
255         return realSQS.removePermissionAsync(removePermissionRequest);
256     }
257
258     public GetQueueUrlResult getQueueUrl(GetQueueUrlRequest getQueueUrlRequest) throws AmazonServiceException,
259             AmazonClientException {
260         ResultConverter.appendUserAgent(getQueueUrlRequest, USER_AGENT);
261         return realSQS.getQueueUrl(getQueueUrlRequest);
262     }
263
264     public RemovePermissionResult removePermission(RemovePermissionRequest removePermissionRequest) throws AmazonServiceException,
265             AmazonClientException {
266         ResultConverter.appendUserAgent(removePermissionRequest, USER_AGENT);
267         return realSQS.removePermission(removePermissionRequest);
268     }
269
270     public Future<GetQueueAttributesResult> getQueueAttributesAsync(GetQueueAttributesRequest getQueueAttributesRequest)
271             throws AmazonServiceException, AmazonClientException {
272         ResultConverter.appendUserAgent(getQueueAttributesRequest, USER_AGENT);
273         return realSQS.getQueueAttributesAsync(getQueueAttributesRequest);
274     }
275
276     public GetQueueAttributesResult getQueueAttributes(GetQueueAttributesRequest getQueueAttributesRequest)
277             throws AmazonServiceException, AmazonClientException {
278         ResultConverter.appendUserAgent(getQueueAttributesRequest, USER_AGENT);
279         return realSQS.getQueueAttributes(getQueueAttributesRequest);
280     }
281
282     public Future<PurgeQueueResult> purgeQueueAsync(PurgeQueueRequest purgeQueueRequest) throws AmazonServiceException,
283             AmazonClientException {
284         ResultConverter.appendUserAgent(purgeQueueRequest, USER_AGENT);
285         return realSQS.purgeQueueAsync(purgeQueueRequest);
286     }
287
288     public PurgeQueueResult purgeQueue(PurgeQueueRequest purgeQueueRequest) throws AmazonServiceException, AmazonClientException {
289         ResultConverter.appendUserAgent(purgeQueueRequest, USER_AGENT);
290         return realSQS.purgeQueue(purgeQueueRequest);
291     }
292
293     public Future<DeleteQueueResult> deleteQueueAsync(DeleteQueueRequest deleteQueueRequest) throws AmazonServiceException,
294             AmazonClientException {
295         ResultConverter.appendUserAgent(deleteQueueRequest, USER_AGENT);
296         return realSQS.deleteQueueAsync(deleteQueueRequest);
297     }
298
299     public DeleteQueueResult deleteQueue(DeleteQueueRequest deleteQueueRequest) throws AmazonServiceException, AmazonClientException {
300         ResultConverter.appendUserAgent(deleteQueueRequest, USER_AGENT);
301         return realSQS.deleteQueue(deleteQueueRequest);
302     }
303
304     public Future<ListQueuesResult> listQueuesAsync(ListQueuesRequest listQueuesRequest) throws AmazonServiceException,
305             AmazonClientException {
306         ResultConverter.appendUserAgent(listQueuesRequest, USER_AGENT);
307         return realSQS.listQueuesAsync(listQueuesRequest);
308     }
309
310     public ListQueuesResult listQueues(ListQueuesRequest listQueuesRequest) throws AmazonServiceException,
311             AmazonClientException {
312         ResultConverter.appendUserAgent(listQueuesRequest, USER_AGENT);
313         return realSQS.listQueues(listQueuesRequest);
314     }
315
316     public Future<CreateQueueResult> createQueueAsync(CreateQueueRequest createQueueRequest)
317             throws AmazonServiceException, AmazonClientException {
318         ResultConverter.appendUserAgent(createQueueRequest, USER_AGENT);
319         return realSQS.createQueueAsync(createQueueRequest);
320     }
321
322     public CreateQueueResult createQueue(CreateQueueRequest createQueueRequest) throws AmazonServiceException,
323             AmazonClientException {
324         ResultConverter.appendUserAgent(createQueueRequest, USER_AGENT);
325         return realSQS.createQueue(createQueueRequest);
326     }
327
328     public Future<AddPermissionResult> addPermissionAsync(AddPermissionRequest addPermissionRequest) throws AmazonServiceException,
329             AmazonClientException {
330         ResultConverter.appendUserAgent(addPermissionRequest, USER_AGENT);
331         return realSQS.addPermissionAsync(addPermissionRequest);
332     }
333
334     @Override
335     public Future<AddPermissionResult> addPermissionAsync(String queueUrl, String label,
336             List<String> aWSAccountIds, List<String> actions) {
337         return addPermissionAsync(new AddPermissionRequest(queueUrl, label,
338                 aWSAccountIds, actions));
339     }
340
341     @Override
342     public Future<AddPermissionResult> addPermissionAsync(String queueUrl, String label,
343             List<String> aWSAccountIds, List<String> actions,
344             AsyncHandler<AddPermissionRequest, AddPermissionResult> asyncHandler) {
345         return addPermissionAsync(new AddPermissionRequest(queueUrl, label,
346                 aWSAccountIds, actions), asyncHandler);
347     }
348
349
350     public AddPermissionResult addPermission(AddPermissionRequest addPermissionRequest) throws AmazonServiceException,
351             AmazonClientException {
352         ResultConverter.appendUserAgent(addPermissionRequest, USER_AGENT);
353         return realSQS.addPermission(addPermissionRequest);
354     }
355
356     public ListQueuesResult listQueues() throws AmazonServiceException, AmazonClientException {
357         return realSQS.listQueues();
358     }
359
360     public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) {
361         ResultConverter.appendUserAgent(request, USER_AGENT);
362         return realSQS.getCachedResponseMetadata(request);
363     }
364
365     public Future<DeleteMessageResult> deleteMessageAsync(DeleteMessageRequest deleteMessageRequest) throws AmazonServiceException,
366             AmazonClientException {
367         ResultConverter.appendUserAgent(deleteMessageRequest, USER_AGENT);
368         QueueBuffer buffer = getQBuffer(deleteMessageRequest.getQueueUrl());
369         return buffer.deleteMessage(deleteMessageRequest, null);
370     }
371
372     /**
373      * Returns (creating it if necessary) a queue buffer for a particular queue Since we are only
374      * storing a limited number of queue buffers, it is possible that as a result of calling this
375      * method the least recently used queue buffer will be removed from our queue buffer cache
376      *
377      * @return a queue buffer associated with the provided queue URL. Never null
378      */

379     private synchronized QueueBuffer getQBuffer(String qUrl) {
380         QueueBuffer toReturn = buffers.get(qUrl);
381         if (null == toReturn) {
382             QueueBufferConfig config = new QueueBufferConfig(bufferConfigExemplar);
383             toReturn = new QueueBuffer(config, qUrl, realSQS);
384             buffers.put(qUrl, toReturn);
385         }
386         return toReturn;
387     }
388
389     class CachingMap extends LinkedHashMap<String, QueueBuffer> {
390         private static final long serialVersionUID = 1;
391         private static final int MAX_ENTRIES = 100;
392
393         public CachingMap(int initial, float loadFactor, boolean accessOrder) {
394             super(initial, loadFactor, accessOrder);
395         }
396
397         protected boolean removeEldestEntry(java.util.Map.Entry<String, QueueBuffer> eldest) {
398             return size() > MAX_ENTRIES;
399         }
400
401     }
402
403     public Future<ChangeMessageVisibilityResult> changeMessageVisibilityAsync(ChangeMessageVisibilityRequest changeMessageVisibilityRequest,
404                                                      AsyncHandler<ChangeMessageVisibilityRequest, ChangeMessageVisibilityResult> asyncHandler)
405             throws AmazonServiceException, AmazonClientException {
406         ResultConverter.appendUserAgent(changeMessageVisibilityRequest, USER_AGENT);
407         QueueBuffer buffer = getQBuffer(changeMessageVisibilityRequest.getQueueUrl());
408         return buffer.changeMessageVisibility(changeMessageVisibilityRequest, asyncHandler);
409     }
410
411     @Override
412     public Future<ChangeMessageVisibilityResult> changeMessageVisibilityAsync(String queueUrl,
413             String receiptHandle, Integer visibilityTimeout) {
414         return changeMessageVisibilityAsync(new ChangeMessageVisibilityRequest(
415                 queueUrl, receiptHandle, visibilityTimeout));
416     }
417
418     @Override
419     public Future<ChangeMessageVisibilityResult> changeMessageVisibilityAsync(String queueUrl,
420             String receiptHandle, Integer visibilityTimeout,
421             AsyncHandler<ChangeMessageVisibilityRequest, ChangeMessageVisibilityResult> asyncHandler) {
422         return changeMessageVisibilityAsync(new ChangeMessageVisibilityRequest(
423                 queueUrl, receiptHandle, visibilityTimeout), asyncHandler);
424     }
425
426     public Future<SendMessageResult> sendMessageAsync(SendMessageRequest sendMessageRequest,
427                                                       AsyncHandler<SendMessageRequest, SendMessageResult> asyncHandler)
428             throws AmazonServiceException, AmazonClientException {
429         ResultConverter.appendUserAgent(sendMessageRequest, USER_AGENT);
430         QueueBuffer buffer = getQBuffer(sendMessageRequest.getQueueUrl());
431         return buffer.sendMessage(sendMessageRequest, asyncHandler);
432     }
433
434     @Override
435     public Future<SendMessageResult> sendMessageAsync(String queueUrl,
436             String messageBody) {
437         return sendMessageAsync(new SendMessageRequest(queueUrl, messageBody));
438     }
439
440     @Override
441     public Future<SendMessageResult> sendMessageAsync(String queueUrl,
442             String messageBody,
443             AsyncHandler<SendMessageRequest, SendMessageResult> asyncHandler) {
444         return sendMessageAsync(new SendMessageRequest(queueUrl, messageBody),
445                 asyncHandler);
446     }
447
448     public Future<ReceiveMessageResult> receiveMessageAsync(ReceiveMessageRequest receiveMessageRequest,
449                                                             AsyncHandler<ReceiveMessageRequest, ReceiveMessageResult> asyncHandler)
450             throws AmazonServiceException, AmazonClientException {
451         ResultConverter.appendUserAgent(receiveMessageRequest, USER_AGENT);
452         QueueBuffer buffer = getQBuffer(receiveMessageRequest.getQueueUrl());
453         return buffer.receiveMessage(receiveMessageRequest, asyncHandler);
454     }
455
456     @Override
457     public Future<ReceiveMessageResult> receiveMessageAsync(String queueUrl) {
458         return receiveMessageAsync(new ReceiveMessageRequest(queueUrl));
459     }
460
461     @Override
462     public Future<ReceiveMessageResult> receiveMessageAsync(
463             String queueUrl,
464             AsyncHandler<ReceiveMessageRequest, ReceiveMessageResult> asyncHandler) {
465         return receiveMessageAsync(new ReceiveMessageRequest(queueUrl), asyncHandler);
466     }
467
468     public Future<DeleteMessageResult> deleteMessageAsync(DeleteMessageRequest deleteMessageRequest,
469                                            AsyncHandler<DeleteMessageRequest, DeleteMessageResult> asyncHandler)
470             throws AmazonServiceException, AmazonClientException {
471         ResultConverter.appendUserAgent(deleteMessageRequest, USER_AGENT);
472         QueueBuffer buffer = getQBuffer(deleteMessageRequest.getQueueUrl());
473         return buffer.deleteMessage(deleteMessageRequest, asyncHandler);
474     }
475
476     @Override
477     public Future<DeleteMessageResult> deleteMessageAsync(String queueUrl, String receiptHandle) {
478         return deleteMessageAsync(new DeleteMessageRequest(queueUrl,
479                 receiptHandle));
480     }
481
482     @Override
483     public Future<DeleteMessageResult> deleteMessageAsync(String queueUrl,
484             String receiptHandle,
485             AsyncHandler<DeleteMessageRequest, DeleteMessageResult> asyncHandler) {
486         return deleteMessageAsync(new DeleteMessageRequest(queueUrl,
487                 receiptHandle), asyncHandler);
488     }
489
490     public Future<SetQueueAttributesResult> setQueueAttributesAsync(SetQueueAttributesRequest setQueueAttributesRequest,
491                                                 AsyncHandler<SetQueueAttributesRequest, SetQueueAttributesResult> asyncHandler)
492             throws AmazonServiceException, AmazonClientException {
493         return realSQS.setQueueAttributesAsync(setQueueAttributesRequest, asyncHandler);
494     }
495
496     public Future<SetQueueAttributesResult> setQueueAttributesAsync(String queueUrl,
497             java.util.Map<String, String> attributes)
498             throws AmazonServiceException, AmazonClientException {
499         return realSQS.setQueueAttributesAsync(queueUrl, attributes);
500     }
501
502     public Future<SetQueueAttributesResult> setQueueAttributesAsync(String queueUrl,
503             java.util.Map<String, String> attributes,
504             com.amazonaws.handlers.AsyncHandler<SetQueueAttributesRequest, SetQueueAttributesResult> asyncHandler)
505             throws AmazonServiceException, AmazonClientException {
506         return realSQS.setQueueAttributesAsync(queueUrl, attributes, asyncHandler);
507     }
508
509     public Future<ChangeMessageVisibilityBatchResult> changeMessageVisibilityBatchAsync(ChangeMessageVisibilityBatchRequest changeMessageVisibilityBatchRequest,
510                                                                                         AsyncHandler<ChangeMessageVisibilityBatchRequest, ChangeMessageVisibilityBatchResult> asyncHandler)
511             throws AmazonServiceException, AmazonClientException {
512         return realSQS.changeMessageVisibilityBatchAsync(changeMessageVisibilityBatchRequest, asyncHandler);
513     }
514
515     @Override
516     public Future<ChangeMessageVisibilityBatchResult> changeMessageVisibilityBatchAsync(
517             String queueUrl,
518             List<ChangeMessageVisibilityBatchRequestEntry> entries) {
519         return changeMessageVisibilityBatchAsync(new ChangeMessageVisibilityBatchRequest(
520                 queueUrl, entries));
521     }
522
523     @Override
524     public Future<ChangeMessageVisibilityBatchResult> changeMessageVisibilityBatchAsync(
525             String queueUrl,
526             List<ChangeMessageVisibilityBatchRequestEntry> entries,
527             AsyncHandler<ChangeMessageVisibilityBatchRequest, ChangeMessageVisibilityBatchResult> asyncHandler) {
528         return changeMessageVisibilityBatchAsync(new ChangeMessageVisibilityBatchRequest(
529                 queueUrl, entries), asyncHandler);
530     }
531
532     public Future<GetQueueUrlResult> getQueueUrlAsync(GetQueueUrlRequest getQueueUrlRequest,
533                                                       AsyncHandler<GetQueueUrlRequest, GetQueueUrlResult> asyncHandler)
534             throws AmazonServiceException, AmazonClientException {
535         return realSQS.getQueueUrlAsync(getQueueUrlRequest, asyncHandler);
536     }
537
538     @Override
539     public Future<GetQueueUrlResult> getQueueUrlAsync(String queueName) {
540         return getQueueUrlAsync(new GetQueueUrlRequest(queueName));
541     }
542
543     @Override
544     public Future<GetQueueUrlResult> getQueueUrlAsync(String queueName,
545             AsyncHandler<GetQueueUrlRequest, GetQueueUrlResult> asyncHandler) {
546         return getQueueUrlAsync(new GetQueueUrlRequest(queueName), asyncHandler);
547     }
548
549     public Future<RemovePermissionResult> removePermissionAsync(RemovePermissionRequest removePermissionRequest,
550                                               AsyncHandler<RemovePermissionRequest, RemovePermissionResult> asyncHandler)
551             throws AmazonServiceException, AmazonClientException {
552         return realSQS.removePermissionAsync(removePermissionRequest, asyncHandler);
553     }
554
555     @Override
556     public Future<RemovePermissionResult> removePermissionAsync(String queueUrl, String label) {
557         return removePermissionAsync(new RemovePermissionRequest(queueUrl,
558                 label));
559     }
560
561     @Override
562     public Future<RemovePermissionResult> removePermissionAsync(String queueUrl, String label,
563             AsyncHandler<RemovePermissionRequest, RemovePermissionResult> asyncHandler) {
564         return removePermissionAsync(new RemovePermissionRequest(queueUrl,
565                 label), asyncHandler);
566     }
567
568     public Future<GetQueueAttributesResult> getQueueAttributesAsync(GetQueueAttributesRequest getQueueAttributesRequest,
569                                                                     AsyncHandler<GetQueueAttributesRequest, GetQueueAttributesResult> asyncHandler)
570             throws AmazonServiceException, AmazonClientException {
571         return realSQS.getQueueAttributesAsync(getQueueAttributesRequest, asyncHandler);
572     }
573
574     @Override
575     public Future<GetQueueAttributesResult> getQueueAttributesAsync(
576             String queueUrl, List<String> attributeNames) {
577         return getQueueAttributesAsync(new GetQueueAttributesRequest(queueUrl,
578                 attributeNames));
579     }
580
581     @Override
582     public Future<GetQueueAttributesResult> getQueueAttributesAsync(
583             String queueUrl,
584             List<String> attributeNames,
585             AsyncHandler<GetQueueAttributesRequest, GetQueueAttributesResult> asyncHandler) {
586         return getQueueAttributesAsync(new GetQueueAttributesRequest(queueUrl,
587                 attributeNames), asyncHandler);
588     }
589
590     public Future<SendMessageBatchResult> sendMessageBatchAsync(SendMessageBatchRequest sendMessageBatchRequest,
591                                                                 AsyncHandler<SendMessageBatchRequest, SendMessageBatchResult> asyncHandler)
592             throws AmazonServiceException, AmazonClientException {
593         return realSQS.sendMessageBatchAsync(sendMessageBatchRequest, asyncHandler);
594     }
595
596     @Override
597     public Future<SendMessageBatchResult> sendMessageBatchAsync(
598             String queueUrl, List<SendMessageBatchRequestEntry> entries) {
599         return sendMessageBatchAsync(new SendMessageBatchRequest(queueUrl,
600                 entries));
601     }
602
603     @Override
604     public Future<SendMessageBatchResult> sendMessageBatchAsync(
605             String queueUrl,
606             List<SendMessageBatchRequestEntry> entries,
607             AsyncHandler<SendMessageBatchRequest, SendMessageBatchResult> asyncHandler) {
608         return sendMessageBatchAsync(new SendMessageBatchRequest(queueUrl,
609                 entries), asyncHandler);
610     }
611
612     public Future<PurgeQueueResult> purgeQueueAsync(PurgeQueueRequest purgeQueueRequest,
613                                         AsyncHandler<PurgeQueueRequest, PurgeQueueResult> asyncHandler)
614             throws AmazonServiceException, AmazonClientException {
615         return realSQS.purgeQueueAsync(purgeQueueRequest, asyncHandler);
616     }
617
618     public Future<DeleteQueueResult> deleteQueueAsync(DeleteQueueRequest deleteQueueRequest,
619                                          AsyncHandler<DeleteQueueRequest, DeleteQueueResult> asyncHandler)
620             throws AmazonServiceException, AmazonClientException {
621         return realSQS.deleteQueueAsync(deleteQueueRequest, asyncHandler);
622     }
623
624     @Override
625     public Future<DeleteQueueResult> deleteQueueAsync(String queueUrl) {
626         return deleteQueueAsync(new DeleteQueueRequest(queueUrl));
627     }
628
629     @Override
630     public Future<DeleteQueueResult> deleteQueueAsync(String queueUrl,
631             AsyncHandler<DeleteQueueRequest, DeleteQueueResult> asyncHandler) {
632         return deleteQueueAsync(new DeleteQueueRequest(queueUrl), asyncHandler);
633     }
634
635     public Future<ListQueuesResult> listQueuesAsync(ListQueuesRequest listQueuesRequest,
636                                                     AsyncHandler<ListQueuesRequest, ListQueuesResult> asyncHandler)
637             throws AmazonServiceException, AmazonClientException {
638         return realSQS.listQueuesAsync(listQueuesRequest, asyncHandler);
639     }
640
641     @Override
642     public Future<ListQueuesResult> listQueuesAsync() {
643         return listQueuesAsync(new ListQueuesRequest());
644     }
645
646     @Override
647     public Future<ListQueuesResult> listQueuesAsync(
648             AsyncHandler<ListQueuesRequest, ListQueuesResult> asyncHandler) {
649         return listQueuesAsync(new ListQueuesRequest(), asyncHandler);
650     }
651
652     @Override
653     public Future<ListQueuesResult> listQueuesAsync(String queueNamePrefix) {
654         return listQueuesAsync(new ListQueuesRequest(queueNamePrefix));
655     }
656
657     @Override
658     public Future<ListQueuesResult> listQueuesAsync(String queueNamePrefix,
659             AsyncHandler<ListQueuesRequest, ListQueuesResult> asyncHandler) {
660         return listQueuesAsync(new ListQueuesRequest(queueNamePrefix),
661                 asyncHandler);
662     }
663
664     public Future<DeleteMessageBatchResult> deleteMessageBatchAsync(DeleteMessageBatchRequest deleteMessageBatchRequest,
665                                                                     AsyncHandler<DeleteMessageBatchRequest, DeleteMessageBatchResult> asyncHandler)
666             throws AmazonServiceException, AmazonClientException {
667         return realSQS.deleteMessageBatchAsync(deleteMessageBatchRequest, asyncHandler);
668     }
669
670     @Override
671     public Future<DeleteMessageBatchResult> deleteMessageBatchAsync(
672             String queueUrl, List<DeleteMessageBatchRequestEntry> entries) {
673         return deleteMessageBatchAsync(new DeleteMessageBatchRequest(queueUrl,
674                 entries));
675     }
676
677     @Override
678     public Future<DeleteMessageBatchResult> deleteMessageBatchAsync(
679             String queueUrl,
680             List<DeleteMessageBatchRequestEntry> entries,
681             AsyncHandler<DeleteMessageBatchRequest, DeleteMessageBatchResult> asyncHandler) {
682         return deleteMessageBatchAsync(new DeleteMessageBatchRequest(queueUrl,
683                 entries), asyncHandler);
684     }
685
686     public Future<CreateQueueResult> createQueueAsync(CreateQueueRequest createQueueRequest,
687                                                       AsyncHandler<CreateQueueRequest, CreateQueueResult> asyncHandler)
688             throws AmazonServiceException, AmazonClientException {
689         return realSQS.createQueueAsync(createQueueRequest, asyncHandler);
690     }
691
692     @Override
693     public Future<CreateQueueResult> createQueueAsync(String queueName) {
694         return createQueueAsync(new CreateQueueRequest(queueName));
695     }
696
697     @Override
698     public Future<CreateQueueResult> createQueueAsync(String queueName,
699             AsyncHandler<CreateQueueRequest, CreateQueueResult> asyncHandler) {
700         return createQueueAsync(new CreateQueueRequest(queueName), asyncHandler);
701     }
702
703     public Future<AddPermissionResult> addPermissionAsync(AddPermissionRequest addPermissionRequest,
704                                            AsyncHandler<AddPermissionRequest, AddPermissionResult> asyncHandler)
705             throws AmazonServiceException, AmazonClientException {
706         return realSQS.addPermissionAsync(addPermissionRequest, asyncHandler);
707     }
708
709     @Override
710     public ListDeadLetterSourceQueuesResult listDeadLetterSourceQueues(ListDeadLetterSourceQueuesRequest listDeadLetterSourceQueuesRequest)
711             throws AmazonServiceException, AmazonClientException {
712         ResultConverter.appendUserAgent(listDeadLetterSourceQueuesRequest, USER_AGENT);
713         return realSQS.listDeadLetterSourceQueues(listDeadLetterSourceQueuesRequest);
714     }
715
716     @Override
717     public Future<ListDeadLetterSourceQueuesResult> listDeadLetterSourceQueuesAsync(ListDeadLetterSourceQueuesRequest listDeadLetterSourceQueuesRequest)
718             throws AmazonServiceException, AmazonClientException {
719         ResultConverter.appendUserAgent(listDeadLetterSourceQueuesRequest, USER_AGENT);
720         return realSQS.listDeadLetterSourceQueuesAsync(listDeadLetterSourceQueuesRequest);
721     }
722
723     @Override
724     public Future<ListDeadLetterSourceQueuesResult> listDeadLetterSourceQueuesAsync(ListDeadLetterSourceQueuesRequest listDeadLetterSourceQueuesRequest,
725                                                                                     AsyncHandler<ListDeadLetterSourceQueuesRequest, ListDeadLetterSourceQueuesResult> asyncHandler)
726             throws AmazonServiceException, AmazonClientException {
727         return realSQS.listDeadLetterSourceQueuesAsync(listDeadLetterSourceQueuesRequest, asyncHandler);
728     }
729
730     @Override
731     public SetQueueAttributesResult setQueueAttributes(String queueUrl, Map<String, String> attributes) throws AmazonServiceException,
732             AmazonClientException {
733         return setQueueAttributes(new SetQueueAttributesRequest(queueUrl, attributes));
734     }
735
736     @Override
737     public ChangeMessageVisibilityBatchResult changeMessageVisibilityBatch(String queueUrl,
738                                                                            List<ChangeMessageVisibilityBatchRequestEntry> entries)
739             throws AmazonServiceException, AmazonClientException {
740         return changeMessageVisibilityBatch(new ChangeMessageVisibilityBatchRequest(queueUrl, entries));
741     }
742
743     @Override
744     public ChangeMessageVisibilityResult changeMessageVisibility(String queueUrl, String receiptHandle, Integer visibilityTimeout)
745             throws AmazonServiceException, AmazonClientException {
746         return changeMessageVisibility(new ChangeMessageVisibilityRequest(queueUrl, receiptHandle, visibilityTimeout));
747     }
748
749     @Override
750     public GetQueueUrlResult getQueueUrl(String queueName) throws AmazonServiceException, AmazonClientException {
751         return getQueueUrl(new GetQueueUrlRequest(queueName));
752     }
753
754     @Override
755     public RemovePermissionResult removePermission(String queueUrl, String label) throws AmazonServiceException, AmazonClientException {
756         return removePermission(new RemovePermissionRequest(queueUrl, label));
757     }
758
759     @Override
760     public SendMessageBatchResult sendMessageBatch(String queueUrl, List<SendMessageBatchRequestEntry> entries)
761             throws AmazonServiceException, AmazonClientException {
762         return sendMessageBatch(new SendMessageBatchRequest(queueUrl, entries));
763     }
764
765     @Override
766     public DeleteQueueResult deleteQueue(String queueUrl) throws AmazonServiceException, AmazonClientException {
767         return deleteQueue(new DeleteQueueRequest(queueUrl));
768     }
769
770     @Override
771     public SendMessageResult sendMessage(String queueUrl, String messageBody) throws AmazonServiceException,
772             AmazonClientException {
773         return sendMessage(new SendMessageRequest(queueUrl, messageBody));
774     }
775
776     @Override
777     public ReceiveMessageResult receiveMessage(String queueUrl) throws AmazonServiceException, AmazonClientException {
778         return receiveMessage(new ReceiveMessageRequest(queueUrl));
779     }
780
781     @Override
782     public ListQueuesResult listQueues(String queueNamePrefix) throws AmazonServiceException, AmazonClientException {
783         return listQueues(new ListQueuesRequest(queueNamePrefix));
784     }
785
786     @Override
787     public DeleteMessageBatchResult deleteMessageBatch(String queueUrl, List<DeleteMessageBatchRequestEntry> entries)
788             throws AmazonServiceException, AmazonClientException {
789         return deleteMessageBatch(new DeleteMessageBatchRequest(queueUrl, entries));
790     }
791
792     @Override
793     public CreateQueueResult createQueue(String queueName) throws AmazonServiceException, AmazonClientException {
794         return createQueue(new CreateQueueRequest(queueName));
795     }
796
797     @Override
798     public AddPermissionResult addPermission(String queueUrl, String label, List<String> aWSAccountIds, List<String> actions)
799             throws AmazonServiceException, AmazonClientException {
800         return addPermission(new AddPermissionRequest(queueUrl, label, aWSAccountIds, actions));
801     }
802
803     @Override
804     public DeleteMessageResult deleteMessage(String queueUrl, String receiptHandle) throws AmazonServiceException,
805             AmazonClientException {
806         return deleteMessage(new DeleteMessageRequest(queueUrl, receiptHandle));
807     }
808
809     @Override
810     public GetQueueAttributesResult getQueueAttributes(String queueUrl, List<String> attributeNames) {
811         return getQueueAttributes(new GetQueueAttributesRequest(queueUrl, attributeNames));
812     }
813
814     public TagQueueResult tagQueue(TagQueueRequest tagQueueRequest) {
815         ResultConverter.appendUserAgent(tagQueueRequest, USER_AGENT);
816         return realSQS.tagQueue(tagQueueRequest);
817     }
818
819     public TagQueueResult tagQueue(String queueUrl, Map<String, String> tags) {
820         return tagQueue(new TagQueueRequest(queueUrl, tags));
821     }
822
823     @Override
824     public Future<TagQueueResult> tagQueueAsync(TagQueueRequest tagQueueRequest) {
825         ResultConverter.appendUserAgent(tagQueueRequest, USER_AGENT);
826         return realSQS.tagQueueAsync(tagQueueRequest);
827     }
828
829     @Override
830     public Future<TagQueueResult> tagQueueAsync(TagQueueRequest tagQueueRequest, AsyncHandler<TagQueueRequest, TagQueueResult> asyncHandler) {
831         ResultConverter.appendUserAgent(tagQueueRequest, USER_AGENT);
832         return realSQS.tagQueueAsync(tagQueueRequest, asyncHandler);
833     }
834
835     @Override
836     public Future<TagQueueResult> tagQueueAsync(String queueUrl, Map<String, String> tags) {
837         return tagQueueAsync(new TagQueueRequest(queueUrl, tags));
838     }
839
840     @Override
841     public Future<TagQueueResult> tagQueueAsync(String queueUrl, Map<String, String> tags, AsyncHandler<TagQueueRequest, TagQueueResult> asyncHandler) {
842         return tagQueueAsync(new TagQueueRequest(queueUrl, tags), asyncHandler);
843     }
844
845     public UntagQueueResult untagQueue(UntagQueueRequest untagQueueRequest) {
846         ResultConverter.appendUserAgent(untagQueueRequest, USER_AGENT);
847         return realSQS.untagQueue(untagQueueRequest);
848     }
849
850     public UntagQueueResult untagQueue(String queueUrl, List<String> tagKeys) {
851         return untagQueue(new UntagQueueRequest(queueUrl, tagKeys));
852     }
853
854     @Override
855     public Future<UntagQueueResult> untagQueueAsync(UntagQueueRequest untagQueueRequest) {
856         ResultConverter.appendUserAgent(untagQueueRequest, USER_AGENT);
857         return realSQS.untagQueueAsync(untagQueueRequest);
858     }
859
860     @Override
861     public Future<UntagQueueResult> untagQueueAsync(UntagQueueRequest untagQueueRequest, AsyncHandler<UntagQueueRequest, UntagQueueResult> asyncHandler) {
862         ResultConverter.appendUserAgent(untagQueueRequest, USER_AGENT);
863         return realSQS.untagQueueAsync(untagQueueRequest, asyncHandler);
864     }
865
866     @Override
867     public Future<UntagQueueResult> untagQueueAsync(String queueUrl, List<String> tagKeys) {
868         return untagQueueAsync(new UntagQueueRequest(queueUrl, tagKeys));
869     }
870
871     @Override
872     public Future<UntagQueueResult> untagQueueAsync(String queueUrl, List<String> tagKeys, AsyncHandler<UntagQueueRequest, UntagQueueResult> asyncHandler) {
873         return untagQueueAsync(new UntagQueueRequest(queueUrl, tagKeys), asyncHandler);
874     }
875
876     public ListQueueTagsResult listQueueTags(ListQueueTagsRequest listQueueTagsRequest) {
877         ResultConverter.appendUserAgent(listQueueTagsRequest, USER_AGENT);
878         return realSQS.listQueueTags(listQueueTagsRequest);
879     }
880
881     public ListQueueTagsResult listQueueTags(String queueUrl) {
882         return listQueueTags(new ListQueueTagsRequest(queueUrl));
883     }
884
885     @Override
886     public Future<ListQueueTagsResult> listQueueTagsAsync(ListQueueTagsRequest listQueueTagsRequest) {
887         ResultConverter.appendUserAgent(listQueueTagsRequest, USER_AGENT);
888         return realSQS.listQueueTagsAsync(listQueueTagsRequest);
889     }
890
891     @Override
892     public Future<ListQueueTagsResult> listQueueTagsAsync(ListQueueTagsRequest listQueueTagsRequest, AsyncHandler<ListQueueTagsRequest, ListQueueTagsResult> asyncHandler) {
893         return realSQS.listQueueTagsAsync(listQueueTagsRequest, asyncHandler);
894     }
895
896     @Override
897     public Future<ListQueueTagsResult> listQueueTagsAsync(String queueUrl) {
898         return listQueueTagsAsync(new ListQueueTagsRequest(queueUrl));
899     }
900
901     @Override
902     public Future<ListQueueTagsResult> listQueueTagsAsync(String queueUrl, AsyncHandler<ListQueueTagsRequest, ListQueueTagsResult> asyncHandler) {
903         return listQueueTagsAsync(new ListQueueTagsRequest(queueUrl), asyncHandler);
904     }
905 }
906