AMQQueue queue;
//TODO: do we need to check that the queue already exists with exactly the same "configuration"?
AMQChannel channel = protocolConnection.getChannel(channelId);
if (channel == null)
{
throw body.getChannelNotFoundException(channelId);
}
if(body.getPassive())
{
queue = virtualHost.getQueue(queueName.toString());
if (queue == null)
{
String msg = "Queue: " + queueName + " not found on VirtualHost(" + virtualHost + ").";
throw body.getChannelException(AMQConstant.NOT_FOUND, msg);
}
else
{
AMQSessionModel owningSession = queue.getExclusiveOwningSession();
if (queue.isExclusive() && !queue.isDurable()
&& (owningSession == null || owningSession.getConnectionModel() != protocolConnection))
{
throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
"Queue " + queue.getName() + " is exclusive, but not created on this Connection.");
}
//set this as the default queue on the channel:
channel.setDefaultQueue(queue);
}
}
else
{
try
{
queue = createQueue(queueName, body, virtualHost, protocolConnection);
queue.setAuthorizationHolder(protocolConnection);
if (body.getExclusive())
{
queue.setExclusiveOwningSession(protocolConnection.getChannel(channelId));
queue.setAuthorizationHolder(protocolConnection);
if(!body.getDurable())
{
final AMQQueue q = queue;
final AMQProtocolSession.Task sessionCloseTask = new AMQProtocolSession.Task()
{
public void doTask(AMQProtocolSession session) throws AMQException
{
q.setExclusiveOwningSession(null);
}
};
protocolConnection.addSessionCloseTask(sessionCloseTask);
queue.addQueueDeleteTask(new AMQQueue.Task() {
public void doTask(AMQQueue queue) throws AMQException
{
protocolConnection.removeSessionCloseTask(sessionCloseTask);
}
});
}
}
}
catch(QueueExistsException qe)
{
queue = qe.getExistingQueue();
AMQSessionModel owningSession = queue.getExclusiveOwningSession();
if (queue.isExclusive() && !queue.isDurable() && (owningSession == null || owningSession.getConnectionModel() != protocolConnection))
{
throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
"Queue " + queue.getName() + " is exclusive, but not created on this Connection.");
}
else if(queue.isExclusive() != body.getExclusive())
{
throw body.getChannelException(AMQConstant.ALREADY_EXISTS,
"Cannot re-declare queue '" + queue.getName() + "' with different exclusivity (was: "
+ queue.isExclusive() + " requested " + body.getExclusive() + ")");
}
else if (body.getExclusive() && !(queue.isDurable() ? String.valueOf(queue.getOwner()).equals(session.getClientID()) : (owningSession == null || owningSession.getConnectionModel() == protocolConnection)))
{
throw body.getChannelException(AMQConstant.ALREADY_EXISTS, "Cannot declare queue('" + queueName + "'), "
+ "as exclusive queue with same name "
+ "declared on another client ID('"
+ queue.getOwner() + "') your clientID('" + session.getClientID() + "')");
}
else if(queue.isAutoDelete() != body.getAutoDelete())
{
throw body.getChannelException(AMQConstant.ALREADY_EXISTS,
"Cannot re-declare queue '" + queue.getName() + "' with different auto-delete (was: "
+ queue.isAutoDelete() + " requested " + body.getAutoDelete() + ")");
}
else if(queue.isDurable() != body.getDurable())
{
throw body.getChannelException(AMQConstant.ALREADY_EXISTS,
"Cannot re-declare queue '" + queue.getName() + "' with different durability (was: "
+ queue.isDurable() + " requested " + body.getDurable() + ")");
}
}
//set this as the default queue on the channel:
channel.setDefaultQueue(queue);
}
if (!body.getNowait())
{
channel.sync();
MethodRegistry methodRegistry = protocolConnection.getMethodRegistry();
QueueDeclareOkBody responseBody =
methodRegistry.createQueueDeclareOkBody(queueName,
queue.getMessageCount(),
queue.getConsumerCount());