use of org.apache.qpid.server.model.ExclusivityPolicy in project qpid-broker-j by apache.
the class ExchangeSendingDestination method getQueue.
private static Queue<?> getQueue(Exchange<?> exchange, Source source, String subscriptionName, BindingInfo bindingInfo) throws AmqpErrorException {
boolean isDurable = source.getExpiryPolicy() == TerminusExpiryPolicy.NEVER;
boolean isShared = hasCapability(source.getCapabilities(), SHARED_CAPABILITY);
QueueManagingVirtualHost virtualHost;
if (exchange.getAddressSpace() instanceof QueueManagingVirtualHost) {
virtualHost = (QueueManagingVirtualHost) exchange.getAddressSpace();
} else {
throw new AmqpErrorException(new Error(AmqpError.INTERNAL_ERROR, "Address space of unexpected type"));
}
Queue<?> queue;
final Map<String, Object> attributes = new HashMap<>();
ExclusivityPolicy exclusivityPolicy;
if (isShared) {
exclusivityPolicy = ExclusivityPolicy.SHARED_SUBSCRIPTION;
} else {
exclusivityPolicy = ExclusivityPolicy.LINK;
}
org.apache.qpid.server.model.LifetimePolicy lifetimePolicy = getLifetimePolicy(source.getExpiryPolicy());
attributes.put(Queue.ID, UUID.randomUUID());
attributes.put(Queue.NAME, subscriptionName);
attributes.put(Queue.LIFETIME_POLICY, lifetimePolicy);
attributes.put(Queue.EXCLUSIVE, exclusivityPolicy);
attributes.put(Queue.DURABLE, isDurable);
Map<String, Map<String, Object>> bindings = bindingInfo.getBindings();
try {
queue = virtualHost.getSubscriptionQueue(exchange.getName(), attributes, bindings);
} catch (NotFoundException e) {
throw new AmqpErrorException(new Error(AmqpError.NOT_FOUND, e.getMessage()));
} catch (IllegalStateException e) {
throw new AmqpErrorException(new Error(AmqpError.RESOURCE_LOCKED, "Subscription is already in use"));
}
return queue;
}
use of org.apache.qpid.server.model.ExclusivityPolicy in project qpid-broker-j by apache.
the class AbstractVirtualHost method getSubscriptionQueue.
@Override
@DoOnConfigThread
public Queue<?> getSubscriptionQueue(@Param(name = "exchangeName", mandatory = true) final String exchangeName, @Param(name = "attributes", mandatory = true) final Map<String, Object> attributes, @Param(name = "bindings", mandatory = true) final Map<String, Map<String, Object>> bindings) {
Queue queue;
Object exclusivityPolicy = attributes.get(Queue.EXCLUSIVE);
if (exclusivityPolicy == null) {
exclusivityPolicy = getContextValue(ExclusivityPolicy.class, Queue.QUEUE_DEFAULT_EXCLUSIVITY_POLICY);
}
if (!(exclusivityPolicy instanceof ExclusivityPolicy)) {
throw new IllegalArgumentException("Exclusivity policy is required");
}
Exchange<?> exchange = findConfiguredObject(Exchange.class, exchangeName);
if (exchange == null) {
throw new NotFoundException(String.format("Exchange '%s' was not found", exchangeName));
}
try {
queue = createMessageDestination(Queue.class, attributes);
for (String binding : bindings.keySet()) {
exchange.addBinding(binding, queue, bindings.get(binding));
}
} catch (AbstractConfiguredObject.DuplicateNameException e) {
Queue<?> existingQueue = (Queue) e.getExisting();
if (existingQueue.getExclusive() == exclusivityPolicy) {
if (hasDifferentBindings(exchange, existingQueue, bindings)) {
if (existingQueue.getConsumers().isEmpty()) {
existingQueue.delete();
queue = createMessageDestination(Queue.class, attributes);
for (String binding : bindings.keySet()) {
try {
exchange.addBinding(binding, queue, bindings.get(binding));
} catch (AMQInvalidArgumentException ia) {
throw new IllegalArgumentException("Unexpected bind argument : " + ia.getMessage(), ia);
}
}
} else {
throw new IllegalStateException("subscription already in use");
}
} else {
queue = existingQueue;
}
} else {
throw new IllegalStateException("subscription already in use");
}
} catch (AMQInvalidArgumentException e) {
throw new IllegalArgumentException("Unexpected bind argument : " + e.getMessage(), e);
}
return queue;
}
use of org.apache.qpid.server.model.ExclusivityPolicy in project qpid-broker-j by apache.
the class BDBUpgradeTest method testQueueExclusivity.
/**
* Test that the backing queue for the durable subscription created was successfully
* detected and set as being exclusive during the upgrade process, and that the
* regular queue was not.
*/
public void testQueueExclusivity() throws Exception {
Map<String, Object> result = getQueueAttributes(QUEUE_NAME);
ExclusivityPolicy exclusivityPolicy = ExclusivityPolicy.valueOf((String) result.get(org.apache.qpid.server.model.Queue.EXCLUSIVE));
assertEquals("Queue should not have been marked as Exclusive during upgrade", ExclusivityPolicy.NONE, exclusivityPolicy);
result = getQueueAttributes("clientid" + ":" + SUB_NAME);
exclusivityPolicy = ExclusivityPolicy.valueOf((String) result.get(org.apache.qpid.server.model.Queue.EXCLUSIVE));
assertTrue("DurableSubscription backing queue should have been marked as Exclusive during upgrade", exclusivityPolicy != ExclusivityPolicy.NONE);
}
use of org.apache.qpid.server.model.ExclusivityPolicy in project qpid by apache.
the class Subscription method setQueueRef.
/**
* Set the queueRef property.
* @param queueRef the queueRef ObjectId.
*/
public void setQueueRef(final ObjectId queueRef, final Queue queue) {
setRefValue("queueRef", queueRef);
// Unfortunately the org.apache.qpid.server.model.Consumer doesn't yet allow access to its associated Queue
// so we pass a reference ourselves when we do setQueueRef. This is because some Subscription properties
// are *actually" related to the associated Queue.
_qName = queue.getName();
// In the Java Broker exclusivity may be NONE, SESSION, CONNECTION, CONTAINER, PRINCIPAL, LINK
// We map these to a boolean value to be consistent with the C++ Broker QMF values.
// TODO The C++ and Java Brokers should really return consistent information.
ExclusivityPolicy exclusivityPolicy = queue.getExclusive();
_exclusive = (exclusivityPolicy != ExclusivityPolicy.NONE) ? true : false;
}
use of org.apache.qpid.server.model.ExclusivityPolicy in project qpid-broker-j by apache.
the class AMQChannel method receiveQueueDeclare.
@Override
public void receiveQueueDeclare(final AMQShortString queueStr, final boolean passive, final boolean durable, final boolean exclusive, final boolean autoDelete, final boolean nowait, final FieldTable arguments) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("RECV[" + _channelId + "] QueueDeclare[" + " queue: " + queueStr + " passive: " + passive + " durable: " + durable + " exclusive: " + exclusive + " autoDelete: " + autoDelete + " nowait: " + nowait + " arguments: " + arguments + " ]");
}
NamedAddressSpace virtualHost = _connection.getAddressSpace();
final AMQShortString queueName;
// if we aren't given a queue name, we create one which we return to the client
if ((queueStr == null) || (queueStr.length() == 0)) {
queueName = AMQShortString.createAMQShortString("tmp_" + UUID.randomUUID());
} else {
queueName = queueStr;
}
Queue<?> queue;
if (passive) {
queue = getQueue(queueName.toString());
if (queue == null) {
closeChannel(ErrorCodes.NOT_FOUND, "Queue: '" + queueName + "' not found on VirtualHost '" + virtualHost.getName() + "'.");
} else {
if (!queue.verifySessionAccess(this)) {
_connection.sendConnectionClose(ErrorCodes.NOT_ALLOWED, "Queue '" + queue.getName() + "' is exclusive, but not created on this Connection.", getChannelId());
} else {
// set this as the default queue on the channel:
setDefaultQueue(queue);
if (!nowait) {
sync();
MethodRegistry methodRegistry = _connection.getMethodRegistry();
QueueDeclareOkBody responseBody = methodRegistry.createQueueDeclareOkBody(queueName, queue.getQueueDepthMessages(), queue.getConsumerCount());
_connection.writeFrame(responseBody.generateFrame(getChannelId()));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Queue " + queueName + " declared successfully");
}
}
}
}
} else {
try {
final String queueNameString = AMQShortString.toString(queueName);
Map<String, Object> wireArguments = FieldTable.convertToMap(arguments);
Object alternateExchange = wireArguments.get(ALTERNATE_EXCHANGE);
if (alternateExchange != null) {
String alternateExchangeName = String.valueOf(alternateExchange);
validateAlternateExchangeIsNotQueue(virtualHost, alternateExchangeName);
}
Queue.BehaviourOnUnknownDeclareArgument unknownArgumentBehaviour = getConnection().getContextValue(Queue.BehaviourOnUnknownDeclareArgument.class, Queue.UNKNOWN_QUEUE_DECLARE_ARGUMENT_BEHAVIOUR_NAME);
Map<String, Object> attributes = QueueArgumentsConverter.convertWireArgsToModel(queueNameString, wireArguments, getModel(), unknownArgumentBehaviour);
attributes.put(Queue.NAME, queueNameString);
attributes.put(Queue.DURABLE, durable);
LifetimePolicy lifetimePolicy;
ExclusivityPolicy exclusivityPolicy;
if (exclusive) {
lifetimePolicy = autoDelete ? LifetimePolicy.DELETE_ON_NO_OUTBOUND_LINKS : durable ? LifetimePolicy.PERMANENT : LifetimePolicy.DELETE_ON_CONNECTION_CLOSE;
exclusivityPolicy = durable ? ExclusivityPolicy.CONTAINER : ExclusivityPolicy.CONNECTION;
} else {
lifetimePolicy = autoDelete ? LifetimePolicy.DELETE_ON_NO_OUTBOUND_LINKS : LifetimePolicy.PERMANENT;
exclusivityPolicy = ExclusivityPolicy.NONE;
}
if (!attributes.containsKey(Queue.EXCLUSIVE)) {
attributes.put(Queue.EXCLUSIVE, exclusivityPolicy);
}
if (!attributes.containsKey(Queue.LIFETIME_POLICY)) {
attributes.put(Queue.LIFETIME_POLICY, lifetimePolicy);
}
queue = virtualHost.createMessageSource(Queue.class, attributes);
setDefaultQueue(queue);
if (!nowait) {
sync();
MethodRegistry methodRegistry = _connection.getMethodRegistry();
QueueDeclareOkBody responseBody = methodRegistry.createQueueDeclareOkBody(queueName, queue.getQueueDepthMessages(), queue.getConsumerCount());
_connection.writeFrame(responseBody.generateFrame(getChannelId()));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Queue " + queueName + " declared successfully");
}
}
} catch (AbstractConfiguredObject.DuplicateNameException qe) {
queue = (Queue<?>) qe.getExisting();
if (!queue.verifySessionAccess(this)) {
_connection.sendConnectionClose(ErrorCodes.NOT_ALLOWED, "Queue '" + queue.getName() + "' is exclusive, but not created on this Connection.", getChannelId());
} else if (queue.isExclusive() != exclusive) {
closeChannel(ErrorCodes.ALREADY_EXISTS, "Cannot re-declare queue '" + queue.getName() + "' with different exclusivity (was: " + queue.isExclusive() + " requested " + exclusive + ")");
} else if ((autoDelete && queue.getLifetimePolicy() == LifetimePolicy.PERMANENT) || (!autoDelete && queue.getLifetimePolicy() != ((exclusive && !durable) ? LifetimePolicy.DELETE_ON_CONNECTION_CLOSE : LifetimePolicy.PERMANENT))) {
closeChannel(ErrorCodes.ALREADY_EXISTS, "Cannot re-declare queue '" + queue.getName() + "' with different lifetime policy (was: " + queue.getLifetimePolicy() + " requested autodelete: " + autoDelete + ")");
} else {
setDefaultQueue(queue);
if (!nowait) {
sync();
MethodRegistry methodRegistry = _connection.getMethodRegistry();
QueueDeclareOkBody responseBody = methodRegistry.createQueueDeclareOkBody(queueName, queue.getQueueDepthMessages(), queue.getConsumerCount());
_connection.writeFrame(responseBody.generateFrame(getChannelId()));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Queue " + queueName + " declared successfully");
}
}
}
} catch (AccessControlException e) {
_connection.sendConnectionClose(ErrorCodes.ACCESS_REFUSED, e.getMessage(), getChannelId());
} catch (UnknownAlternateBindingException e) {
final String message = String.format("Unknown alternate destination: '%s'", e.getAlternateBindingName());
_connection.sendConnectionClose(ErrorCodes.NOT_FOUND, message, getChannelId());
} catch (IllegalArgumentException | IllegalConfigurationException e) {
String message = String.format("Error creating queue '%s': %s", queueName, e.getMessage());
_connection.sendConnectionClose(ErrorCodes.INVALID_ARGUMENT, message, getChannelId());
}
}
}
Aggregations