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 ;
5456import java .util .Collections ;
5557import java .util .HashMap ;
5658import java .util .Map ;
59+ import java .util .concurrent .atomic .AtomicLong ;
5760import java .util .concurrent .TimeoutException ;
5861
5962
@@ -98,6 +101,14 @@ public class ChannelN extends AMQChannel implements com.rabbitmq.client.Channel
98101 */
99102 public volatile FlowListener flowListener = null ;
100103
104+ /** Reference to the currently-active AckListener, or null if there is none.
105+ */
106+ public volatile AckListener ackListener = null ;
107+
108+ /** Current published message count (used by publisher acknowledgements)
109+ */
110+ private final AtomicLong publishedMessageCount = new AtomicLong (-1 );
111+
101112 /** Reference to the currently-active default consumer, or null if there is
102113 * none.
103114 */
@@ -153,6 +164,19 @@ public void setFlowListener(FlowListener listener) {
153164 flowListener = listener ;
154165 }
155166
167+ /** Returns the current AckListener. */
168+ public AckListener getAckListener () {
169+ return ackListener ;
170+ }
171+
172+ /**
173+ * Sets the current AckListener.
174+ * A null argument is interpreted to mean "do not use an ack listener".
175+ */
176+ public void setAckListener (AckListener listener ) {
177+ ackListener = listener ;
178+ }
179+
156180 /** Returns the current default consumer. */
157181 public Consumer getDefaultConsumer () {
158182 return defaultConsumer ;
@@ -310,6 +334,17 @@ public void releaseChannelNumber() {
310334 }
311335 }
312336 return true ;
337+ } else if (method instanceof Basic .Ack ) {
338+ Basic .Ack ack = (Basic .Ack ) method ;
339+ AckListener l = getAckListener ();
340+ if (l != null ) {
341+ try {
342+ l .handleAck (ack .getDeliveryTag (), ack .getMultiple ());
343+ } catch (Throwable ex ) {
344+ _connection .getExceptionHandler ().handleAckListenerException (this , ex );
345+ }
346+ }
347+ return true ;
313348 } else if (method instanceof Basic .RecoverOk ) {
314349 for (Consumer callback : _consumers .values ()) {
315350 callback .handleRecoverOk ();
@@ -463,6 +498,8 @@ public void basicPublish(String exchange, String routingKey,
463498 BasicProperties props , byte [] body )
464499 throws IOException
465500 {
501+ if (publishedMessageCount .get () >= 0 )
502+ publishedMessageCount .incrementAndGet ();
466503 BasicProperties useProps = props ;
467504 if (props == null ) {
468505 useProps = MessageProperties .MINIMAL_BASIC ;
@@ -553,7 +590,7 @@ public Exchange.UnbindOk exchangeUnbind(String destination, String source,
553590 String routingKey ) throws IOException {
554591 return exchangeUnbind (destination , source , routingKey , null );
555592 }
556-
593+
557594 /** Public API - {@inheritDoc} */
558595 public Queue .DeclareOk queueDeclare (String queue , boolean durable , boolean exclusive ,
559596 boolean autoDelete , Map <String , Object > arguments )
@@ -769,6 +806,14 @@ public Consumer transformReply(AMQCommand replyCommand) {
769806 }
770807 }
771808
809+
810+ /** Public API - {@inheritDoc} */
811+ public Basic .RecoverOk basicRecover ()
812+ throws IOException
813+ {
814+ return basicRecover (true );
815+ }
816+
772817 /** Public API - {@inheritDoc} */
773818 public Basic .RecoverOk basicRecover (boolean requeue )
774819 throws IOException
@@ -805,6 +850,17 @@ public Tx.RollbackOk txRollback()
805850 return (Tx .RollbackOk ) exnWrappingRpc (new Tx .Rollback ()).getMethod ();
806851 }
807852
853+ /** Public API - {@inheritDoc} */
854+ public Confirm .SelectOk confirmSelect (boolean multiple )
855+ throws IOException
856+ {
857+ if (publishedMessageCount .get () == -1 )
858+ publishedMessageCount .set (0 );
859+ return (Confirm .SelectOk )
860+ exnWrappingRpc (new Confirm .Select (multiple , false )).getMethod ();
861+
862+ }
863+
808864 /** Public API - {@inheritDoc} */
809865 public Channel .FlowOk flow (final boolean a ) throws IOException {
810866 return (Channel .FlowOk ) exnWrappingRpc (new Channel .Flow () {{active = a ;}}).getMethod ();
@@ -815,4 +871,8 @@ public Channel.FlowOk getFlow() {
815871 return new Channel .FlowOk (!_blockContent );
816872 }
817873
874+ /** Public API - {@inheritDoc} */
875+ public long getPublishedMessageCount () {
876+ return publishedMessageCount .longValue ();
877+ }
818878}
0 commit comments