1
1
/*
2
- * Copyright 2002-2017 the original author or authors.
2
+ * Copyright 2002-2018 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
135
135
* @author Gary Russell
136
136
* @author Artem Bilan
137
137
* @author Ernest Sadykov
138
+ * @author Mark Norkin
138
139
* @since 1.0
139
140
*/
140
141
public class RabbitTemplate extends RabbitAccessor implements BeanFactoryAware , RabbitOperations , MessageListener ,
@@ -341,7 +342,7 @@ public String getEncoding() {
341
342
* exchange and routing key.
342
343
* @param replyAddress the replyAddress to set
343
344
*/
344
- public void setReplyAddress (String replyAddress ) {
345
+ public synchronized void setReplyAddress (String replyAddress ) {
345
346
this .replyAddress = replyAddress ;
346
347
this .evaluatedFastReplyTo = false ;
347
348
}
@@ -726,13 +727,11 @@ public Collection<String> expectedQueueNames() {
726
727
*/
727
728
public Collection <CorrelationData > getUnconfirmed (long age ) {
728
729
Set <CorrelationData > unconfirmed = new HashSet <>();
729
- synchronized (this .publisherConfirmChannels ) {
730
- long cutoffTime = System .currentTimeMillis () - age ;
731
- for (Channel channel : this .publisherConfirmChannels .keySet ()) {
732
- Collection <PendingConfirm > confirms = ((PublisherCallbackChannel ) channel ).expire (this , cutoffTime );
733
- for (PendingConfirm confirm : confirms ) {
734
- unconfirmed .add (confirm .getCorrelationData ());
735
- }
730
+ long cutoffTime = System .currentTimeMillis () - age ;
731
+ for (Channel channel : this .publisherConfirmChannels .keySet ()) {
732
+ Collection <PendingConfirm > confirms = ((PublisherCallbackChannel ) channel ).expire (this , cutoffTime );
733
+ for (PendingConfirm confirm : confirms ) {
734
+ unconfirmed .add (confirm .getCorrelationData ());
736
735
}
737
736
}
738
737
return unconfirmed .size () > 0 ? unconfirmed : null ;
@@ -744,12 +743,10 @@ public Collection<CorrelationData> getUnconfirmed(long age) {
744
743
* @since 2.0
745
744
*/
746
745
public int getUnconfirmedCount () {
747
- synchronized (this .publisherConfirmChannels ) {
748
- return this .publisherConfirmChannels .keySet ()
749
- .stream ()
750
- .mapToInt (channel -> ((PublisherCallbackChannel ) channel ).getPendingConfirmsCount (this ))
751
- .sum ();
752
- }
746
+ return this .publisherConfirmChannels .keySet ()
747
+ .stream ()
748
+ .mapToInt (channel -> ((PublisherCallbackChannel ) channel ).getPendingConfirmsCount (this ))
749
+ .sum ();
753
750
}
754
751
755
752
@ Override
@@ -788,11 +785,9 @@ protected void doStop() {
788
785
@ Override
789
786
public boolean isRunning () {
790
787
synchronized (this .directReplyToContainers ) {
791
- synchronized (this .directReplyToContainers ) {
792
- return this .directReplyToContainers .values ()
793
- .stream ()
794
- .anyMatch (AbstractMessageListenerContainer ::isRunning );
795
- }
788
+ return this .directReplyToContainers .values ()
789
+ .stream ()
790
+ .anyMatch (AbstractMessageListenerContainer ::isRunning );
796
791
}
797
792
}
798
793
@@ -1138,19 +1133,18 @@ public <R, S> boolean receiveAndReply(String queueName, ReceiveAndReplyCallback<
1138
1133
private <R , S > boolean doReceiveAndReply (final String queueName , final ReceiveAndReplyCallback <R , S > callback ,
1139
1134
final ReplyToAddressCallback <S > replyToAddressCallback ) throws AmqpException {
1140
1135
return execute (channel -> {
1141
- Message receiveMessage = null ;
1142
-
1143
- receiveMessage = receiveForReply (queueName , channel , receiveMessage );
1136
+ Message receiveMessage = receiveForReply (queueName , channel );
1144
1137
if (receiveMessage != null ) {
1145
1138
return sendReply (callback , replyToAddressCallback , channel , receiveMessage );
1146
1139
}
1147
1140
return false ;
1148
1141
}, obtainTargetConnectionFactory (this .receiveConnectionFactorySelectorExpression , queueName ));
1149
1142
}
1150
1143
1151
- private Message receiveForReply (final String queueName , Channel channel , Message receiveMessage ) throws Exception {
1144
+ private Message receiveForReply (final String queueName , Channel channel ) throws Exception {
1152
1145
boolean channelTransacted = isChannelTransacted ();
1153
1146
boolean channelLocallyTransacted = isChannelLocallyTransacted (channel );
1147
+ Message receiveMessage = null ;
1154
1148
if (RabbitTemplate .this .receiveTimeout == 0 ) {
1155
1149
GetResponse response = channel .basicGet (queueName , !channelTransacted );
1156
1150
// Response can be null in the case that there is no message on the queue.
@@ -1189,7 +1183,7 @@ else if (channelTransacted) {
1189
1183
1190
1184
private Delivery consumeDelivery (Channel channel , String queueName , long timeoutMillis ) throws Exception {
1191
1185
Delivery delivery = null ;
1192
- Throwable exception = null ;
1186
+ RuntimeException exception = null ;
1193
1187
CompletableFuture <Delivery > future = new CompletableFuture <>();
1194
1188
DefaultConsumer consumer = createConsumer (queueName , channel , future ,
1195
1189
timeoutMillis < 0 ? DEFAULT_CONSUME_TIMEOUT : timeoutMillis );
@@ -1202,34 +1196,20 @@ private Delivery consumeDelivery(Channel channel, String queueName, long timeout
1202
1196
}
1203
1197
}
1204
1198
catch (ExecutionException e ) {
1205
- this .logger .error ("Consumer failed to receive message: " + consumer , e .getCause ());
1206
- exception = e .getCause ();
1199
+ Throwable cause = e .getCause ();
1200
+ this .logger .error ("Consumer failed to receive message: " + consumer , cause );
1201
+ exception = RabbitExceptionTranslator .convertRabbitAccessException (cause );
1202
+ throw exception ;
1207
1203
}
1208
1204
catch (InterruptedException e ) {
1209
1205
Thread .currentThread ().interrupt ();
1210
1206
}
1211
1207
catch (TimeoutException e ) {
1212
1208
// no result in time
1213
1209
}
1214
- try {
1210
+ finally {
1215
1211
if (exception == null || !(exception instanceof ConsumerCancelledException )) {
1216
- channel .basicCancel (consumer .getConsumerTag ());
1217
- }
1218
- }
1219
- catch (Exception e ) {
1220
- if (this .logger .isDebugEnabled ()) {
1221
- this .logger .debug ("Failed to cancel consumer: " + consumer , e );
1222
- }
1223
- }
1224
- if (exception != null ) {
1225
- if (exception instanceof RuntimeException ) {
1226
- throw (RuntimeException ) exception ;
1227
- }
1228
- else if (exception instanceof Error ) {
1229
- throw (Error ) exception ;
1230
- }
1231
- else {
1232
- throw new AmqpException (exception );
1212
+ cancelConsumerQuietly (channel , consumer );
1233
1213
}
1234
1214
}
1235
1215
return delivery ;
@@ -1606,16 +1586,23 @@ public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProp
1606
1586
}
1607
1587
finally {
1608
1588
this .replyHolder .remove (messageTag );
1609
- try {
1610
- channel .basicCancel (consumerTag );
1611
- }
1612
- catch (Exception e ) {
1613
- }
1589
+ cancelConsumerQuietly (channel , consumer );
1614
1590
}
1615
1591
return reply ;
1616
1592
}, obtainTargetConnectionFactory (this .sendConnectionFactorySelectorExpression , message ));
1617
1593
}
1618
1594
1595
+ private void cancelConsumerQuietly (Channel channel , DefaultConsumer consumer ) {
1596
+ try {
1597
+ channel .basicCancel (consumer .getConsumerTag ());
1598
+ }
1599
+ catch (Exception e ) {
1600
+ if (this .logger .isDebugEnabled ()) {
1601
+ this .logger .debug ("Failed to cancel consumer: " + consumer , e );
1602
+ }
1603
+ }
1604
+ }
1605
+
1619
1606
protected Message doSendAndReceiveWithFixed (final String exchange , final String routingKey , final Message message ,
1620
1607
final CorrelationData correlationData ) {
1621
1608
Assert .state (this .isListener , () -> "RabbitTemplate is not configured as MessageListener - "
0 commit comments