All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.bitsensor.plugins.shaded.org.springframework.amqp.rabbit.support.PublisherCallbackChannelImpl Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.bitsensor.plugins.shaded.io.bitsensor.plugins.shaded.org.springframework.amqp.rabbit.support;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.TimeoutException;

import io.bitsensor.plugins.shaded.org.apache.commons.logging.Log;
import io.bitsensor.plugins.shaded.org.apache.commons.logging.LogFactory;

import io.bitsensor.plugins.shaded.org.springframework.util.Assert;

import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Basic.RecoverOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.BasicProperties;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Exchange.BindOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Exchange.DeclareOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Exchange.DeleteOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Exchange.UnbindOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.PurgeOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Tx.CommitOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Tx.RollbackOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Tx.SelectOk;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.AlreadyClosedException;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.BuiltinExchangeType;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.Channel;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.Command;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.ConfirmListener;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.Connection;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.Consumer;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.GetResponse;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.Method;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.ReturnListener;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.ShutdownListener;
import io.bitsensor.plugins.shaded.com.rabbitmq.client.ShutdownSignalException;

/**
 * Channel wrapper to allow a single listener able to handle
 * confirms from multiple channels.
 *
 * @author Gary Russell
 * @since 1.0.1
 *
 */
public class PublisherCallbackChannelImpl
		implements PublisherCallbackChannel, ConfirmListener, ReturnListener, ShutdownListener {

	private final Log logger = LogFactory.getLog(this.getClass());

	private final Channel delegate;

	private final ConcurrentMap listeners = new ConcurrentHashMap();

	private final Map> pendingConfirms
		= new ConcurrentHashMap>();

	private final SortedMap listenerForSeq = new ConcurrentSkipListMap();

	public PublisherCallbackChannelImpl(Channel delegate) {
		delegate.addShutdownListener(this);
		this.delegate = delegate;
	}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BEGIN PURE DELEGATE METHODS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	@Override
	public void addShutdownListener(ShutdownListener listener) {
		this.delegate.addShutdownListener(listener);
	}

	@Override
	public void removeShutdownListener(ShutdownListener listener) {
		this.delegate.removeShutdownListener(listener);
	}

	@Override
	public ShutdownSignalException getCloseReason() {
		return this.delegate.getCloseReason();
	}

	@Override
	public void notifyListeners() {
		this.delegate.notifyListeners();
	}

	@Override
	public boolean isOpen() {
		return this.delegate.isOpen();
	}

	@Override
	public int getChannelNumber() {
		return this.delegate.getChannelNumber();
	}

	@Override
	public Connection getConnection() {
		return this.delegate.getConnection();
	}

	@Override
	public void close(int closeCode, String closeMessage) throws IOException, TimeoutException {
		this.delegate.close(closeCode, closeMessage);
	}

	/**
	 * Added to the 3.3.x client
	 * @since 1.3.3
	 * @deprecated in the 3.5.3 client
	 */
	@Override
	@Deprecated
	public boolean flowBlocked() {
		return this.delegate.flowBlocked();
	}

	@Override
	public void abort() throws IOException {
		this.delegate.abort();
	}

	@Override
	public void abort(int closeCode, String closeMessage) throws IOException {
		this.delegate.abort(closeCode, closeMessage);
	}

	@Override
	@SuppressWarnings("deprecation")
	public void addFlowListener(io.bitsensor.plugins.shaded.com.rabbitmq.client.FlowListener listener) {
		this.delegate.addFlowListener(listener);
	}

	@Override
	@SuppressWarnings("deprecation")
	public boolean removeFlowListener(io.bitsensor.plugins.shaded.com.rabbitmq.client.FlowListener listener) {
		return this.delegate.removeFlowListener(listener);
	}

	@Override
	@SuppressWarnings("deprecation")
	public void clearFlowListeners() {
		this.delegate.clearFlowListeners();
	}

	@Override
	public Consumer getDefaultConsumer() {
		return this.delegate.getDefaultConsumer();
	}

	@Override
	public void setDefaultConsumer(Consumer consumer) {
		this.delegate.setDefaultConsumer(consumer);
	}

	@Override
	public void basicQos(int prefetchSize, int prefetchCount, boolean global)
			throws IOException {
		this.delegate.basicQos(prefetchSize, prefetchCount, global);
	}

	/**
	 * Added to the 3.3.x client
	 * @since 1.3.3
	 */
	@Override
	public void basicQos(int prefetchCount, boolean global) throws IOException {
		this.delegate.basicQos(prefetchCount, global);
	}

	@Override
	public void basicQos(int prefetchCount) throws IOException {
		this.delegate.basicQos(prefetchCount);
	}

	@Override
	public void basicPublish(String exchange, String routingKey,
			BasicProperties props, byte[] body) throws IOException {
		this.delegate.basicPublish(exchange, routingKey, props, body);
	}

	@Override
	public void basicPublish(String exchange, String routingKey,
			boolean mandatory, boolean immediate, BasicProperties props,
			byte[] body) throws IOException {
		this.delegate.basicPublish(exchange, routingKey, mandatory, props, body);
	}

	@Override
	public void basicPublish(String exchange, String routingKey,
			boolean mandatory, BasicProperties props, byte[] body)
			throws IOException {
		this.delegate.basicPublish(exchange, routingKey, mandatory, props, body);
	}

	@Override
	public DeclareOk exchangeDeclare(String exchange, String type)
			throws IOException {
		return this.delegate.exchangeDeclare(exchange, type);
	}

	@Override
	public DeclareOk exchangeDeclare(String exchange, BuiltinExchangeType type) throws IOException {
		return this.delegate.exchangeDeclare(exchange, type);
	}

	@Override
	public DeclareOk exchangeDeclare(String exchange, String type,
			boolean durable) throws IOException {
		return this.delegate.exchangeDeclare(exchange, type, durable);
	}

	@Override
	public DeclareOk exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable) throws IOException {
		return this.delegate.exchangeDeclare(exchange, type, durable);
	}

	@Override
	public DeclareOk exchangeDeclare(String exchange, String type,
			boolean durable, boolean autoDelete, Map arguments)
			throws IOException {
		return this.delegate.exchangeDeclare(exchange, type, durable, autoDelete,
				arguments);
	}

	@Override
	public DeclareOk exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete,
			Map arguments) throws IOException {
		return this.delegate.exchangeDeclare(exchange, type, durable, autoDelete, arguments);
	}

	@Override
	public DeclareOk exchangeDeclare(String exchange, String type,
			boolean durable, boolean autoDelete, boolean internal,
			Map arguments) throws IOException {
		return this.delegate.exchangeDeclare(exchange, type, durable, autoDelete,
				internal, arguments);
	}

	@Override
	public DeclareOk exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete,
			boolean internal, Map arguments) throws IOException {
		return this.delegate.exchangeDeclare(exchange, type, durable, autoDelete, internal, arguments);
	}

	@Override
	public DeclareOk exchangeDeclarePassive(String name) throws IOException {
		return this.delegate.exchangeDeclarePassive(name);
	}

	@Override
	public DeleteOk exchangeDelete(String exchange, boolean ifUnused)
			throws IOException {
		return this.delegate.exchangeDelete(exchange, ifUnused);
	}

	@Override
	public DeleteOk exchangeDelete(String exchange) throws IOException {
		return this.delegate.exchangeDelete(exchange);
	}

	@Override
	public BindOk exchangeBind(String destination, String source,
			String routingKey) throws IOException {
		return this.delegate.exchangeBind(destination, source, routingKey);
	}

	@Override
	public BindOk exchangeBind(String destination, String source,
			String routingKey, Map arguments)
			throws IOException {
		return this.delegate
				.exchangeBind(destination, source, routingKey, arguments);
	}

	@Override
	public UnbindOk exchangeUnbind(String destination, String source,
			String routingKey) throws IOException {
		return this.delegate.exchangeUnbind(destination, source, routingKey);
	}

	@Override
	public UnbindOk exchangeUnbind(String destination, String source,
			String routingKey, Map arguments)
			throws IOException {
		return this.delegate.exchangeUnbind(destination, source, routingKey,
				arguments);
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.DeclareOk queueDeclare()
			throws IOException {
		return this.delegate.queueDeclare();
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.DeclareOk queueDeclare(String queue,
			boolean durable, boolean exclusive, boolean autoDelete,
			Map arguments) throws IOException {
		return this.delegate.queueDeclare(queue, durable, exclusive, autoDelete,
				arguments);
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.DeclareOk queueDeclarePassive(
			String queue) throws IOException {
		return this.delegate.queueDeclarePassive(queue);
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.DeleteOk queueDelete(String queue)
			throws IOException {
		return this.delegate.queueDelete(queue);
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.DeleteOk queueDelete(String queue,
			boolean ifUnused, boolean ifEmpty) throws IOException {
		return this.delegate.queueDelete(queue, ifUnused, ifEmpty);
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.BindOk queueBind(String queue,
			String exchange, String routingKey) throws IOException {
		return this.delegate.queueBind(queue, exchange, routingKey);
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.BindOk queueBind(String queue,
			String exchange, String routingKey, Map arguments)
			throws IOException {
		return this.delegate.queueBind(queue, exchange, routingKey, arguments);
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.UnbindOk queueUnbind(String queue,
			String exchange, String routingKey) throws IOException {
		return this.delegate.queueUnbind(queue, exchange, routingKey);
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Queue.UnbindOk queueUnbind(String queue,
			String exchange, String routingKey, Map arguments)
			throws IOException {
		return this.delegate.queueUnbind(queue, exchange, routingKey, arguments);
	}

	@Override
	public PurgeOk queuePurge(String queue) throws IOException {
		return this.delegate.queuePurge(queue);
	}

	@Override
	public GetResponse basicGet(String queue, boolean autoAck)
			throws IOException {
		return this.delegate.basicGet(queue, autoAck);
	}

	@Override
	public void basicAck(long deliveryTag, boolean multiple) throws IOException {
		this.delegate.basicAck(deliveryTag, multiple);
	}

	@Override
	public void basicNack(long deliveryTag, boolean multiple, boolean requeue)
			throws IOException {
		this.delegate.basicNack(deliveryTag, multiple, requeue);
	}

	@Override
	public void basicReject(long deliveryTag, boolean requeue)
			throws IOException {
		this.delegate.basicReject(deliveryTag, requeue);
	}

	@Override
	public String basicConsume(String queue, Consumer callback)
			throws IOException {
		return this.delegate.basicConsume(queue, callback);
	}

	@Override
	public String basicConsume(String queue, boolean autoAck, Consumer callback)
			throws IOException {
		return this.delegate.basicConsume(queue, autoAck, callback);
	}

	@Override
	public String basicConsume(String queue, boolean autoAck,
			String consumerTag, Consumer callback) throws IOException {
		return this.delegate.basicConsume(queue, autoAck, consumerTag, callback);
	}

	/**
	 * Added to the 3.3.x client
	 * @since 1.3.3
	 */
	@Override
	public String basicConsume(String queue, boolean autoAck, Map arguments, Consumer callback)
			throws IOException {
		return this.delegate.basicConsume(queue, autoAck, arguments, callback);
	}

	@Override
	public String basicConsume(String queue, boolean autoAck,
			String consumerTag, boolean noLocal, boolean exclusive,
			Map arguments, Consumer callback)
			throws IOException {
		return this.delegate.basicConsume(queue, autoAck, consumerTag, noLocal,
				exclusive, arguments, callback);
	}

	@Override
	public void basicCancel(String consumerTag) throws IOException {
		this.delegate.basicCancel(consumerTag);
	}

	@Override
	public RecoverOk basicRecover() throws IOException {
		return this.delegate.basicRecover();
	}

	@Override
	public RecoverOk basicRecover(boolean requeue) throws IOException {
		return this.delegate.basicRecover(requeue);
	}

	@Override
	public SelectOk txSelect() throws IOException {
		return this.delegate.txSelect();
	}

	@Override
	public CommitOk txCommit() throws IOException {
		return this.delegate.txCommit();
	}

	@Override
	public RollbackOk txRollback() throws IOException {
		return this.delegate.txRollback();
	}

	@Override
	public io.bitsensor.plugins.shaded.com.rabbitmq.client.AMQP.Confirm.SelectOk confirmSelect()
			throws IOException {
		return this.delegate.confirmSelect();
	}

	@Override
	public long getNextPublishSeqNo() {
		return this.delegate.getNextPublishSeqNo();
	}

	@Override
	public boolean waitForConfirms() throws InterruptedException {
		return this.delegate.waitForConfirms();
	}

	@Override
	public boolean waitForConfirms(long timeout) throws InterruptedException,
			TimeoutException {
		return this.delegate.waitForConfirms(timeout);
	}

	@Override
	public void waitForConfirmsOrDie() throws IOException, InterruptedException {
		this.delegate.waitForConfirmsOrDie();
	}

	@Override
	public void waitForConfirmsOrDie(long timeout) throws IOException,
			InterruptedException, TimeoutException {
		this.delegate.waitForConfirmsOrDie(timeout);
	}

	@Override
	public void asyncRpc(Method method) throws IOException {
		this.delegate.asyncRpc(method);
	}

	@Override
	public Command rpc(Method method) throws IOException {
		return this.delegate.rpc(method);
	}

	@Override
	public void addConfirmListener(ConfirmListener listener) {
		this.delegate.addConfirmListener(listener);
	}

	@Override
	public boolean removeConfirmListener(ConfirmListener listener) {
		return this.delegate.removeConfirmListener(listener);
	}

	@Override
	public void clearConfirmListeners() {
		this.delegate.clearConfirmListeners();
	}

	@Override
	public void addReturnListener(ReturnListener listener) {
		this.delegate.addReturnListener(listener);
	}

	@Override
	public boolean removeReturnListener(ReturnListener listener) {
		return this.delegate.removeReturnListener(listener);
	}

	@Override
	public synchronized void clearReturnListeners() {
		this.delegate.clearReturnListeners();
	}

	@Override
	public void exchangeBindNoWait(String destination, String source,
			String routingKey, Map arguments) throws IOException {
		this.delegate.exchangeBind(destination, source, routingKey, arguments);
	}

	@Override
	public void exchangeDeclareNoWait(String exchange, String type,
			boolean durable, boolean autoDelete, boolean internal,
			Map arguments) throws IOException {
		this.delegate.exchangeDeclareNoWait(exchange, type, durable, autoDelete, internal, arguments);
	}

	@Override
	public void exchangeDeclareNoWait(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete,
			boolean internal, Map arguments) throws IOException {
		this.delegate.exchangeDeclareNoWait(exchange, type, durable, autoDelete, internal, arguments);
	}

	@Override
	public void exchangeDeleteNoWait(String exchange, boolean ifUnused) throws IOException {
		this.delegate.exchangeDeleteNoWait(exchange, ifUnused);
	}

	@Override
	public void exchangeUnbindNoWait(String destination, String source,
			String routingKey, Map arguments)
			throws IOException {
		this.delegate.exchangeUnbindNoWait(destination, source, routingKey, arguments);
	}

	@Override
	public void queueBindNoWait(String queue,
			String exchange, String routingKey, Map arguments) throws IOException {
		this.delegate.queueBindNoWait(queue, exchange, routingKey, arguments);
	}

	@Override
	public void queueDeclareNoWait(String queue,
			boolean durable, boolean exclusive, boolean autoDelete,
			Map arguments)
			throws IOException {
		this.delegate.queueDeclareNoWait(queue, durable, exclusive, autoDelete, arguments);
	}

	@Override
	public void queueDeleteNoWait(String queue,
			boolean ifUnused, boolean ifEmpty) throws IOException {
		this.delegate.queueDeleteNoWait(queue, ifUnused, ifEmpty);
	}

	@Override
	public long consumerCount(String queue) throws IOException {
		return this.delegate.consumerCount(queue);
	}

	@Override
	public long messageCount(String queue) throws IOException {
		return this.delegate.messageCount(queue);
	}

	@Override
	public Channel getDelegate() {
		return this.delegate;
	}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// END PURE DELEGATE METHODS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	@Override
	public void close() throws IOException, TimeoutException {
		try {
			this.delegate.close();
		}
		catch (AlreadyClosedException e) {
			if (this.logger.isTraceEnabled()) {
				this.logger.trace(this.delegate + " is already closed");
			}
		}
		generateNacksForPendingAcks("Channel closed by application");
	}

	private synchronized void generateNacksForPendingAcks(String cause) {
		for (Entry> entry : this.pendingConfirms.entrySet()) {
			Listener listener = entry.getKey();
			for (Entry confirmEntry : entry.getValue().entrySet()) {
				confirmEntry.getValue().setCause(cause);
				if (this.logger.isDebugEnabled()) {
					this.logger.debug(this.toString() + " PC:Nack:(close):" + confirmEntry.getKey());
				}
				processAck(confirmEntry.getKey(), false, false, false);
			}
			listener.revoke(this);
		}
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("PendingConfirms cleared");
		}
		this.pendingConfirms.clear();
		this.listenerForSeq.clear();
		this.listeners.clear();
	}

	/**
	 * Add the listener and return the internal map of pending confirmations for that listener.
	 * @param listener the listener.
	 */
	@Override
	public void addListener(Listener listener) {
		Assert.notNull(listener, "Listener cannot be null");
		if (this.listeners.size() == 0) {
			this.delegate.addConfirmListener(this);
			this.delegate.addReturnListener(this);
		}
		if (this.listeners.putIfAbsent(listener.getUUID(), listener) == null) {
			this.pendingConfirms.put(listener, new ConcurrentSkipListMap());
			if (this.logger.isDebugEnabled()) {
				this.logger.debug("Added listener " + listener);
			}
		}
	}

	@Override
	public synchronized Collection expire(Listener listener, long cutoffTime) {
		SortedMap pendingConfirmsForListener = this.pendingConfirms.get(listener);
		if (pendingConfirmsForListener == null) {
			return Collections.emptyList();
		}
		else {
			List expired = new ArrayList();
			Iterator> iterator = pendingConfirmsForListener.entrySet().iterator();
			while (iterator.hasNext()) {
				PendingConfirm pendingConfirm = iterator.next().getValue();
				if (pendingConfirm.getTimestamp() < cutoffTime) {
					expired.add(pendingConfirm);
					iterator.remove();
				}
				else {
					break;
				}
			}
			return expired;
		}
	}

//	ConfirmListener

	@Override
	public void handleAck(long seq, boolean multiple)
			throws IOException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug(this.toString() + " PC:Ack:" + seq + ":" + multiple);
		}
		this.processAck(seq, true, multiple, true);
	}

	@Override
	public void handleNack(long seq, boolean multiple)
			throws IOException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug(this.toString() + " PC:Nack:" + seq + ":" + multiple);
		}
		this.processAck(seq, false, multiple, true);
	}

	private synchronized void processAck(long seq, boolean ack, boolean multiple, boolean remove) {
		if (multiple) {
			/*
			 * Piggy-backed ack - extract all Listeners for this and earlier
			 * sequences. Then, for each Listener, handle each of it's acks.
			 * Finally, remove the sequences from listenerForSeq.
			 */
			Map involvedListeners = this.listenerForSeq.headMap(seq + 1);
			// eliminate duplicates
			Set listeners = new HashSet(involvedListeners.values());
			for (Listener involvedListener : listeners) {
				// find all unack'd confirms for this listener and handle them
				SortedMap confirmsMap = this.pendingConfirms.get(involvedListener);
				if (confirmsMap != null) {
					Map confirms = confirmsMap.headMap(seq + 1);
					Iterator> iterator = confirms.entrySet().iterator();
					while (iterator.hasNext()) {
						Entry entry = iterator.next();
						PendingConfirm value = entry.getValue();
						iterator.remove();
						doHandleConfirm(ack, involvedListener, value);
					}
				}
			}
			List seqs = new ArrayList(involvedListeners.keySet());
			for (Long key : seqs) {
				this.listenerForSeq.remove(key);
			}
		}
		else {
			Listener listener = this.listenerForSeq.remove(seq);
			if (listener != null) {
				SortedMap confirmsForListener = this.pendingConfirms.get(listener);
				PendingConfirm pendingConfirm;
				if (remove) {
					pendingConfirm = confirmsForListener.remove(seq);
				}
				else {
					pendingConfirm = confirmsForListener.get(seq);
				}
				if (pendingConfirm != null) {
					doHandleConfirm(ack, listener, pendingConfirm);
				}
			}
			else {
				if (this.logger.isDebugEnabled()) {
					this.logger.debug(this.delegate.toString() + " No listener for seq:" + seq);
				}
			}
		}
	}

	private void doHandleConfirm(boolean ack, Listener listener, PendingConfirm pendingConfirm) {
		try {
			if (listener.isConfirmListener()) {
				if (this.logger.isDebugEnabled()) {
					this.logger.debug("Sending confirm " + pendingConfirm);
				}
				listener.handleConfirm(pendingConfirm, ack);
			}
		}
		catch (Exception e) {
			this.logger.error("Exception delivering confirm", e);
		}
	}

	@Override
	public synchronized void addPendingConfirm(Listener listener, long seq, PendingConfirm pendingConfirm) {
		SortedMap pendingConfirmsForListener = this.pendingConfirms.get(listener);
		Assert.notNull(pendingConfirmsForListener,
				"Listener not registered: " + listener + " " + this.pendingConfirms.keySet());
		pendingConfirmsForListener.put(seq, pendingConfirm);
		this.listenerForSeq.put(seq, listener);
	}

//  ReturnListener

	@Override
	public void handleReturn(int replyCode,
			String replyText,
			String exchange,
			String routingKey,
			AMQP.BasicProperties properties,
			byte[] body) throws IOException {
		String uuidObject = properties.getHeaders().get(RETURN_CORRELATION_KEY).toString();
		Listener listener = this.listeners.get(uuidObject);
		if (listener == null || !listener.isReturnListener()) {
			if (this.logger.isWarnEnabled()) {
				this.logger.warn("No Listener for returned message");
			}
		}
		else {
			listener.handleReturn(replyCode, replyText, exchange, routingKey, properties, body);
		}
	}

// ShutdownListener

	@Override
	public void shutdownCompleted(ShutdownSignalException cause) {
		generateNacksForPendingAcks(cause.getMessage());
	}

// Object

	@Override
	public int hashCode() {
		return this.delegate.hashCode();
	}


	@Override
	public boolean equals(Object obj) {
		return obj == this || this.delegate.equals(obj);
	}

	@Override
	public String toString() {
		return "PublisherCallbackChannelImpl: " + this.delegate.toString();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy