3131
3232package com .rabbitmq .client .impl ;
3333
34+ import com .rabbitmq .client .AckListener ;
3435import com .rabbitmq .client .AMQP .BasicProperties ;
3536import com .rabbitmq .client .AMQP ;
3637import com .rabbitmq .client .Command ;
4546import com .rabbitmq .client .UnexpectedMethodError ;
4647import com .rabbitmq .client .impl .AMQImpl .Basic ;
4748import com .rabbitmq .client .impl .AMQImpl .Channel ;
49+ import com .rabbitmq .client .impl .AMQImpl .Confirm ;
4850import com .rabbitmq .client .impl .AMQImpl .Exchange ;
4951import com .rabbitmq .client .impl .AMQImpl .Queue ;
5052import com .rabbitmq .client .impl .AMQImpl .Tx ;
@@ -98,6 +100,14 @@ public class ChannelN extends AMQChannel implements com.rabbitmq.client.Channel
98100 */
99101 public volatile FlowListener flowListener = null ;
100102
103+ /** Reference to the currently-active AckListener, or null if there is none.
104+ */
105+ public volatile AckListener ackListener = null ;
106+
107+ /** Current published message count (used by publisher acknowledgements)
108+ */
109+ private long publishedMessageCount ;
110+
101111 /** Reference to the currently-active default consumer, or null if there is
102112 * none.
103113 */
@@ -153,6 +163,19 @@ public void setFlowListener(FlowListener listener) {
153163 flowListener = listener ;
154164 }
155165
166+ /** Returns the current AckListener. */
167+ public AckListener getAckListener () {
168+ return ackListener ;
169+ }
170+
171+ /**
172+ * Sets the current AckListener.
173+ * A null argument is interpreted to mean "do not use an ack listener".
174+ */
175+ public void setAckListener (AckListener listener ) {
176+ ackListener = listener ;
177+ }
178+
156179 /** Returns the current default consumer. */
157180 public Consumer getDefaultConsumer () {
158181 return defaultConsumer ;
@@ -310,6 +333,17 @@ public void releaseChannelNumber() {
310333 }
311334 }
312335 return true ;
336+ } else if (method instanceof Basic .Ack ) {
337+ Basic .Ack ack = (Basic .Ack ) method ;
338+ AckListener l = getAckListener ();
339+ if (l != null ) {
340+ try {
341+ l .handleAck (ack .getDeliveryTag (), ack .getMultiple ());
342+ } catch (Throwable ex ) {
343+ _connection .getExceptionHandler ().handleAckListenerException (this , ex );
344+ }
345+ }
346+ return true ;
313347 } else if (method instanceof Basic .RecoverOk ) {
314348 for (Consumer callback : _consumers .values ()) {
315349 callback .handleRecoverOk ();
@@ -463,6 +497,10 @@ public void basicPublish(String exchange, String routingKey,
463497 BasicProperties props , byte [] body )
464498 throws IOException
465499 {
500+ synchronized (_channelMutex ) {
501+ if (publishedMessageCount >= 0 )
502+ ++publishedMessageCount ;
503+ }
466504 BasicProperties useProps = props ;
467505 if (props == null ) {
468506 useProps = MessageProperties .MINIMAL_BASIC ;
@@ -805,6 +843,19 @@ public Tx.RollbackOk txRollback()
805843 return (Tx .RollbackOk ) exnWrappingRpc (new Tx .Rollback ()).getMethod ();
806844 }
807845
846+ /** Public API - {@inheritDoc} */
847+ public Confirm .SelectOk confirmSelect (boolean multiple )
848+ throws IOException
849+ {
850+ synchronized (_channelMutex ) {
851+ if (publishedMessageCount == -1 )
852+ publishedMessageCount = 0 ;
853+ }
854+ return (Confirm .SelectOk )
855+ exnWrappingRpc (new Confirm .Select (multiple , false )).getMethod ();
856+
857+ }
858+
808859 /** Public API - {@inheritDoc} */
809860 public Channel .FlowOk flow (final boolean a ) throws IOException {
810861 return (Channel .FlowOk ) exnWrappingRpc (new Channel .Flow () {{active = a ;}}).getMethod ();
@@ -815,4 +866,8 @@ public Channel.FlowOk getFlow() {
815866 return new Channel .FlowOk (!_blockContent );
816867 }
817868
869+ /** Public API - {@inheritDoc} */
870+ public long getPublishedMessageCount () {
871+ return publishedMessageCount ;
872+ }
818873}
0 commit comments