use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class AMQChannel method consumeFromSource.
/**
* Subscribe to a queue. We register all subscriptions in the channel so that if the channel is closed we can clean
* up all subscriptions, even if the client does not explicitly unsubscribe from all queues.
*
* @param tag the tag chosen by the client (if null, server will generate one)
* @param sources the queues to subscribe to
* @param acks Are acks enabled for this subscriber
* @param arguments Filters to apply to this subscriber
*
* @param exclusive Flag requesting exclusive access to the queue
* @return the consumer tag. This is returned to the subscriber and used in subsequent unsubscribe requests
*/
private AMQShortString consumeFromSource(AMQShortString tag, Collection<MessageSource> sources, boolean acks, FieldTable arguments, boolean exclusive, boolean noLocal) throws MessageSource.ExistingConsumerPreventsExclusive, MessageSource.ExistingExclusiveConsumer, AMQInvalidArgumentException, MessageSource.ConsumerAccessRefused, ConsumerTagInUseException, MessageSource.QueueDeleted {
if (tag == null) {
tag = new AMQShortString("sgen_" + getNextConsumerTag());
}
if (_tag2SubscriptionTargetMap.containsKey(tag)) {
throw new ConsumerTagInUseException("Consumer already exists with same tag: " + tag);
}
ConsumerTarget_0_8 target;
EnumSet<ConsumerOption> options = EnumSet.noneOf(ConsumerOption.class);
final boolean multiQueue = sources.size() > 1;
if (arguments != null && Boolean.TRUE.equals(arguments.get(AMQPFilterTypes.NO_CONSUME.getValue()))) {
target = ConsumerTarget_0_8.createBrowserTarget(this, tag, arguments, INFINITE_CREDIT_CREDIT_MANAGER, multiQueue);
} else if (acks) {
target = ConsumerTarget_0_8.createAckTarget(this, tag, arguments, _creditManager, multiQueue);
options.add(ConsumerOption.ACQUIRES);
options.add(ConsumerOption.SEES_REQUEUES);
} else {
target = ConsumerTarget_0_8.createNoAckTarget(this, tag, arguments, INFINITE_CREDIT_CREDIT_MANAGER, multiQueue);
options.add(ConsumerOption.ACQUIRES);
options.add(ConsumerOption.SEES_REQUEUES);
}
if (exclusive) {
options.add(ConsumerOption.EXCLUSIVE);
}
// So to keep things straight we put before the call and catch all exceptions from the register and tidy up.
// We add before we register as the Async Delivery process may AutoClose the subscriber
// so calling _cT2QM.remove before we have done put which was after the register succeeded.
// So to keep things straight we put before the call and catch all exceptions from the register and tidy up.
_tag2SubscriptionTargetMap.put(tag, target);
try {
FilterManager filterManager = FilterManagerFactory.createManager(FieldTable.convertToMap(arguments));
if (noLocal) {
if (filterManager == null) {
filterManager = new FilterManager();
}
MessageFilter filter = new NoLocalFilter();
filterManager.add(filter.getName(), filter);
}
if (arguments != null && arguments.containsKey(AMQPFilterTypes.REPLAY_PERIOD.toString())) {
Object value = arguments.get(AMQPFilterTypes.REPLAY_PERIOD.toString());
final long period;
if (value instanceof Number) {
period = ((Number) value).longValue();
} else if (value instanceof String) {
try {
period = Long.parseLong(value.toString());
} catch (NumberFormatException e) {
throw new AMQInvalidArgumentException("Cannot parse value " + value + " as a number for filter " + AMQPFilterTypes.REPLAY_PERIOD.toString());
}
} else {
throw new AMQInvalidArgumentException("Cannot parse value " + value + " as a number for filter " + AMQPFilterTypes.REPLAY_PERIOD.toString());
}
final long startingFrom = System.currentTimeMillis() - (1000l * period);
if (filterManager == null) {
filterManager = new FilterManager();
}
MessageFilter filter = new ArrivalTimeFilter(startingFrom, period == 0);
filterManager.add(filter.getName(), filter);
}
Integer priority = null;
if (arguments != null && arguments.containsKey("x-priority")) {
Object value = arguments.get("x-priority");
if (value instanceof Number) {
priority = ((Number) value).intValue();
} else if (value instanceof String || value instanceof AMQShortString) {
try {
priority = Integer.parseInt(value.toString());
} catch (NumberFormatException e) {
// use default vlaue
}
}
}
for (MessageSource source : sources) {
source.addConsumer(target, filterManager, AMQMessage.class, AMQShortString.toString(tag), options, priority);
}
target.updateNotifyWorkDesired();
} catch (AccessControlException | MessageSource.ExistingExclusiveConsumer | MessageSource.ExistingConsumerPreventsExclusive | MessageSource.QueueDeleted | AMQInvalidArgumentException | MessageSource.ConsumerAccessRefused e) {
_tag2SubscriptionTargetMap.remove(tag);
throw e;
}
return tag;
}
use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class Session_1_0 method getSendingDestination.
public SendingDestination getSendingDestination(final Link_1_0<?, ?> link, final Source source) throws AmqpErrorException {
SendingDestination destination = null;
if (Boolean.TRUE.equals(source.getDynamic())) {
MessageSource tempSource = createDynamicSource(link, source.getDynamicNodeProperties());
if (tempSource != null) {
source.setAddress(_primaryDomain + tempSource.getName());
} else {
throw new AmqpErrorException(AmqpError.INTERNAL_ERROR, "Cannot create dynamic source");
}
}
String address = source.getAddress();
if (address != null) {
if (!address.startsWith("/") && address.contains("/")) {
destination = createExchangeDestination(address, link.getName(), source);
} else {
MessageSource queue = getAddressSpace().getAttainedMessageSource(address);
if (queue != null) {
destination = new StandardSendingDestination(queue);
} else {
destination = createExchangeDestination(address, null, link.getName(), source);
}
}
}
if (destination == null) {
throw new AmqpErrorException(AmqpError.NOT_FOUND, String.format("Could not find destination for source '%s'", source));
}
return destination;
}
use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class ServerSessionDelegate method exchangeBound.
@Override
public void exchangeBound(ServerSession session, ExchangeBound method) {
ExchangeBoundResult result = new ExchangeBoundResult();
NamedAddressSpace addressSpace = getAddressSpace(session);
Exchange<?> exchange;
MessageSource source;
Queue<?> queue;
boolean isDefaultExchange;
if (!nameNullOrEmpty(method.getExchange())) {
isDefaultExchange = false;
exchange = getExchange(addressSpace, method.getExchange());
if (exchange == null) {
result.setExchangeNotFound(true);
}
} else {
isDefaultExchange = true;
exchange = null;
}
if (isDefaultExchange) {
// fake the existence of the "default" exchange for 0-10
if (method.hasQueue()) {
queue = getQueue(session, method.getQueue());
if (queue == null) {
result.setQueueNotFound(true);
} else {
if (method.hasBindingKey()) {
if (!method.getBindingKey().equals(method.getQueue())) {
result.setKeyNotMatched(true);
}
}
}
} else if (method.hasBindingKey()) {
if (getQueue(session, method.getBindingKey()) == null) {
result.setKeyNotMatched(true);
}
}
if (method.hasArguments() && !method.getArguments().isEmpty()) {
result.setArgsNotMatched(true);
}
} else if (method.hasQueue()) {
source = getMessageSource(session, method.getQueue());
if (source == null) {
result.setQueueNotFound(true);
}
if (source == null || source instanceof Queue) {
queue = (Queue<?>) source;
if (exchange != null && queue != null) {
boolean queueMatched = exchange.isBound(queue);
result.setQueueNotMatched(!queueMatched);
if (method.hasBindingKey()) {
if (queueMatched) {
final boolean keyMatched = exchange.isBound(method.getBindingKey(), queue);
result.setKeyNotMatched(!keyMatched);
if (method.hasArguments()) {
if (keyMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments(), queue));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments(), queue));
}
}
} else {
boolean keyMatched = exchange.isBound(method.getBindingKey());
result.setKeyNotMatched(!keyMatched);
if (method.hasArguments()) {
if (keyMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments()));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
}
}
} else if (method.hasArguments()) {
if (queueMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getArguments(), queue));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
}
} else if (exchange != null && method.hasBindingKey()) {
final boolean keyMatched = exchange.isBound(method.getBindingKey());
result.setKeyNotMatched(!keyMatched);
if (method.hasArguments()) {
if (keyMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments()));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
}
}
}
} else if (exchange != null && method.hasBindingKey()) {
final boolean keyMatched = exchange.isBound(method.getBindingKey());
result.setKeyNotMatched(!keyMatched);
if (method.hasArguments()) {
if (keyMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments()));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
}
} else if (exchange != null && method.hasArguments()) {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
session.executionResult((int) method.getId(), result);
}
use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class ServerSessionDelegate method queueQuery.
@Override
public void queueQuery(ServerSession session, QueueQuery method) {
QueueQueryResult result = new QueueQueryResult();
MessageSource source = getMessageSource(session, method.getQueue());
if (source != null) {
result.setQueue(source.getName());
if (source instanceof Queue) {
final Queue<?> queue = (Queue<?>) source;
result.setDurable(queue.isDurable());
result.setExclusive(queue.isExclusive());
result.setAutoDelete(queue.getLifetimePolicy() != LifetimePolicy.PERMANENT);
Map<String, Object> arguments = new LinkedHashMap<>();
Collection<String> availableAttrs = queue.getAvailableAttributes();
for (String attrName : availableAttrs) {
arguments.put(attrName, queue.getAttribute(attrName));
}
result.setArguments(QueueArgumentsConverter.convertModelArgsToWire(arguments));
result.setMessageCount(queue.getQueueDepthMessages());
result.setSubscriberCount(queue.getConsumerCount());
} else {
result.setDurable(true);
result.setExclusive(false);
result.setAutoDelete(false);
result.setMessageCount(Integer.MAX_VALUE);
result.setSubscriberCount(0);
}
}
session.executionResult((int) method.getId(), result);
}
use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class AbstractConsumerTarget method sendNextMessage.
@Override
public boolean sendNextMessage() {
MessageContainer messageContainer = null;
MessageInstanceConsumer consumer = null;
boolean iteratedCompleteList = false;
while (messageContainer == null) {
if (_pullIterator == null || !_pullIterator.hasNext()) {
if (iteratedCompleteList) {
break;
}
iteratedCompleteList = true;
_pullIterator = getConsumers().iterator();
}
if (_pullIterator.hasNext()) {
consumer = _pullIterator.next();
messageContainer = consumer.pullMessage();
}
}
if (messageContainer != null) {
MessageInstance entry = messageContainer.getMessageInstance();
try {
send(consumer, entry, false);
} catch (MessageConversionException mce) {
restoreCredit(entry.getMessage());
final TransactionLogResource owningResource = entry.getOwningResource();
if (owningResource instanceof MessageSource) {
final MessageSource.MessageConversionExceptionHandlingPolicy handlingPolicy = ((MessageSource) owningResource).getMessageConversionExceptionHandlingPolicy();
switch(handlingPolicy) {
case CLOSE:
entry.release(consumer);
throw new ConnectionScopedRuntimeException(String.format("Unable to convert message %s for this consumer", entry.getMessage()), mce);
case ROUTE_TO_ALTERNATE:
if (consumer.acquires()) {
int enqueues = entry.routeToAlternate(null, null);
if (enqueues == 0) {
LOGGER.info("Failed to convert message {} for this consumer because '{}'." + " Message discarded.", entry.getMessage(), mce.getMessage());
} else {
LOGGER.info("Failed to convert message {} for this consumer because '{}'." + " Message routed to alternate.", entry.getMessage(), mce.getMessage());
}
} else {
LOGGER.info("Failed to convert message {} for this browser because '{}'." + " Message skipped.", entry.getMessage(), mce.getMessage());
}
break;
case REJECT:
entry.reject(consumer);
entry.release(consumer);
LOGGER.info("Failed to convert message {} for this consumer because '{}'." + " Message skipped.", entry.getMessage(), mce.getMessage());
break;
default:
throw new ServerScopedRuntimeException("Unrecognised policy " + handlingPolicy);
}
} else {
throw new ConnectionScopedRuntimeException(String.format("Unable to convert message %s for this consumer", entry.getMessage()), mce);
}
} finally {
if (messageContainer.getMessageReference() != null) {
messageContainer.getMessageReference().release();
}
}
return true;
} else {
return false;
}
}
Aggregations