17
17
import java .util .Enumeration ;
18
18
import java .util .HashMap ;
19
19
import java .util .Map ;
20
+ import java .util .concurrent .Future ;
20
21
import java .util .concurrent .TimeUnit ;
21
22
import java .util .concurrent .atomic .AtomicBoolean ;
22
23
30
31
import javax .jms .Queue ;
31
32
import javax .jms .QueueSender ;
32
33
34
+ import com .amazonaws .handlers .AsyncHandler ;
35
+ import com .amazonaws .services .sqs .AmazonSQSAsync ;
33
36
import org .apache .commons .logging .Log ;
34
37
import org .apache .commons .logging .LogFactory ;
35
38
@@ -90,13 +93,75 @@ public class SQSMessageProducer implements MessageProducer, QueueSender {
90
93
91
94
void sendInternal (SQSQueueDestination queue , Message rawMessage ) throws JMSException {
92
95
checkClosed ();
93
- String sqsMessageBody = null ;
94
- String messageType = null ;
95
96
if (!(rawMessage instanceof SQSMessage )) {
96
97
throw new MessageFormatException (
97
- "Unrecognized message type. Messages have to be one of: SQSBytesMessage, SQSObjectMessage, or SQSTextMessage" );
98
+ "Unrecognized message type. Messages have to be one of: SQSBytesMessage, SQSObjectMessage, or SQSTextMessage" );
99
+ }
100
+ SendMessageRequest sendMessageRequest = createSendMessageRequest (queue , rawMessage );
101
+ SQSMessage message = (SQSMessage ) rawMessage ;
102
+
103
+ SendMessageResult sendMessageResult = amazonSQSClient .sendMessage (sendMessageRequest );
104
+ String messageId = sendMessageResult .getMessageId ();
105
+ LOG .info ("Message sent to SQS with SQS-assigned messageId: " + messageId );
106
+ applySendMessageResult (sendMessageResult , message );
107
+ }
108
+
109
+ private void sendInternalAsync (SQSQueueDestination queue , Message rawMessage , final CompletionListener completionListener ) throws JMSException {
110
+ checkClosed ();
111
+ if (!(amazonSQSClient .getAmazonSQSClient () instanceof AmazonSQSAsync )) {
112
+ throw new UnsupportedOperationException ("Expected instance of " + SQSMessageProducer .class .getName () + " to be backed by an instance of " +
113
+ AmazonSQSAsync .class .getName () +
114
+ " but was: " + amazonSQSClient .getAmazonSQSClient ().getClass ().getName ());
115
+ }
116
+ if (!(rawMessage instanceof SQSMessage )) {
117
+ throw new MessageFormatException (
118
+ "Unrecognized message type. Messages have to be one of: SQSBytesMessage, SQSObjectMessage, or SQSTextMessage" );
119
+ }
120
+ AmazonSQSAsync amazonSQSAsync = (AmazonSQSAsync ) amazonSQSClient .getAmazonSQSClient ();
121
+
122
+ SendMessageRequest sendMessageRequest = createSendMessageRequest (queue , rawMessage );
123
+ final SQSMessage message = (SQSMessage ) rawMessage ;
124
+
125
+ amazonSQSAsync .sendMessageAsync (sendMessageRequest , new AsyncHandler <SendMessageRequest , SendMessageResult >() {
126
+ @ Override
127
+ public void onError (Exception e ) {
128
+ if (completionListener != null ) {
129
+ completionListener .onException (message , e );
130
+ }
131
+ }
132
+
133
+ @ Override
134
+ public void onSuccess (SendMessageRequest request , SendMessageResult sendMessageResult ) {
135
+ String messageId = sendMessageResult .getMessageId ();
136
+ LOG .info ("Message sent to SQS with SQS-assigned messageId: " + messageId );
137
+ try {
138
+ applySendMessageResult (sendMessageResult , message );
139
+ } catch (JMSException e ) {
140
+ throw new RuntimeException (e );
141
+ }
142
+ if (completionListener != null ) {
143
+ completionListener .onCompletion (message );
144
+ }
145
+ }
146
+ });
147
+ }
148
+
149
+ private void applySendMessageResult (SendMessageResult sendMessageResult , SQSMessage message ) throws JMSException {
150
+ /** TODO: Do not support disableMessageID for now. */
151
+ message .setSQSMessageId (sendMessageResult .getMessageId ());
152
+
153
+ // if the message was sent to FIFO queue, the sequence number will be
154
+ // set in the response
155
+ // pass it to JMS user through provider specific JMS property
156
+ if (sendMessageResult .getSequenceNumber () != null ) {
157
+ message .setSequenceNumber (sendMessageResult .getSequenceNumber ());
98
158
}
99
-
159
+ }
160
+
161
+ private SendMessageRequest createSendMessageRequest (SQSQueueDestination queue , Message rawMessage ) throws JMSException {
162
+ String sqsMessageBody = null ;
163
+ String messageType = null ;
164
+
100
165
SQSMessage message = (SQSMessage )rawMessage ;
101
166
message .setJMSDestination (queue );
102
167
if (message instanceof SQSBytesMessage ) {
@@ -105,11 +170,11 @@ void sendInternal(SQSQueueDestination queue, Message rawMessage) throws JMSExcep
105
170
} else if (message instanceof SQSObjectMessage ) {
106
171
sqsMessageBody = ((SQSObjectMessage ) message ).getMessageBody ();
107
172
messageType = SQSMessage .OBJECT_MESSAGE_TYPE ;
108
- } else if (message instanceof SQSTextMessage ) {
173
+ } else if (message instanceof SQSTextMessage ) {
109
174
sqsMessageBody = ((SQSTextMessage ) message ).getText ();
110
175
messageType = SQSMessage .TEXT_MESSAGE_TYPE ;
111
176
}
112
-
177
+
113
178
if (sqsMessageBody == null || sqsMessageBody .isEmpty ()) {
114
179
throw new JMSException ("Message body cannot be null or empty" );
115
180
}
@@ -139,19 +204,7 @@ void sendInternal(SQSQueueDestination queue, Message rawMessage) throws JMSExcep
139
204
sendMessageRequest .setMessageGroupId (message .getSQSMessageGroupId ());
140
205
sendMessageRequest .setMessageDeduplicationId (message .getSQSMessageDeduplicationId ());
141
206
}
142
-
143
- SendMessageResult sendMessageResult = amazonSQSClient .sendMessage (sendMessageRequest );
144
- String messageId = sendMessageResult .getMessageId ();
145
- LOG .info ("Message sent to SQS with SQS-assigned messageId: " + messageId );
146
- /** TODO: Do not support disableMessageID for now. */
147
- message .setSQSMessageId (messageId );
148
-
149
- // if the message was sent to FIFO queue, the sequence number will be
150
- // set in the response
151
- // pass it to JMS user through provider specific JMS property
152
- if (sendMessageResult .getSequenceNumber () != null ) {
153
- message .setSequenceNumber (sendMessageResult .getSequenceNumber ());
154
- }
207
+ return sendMessageRequest ;
155
208
}
156
209
157
210
@ Override
@@ -187,6 +240,15 @@ public void send(Queue queue, Message message) throws JMSException {
187
240
sendInternal ((SQSQueueDestination )queue , message );
188
241
}
189
242
243
+ public void sendAsync (Queue queue , Message message , CompletionListener completionListener ) throws JMSException {
244
+ if (!(queue instanceof SQSQueueDestination )) {
245
+ throw new InvalidDestinationException (
246
+ "Incompatible implementation of Queue. Please use SQSQueueDestination implementation." );
247
+ }
248
+ checkIfDestinationAlreadySet ();
249
+ sendInternalAsync ((SQSQueueDestination )queue , message , completionListener );
250
+ }
251
+
190
252
/**
191
253
* Not verified on the client side, but SQS Attribute names must be valid
192
254
* letter or digit on the basic multilingual plane in addition to allowing
@@ -314,7 +376,12 @@ public void send(Queue queue, Message message, int deliveryMode, int priority, l
314
376
throws JMSException {
315
377
send (queue , message );
316
378
}
317
-
379
+
380
+ public void sendAsync (Queue queue , Message message , int deliveryMode , int priority , long timeToLive , CompletionListener completionListener )
381
+ throws JMSException {
382
+ sendAsync (queue , message , completionListener );
383
+ }
384
+
318
385
/**
319
386
* Gets the destination associated with this MessageProducer.
320
387
*
@@ -358,19 +425,27 @@ public void send(Message message) throws JMSException {
358
425
}
359
426
sendInternal (sqsDestination , message );
360
427
}
361
-
428
+
429
+ public void sendAsync (Message message , CompletionListener completionListener ) throws JMSException {
430
+ if (sqsDestination == null ) {
431
+ throw new UnsupportedOperationException (
432
+ "MessageProducer has to specify a destination at creation time." );
433
+ }
434
+ sendInternalAsync (sqsDestination , message , completionListener );
435
+ }
436
+
362
437
/**
363
438
* Sends a message to a destination created during the creation time of this
364
439
* message producer.
365
440
* <P>
366
441
* Send does not support deliveryMode, priority, and timeToLive. It will
367
442
* ignore anything in deliveryMode, priority, and timeToLive.
368
- *
443
+ *
369
444
* @param message
370
445
* the message to send
371
446
* @param deliveryMode
372
447
* @param priority
373
- * @param timeToLive
448
+ * @param timeToLive
374
449
* @throws MessageFormatException
375
450
* If an invalid message is specified.
376
451
* @throws UnsupportedOperationException
@@ -383,7 +458,11 @@ public void send(Message message) throws JMSException {
383
458
public void send (Message message , int deliveryMode , int priority , long timeToLive ) throws JMSException {
384
459
send (message );
385
460
}
386
-
461
+
462
+ public void sendAsync (Message message , int deliveryMode , int priority , long timeToLive , CompletionListener completionListener ) throws JMSException {
463
+ sendAsync (message , completionListener );
464
+ }
465
+
387
466
/**
388
467
* Sends a message to a queue destination.
389
468
*
@@ -414,6 +493,17 @@ public void send(Destination destination, Message message) throws JMSException {
414
493
}
415
494
}
416
495
496
+ public void sendAsync (Destination destination , Message message , CompletionListener completionListener ) throws JMSException {
497
+ if (destination == null ) {
498
+ throw new InvalidDestinationException ("Destination cannot be null" );
499
+ }
500
+ if (destination instanceof SQSQueueDestination ) {
501
+ sendAsync ((Queue ) destination , message , completionListener );
502
+ } else {
503
+ throw new InvalidDestinationException ("Incompatible implementation of Destination. Please use SQSQueueDestination implementation." );
504
+ }
505
+ }
506
+
417
507
/**
418
508
* Sends a message to a queue destination.
419
509
* <P>
@@ -443,6 +533,10 @@ public void send(Destination destination, Message message, int deliveryMode, int
443
533
send (destination , message );
444
534
}
445
535
536
+ public void sendAsync (Destination destination , Message message , int deliveryMode , int priority , long timeToLive , CompletionListener completionListener ) throws JMSException {
537
+ sendAsync (destination , message , completionListener );
538
+ }
539
+
446
540
/** This method is not supported. */
447
541
@ Override
448
542
public void setDisableMessageID (boolean value ) throws JMSException {
0 commit comments