Search in sources :

Example 6 with MessageSource

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;
}
Also used : AMQInvalidArgumentException(org.apache.qpid.server.filter.AMQInvalidArgumentException) ConsumerOption(org.apache.qpid.server.consumer.ConsumerOption) MessageSource(org.apache.qpid.server.message.MessageSource) AccessControlException(java.security.AccessControlException) FilterManager(org.apache.qpid.server.filter.FilterManager) AbstractConfiguredObject(org.apache.qpid.server.model.AbstractConfiguredObject) MessageFilter(org.apache.qpid.server.filter.MessageFilter) ArrivalTimeFilter(org.apache.qpid.server.filter.ArrivalTimeFilter)

Example 7 with MessageSource

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;
}
Also used : MessageSource(org.apache.qpid.server.message.MessageSource) AmqpErrorException(org.apache.qpid.server.protocol.v1_0.type.AmqpErrorException)

Example 8 with MessageSource

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);
}
Also used : NamedAddressSpace(org.apache.qpid.server.model.NamedAddressSpace) MessageSource(org.apache.qpid.server.message.MessageSource) Queue(org.apache.qpid.server.model.Queue)

Example 9 with MessageSource

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);
}
Also used : MessageSource(org.apache.qpid.server.message.MessageSource) AbstractConfiguredObject(org.apache.qpid.server.model.AbstractConfiguredObject) Queue(org.apache.qpid.server.model.Queue) LinkedHashMap(java.util.LinkedHashMap)

Example 10 with MessageSource

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;
    }
}
Also used : MessageInstance(org.apache.qpid.server.message.MessageInstance) MessageConversionException(org.apache.qpid.server.protocol.converter.MessageConversionException) MessageContainer(org.apache.qpid.server.message.MessageContainer) ConnectionScopedRuntimeException(org.apache.qpid.server.util.ConnectionScopedRuntimeException) MessageInstanceConsumer(org.apache.qpid.server.message.MessageInstanceConsumer) MessageSource(org.apache.qpid.server.message.MessageSource) TransactionLogResource(org.apache.qpid.server.store.TransactionLogResource) ServerScopedRuntimeException(org.apache.qpid.server.util.ServerScopedRuntimeException)

Aggregations

MessageSource (org.apache.qpid.server.message.MessageSource)10 Queue (org.apache.qpid.server.model.Queue)6 NamedAddressSpace (org.apache.qpid.server.model.NamedAddressSpace)5 AccessControlException (java.security.AccessControlException)4 AbstractConfiguredObject (org.apache.qpid.server.model.AbstractConfiguredObject)4 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)3 ConsumerOption (org.apache.qpid.server.consumer.ConsumerOption)3 AMQInvalidArgumentException (org.apache.qpid.server.filter.AMQInvalidArgumentException)3 FilterManager (org.apache.qpid.server.filter.FilterManager)3 Collection (java.util.Collection)2 ArrivalTimeFilter (org.apache.qpid.server.filter.ArrivalTimeFilter)2 MessageFilter (org.apache.qpid.server.filter.MessageFilter)2 AmqpErrorException (org.apache.qpid.server.protocol.v1_0.type.AmqpErrorException)2 ConnectionScopedRuntimeException (org.apache.qpid.server.util.ConnectionScopedRuntimeException)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 JMSSelectorFilter (org.apache.qpid.server.filter.JMSSelectorFilter)1