Search in sources :

Example 1 with MessageFilter

use of org.apache.qpid.server.filter.MessageFilter in project qpid-broker-j by apache.

the class AbstractQueue method onOpen.

@Override
protected void onOpen() {
    super.onOpen();
    final Map<String, Object> attributes = getActualAttributes();
    final LinkedHashMap<String, Object> arguments = new LinkedHashMap<>(attributes);
    arguments.put(Queue.EXCLUSIVE, _exclusive);
    arguments.put(Queue.LIFETIME_POLICY, getLifetimePolicy());
    _arguments = Collections.synchronizedMap(arguments);
    _queueHouseKeepingTask = new AdvanceConsumersTask();
    final Set<SessionPrincipal> sessionPrincipals = getSessionPrincipals();
    final AMQPSession<?, ?> session;
    if (sessionPrincipals.isEmpty()) {
        session = null;
    } else {
        final SessionPrincipal sessionPrincipal = sessionPrincipals.iterator().next();
        session = sessionPrincipal.getSession();
    }
    if (session != null) {
        switch(_exclusive) {
            case PRINCIPAL:
                _exclusiveOwner = session.getAMQPConnection().getAuthorizedPrincipal();
                break;
            case CONTAINER:
                _exclusiveOwner = session.getAMQPConnection().getRemoteContainerName();
                break;
            case CONNECTION:
                _exclusiveOwner = session.getAMQPConnection();
                addExclusivityConstraint(session.getAMQPConnection());
                break;
            case SESSION:
                _exclusiveOwner = session;
                addExclusivityConstraint(session);
                break;
            case NONE:
            case LINK:
            case SHARED_SUBSCRIPTION:
                break;
            default:
                throw new ServerScopedRuntimeException("Unknown exclusivity policy: " + _exclusive + " this is a coding error inside Qpid");
        }
    } else if (_exclusive == ExclusivityPolicy.PRINCIPAL) {
        if (attributes.get(Queue.OWNER) != null) {
            final String owner = String.valueOf(attributes.get(Queue.OWNER));
            Principal ownerPrincipal;
            try {
                ownerPrincipal = new GenericPrincipal(owner);
            } catch (IllegalArgumentException e) {
                ownerPrincipal = new GenericPrincipal(owner + "@('')");
            }
            _exclusiveOwner = new AuthenticatedPrincipal(ownerPrincipal);
        }
    } else if (_exclusive == ExclusivityPolicy.CONTAINER) {
        if (attributes.get(Queue.OWNER) != null) {
            _exclusiveOwner = String.valueOf(attributes.get(Queue.OWNER));
        }
    }
    if (getLifetimePolicy() == LifetimePolicy.DELETE_ON_CONNECTION_CLOSE) {
        if (session != null) {
            addLifetimeConstraint(session.getAMQPConnection());
        } else {
            throw new IllegalArgumentException("Queues created with a lifetime policy of " + getLifetimePolicy() + " must be created from a connection.");
        }
    } else if (getLifetimePolicy() == LifetimePolicy.DELETE_ON_SESSION_END) {
        if (session != null) {
            addLifetimeConstraint(session);
        } else {
            throw new IllegalArgumentException("Queues created with a lifetime policy of " + getLifetimePolicy() + " must be created from a connection.");
        }
    } else if (getLifetimePolicy() == LifetimePolicy.DELETE_ON_CREATING_LINK_CLOSE) {
        if (_creatingLinkInfo != null) {
            final LinkModel link;
            if (_creatingLinkInfo.isSendingLink()) {
                link = _virtualHost.getSendingLink(_creatingLinkInfo.getRemoteContainerId(), _creatingLinkInfo.getLinkName());
            } else {
                link = _virtualHost.getReceivingLink(_creatingLinkInfo.getRemoteContainerId(), _creatingLinkInfo.getLinkName());
            }
            addLifetimeConstraint(link);
        } else {
            throw new IllegalArgumentException("Queues created with a lifetime policy of " + getLifetimePolicy() + " must be created from a AMQP 1.0 link.");
        }
    }
    switch(getMessageGroupType()) {
        case NONE:
            _messageGroupManager = null;
            break;
        case STANDARD:
            _messageGroupManager = new AssignedConsumerMessageGroupManager(getMessageGroupKeyOverride(), getMaximumDistinctGroups());
            break;
        case SHARED_GROUPS:
            _messageGroupManager = new DefinedGroupMessageGroupManager(getMessageGroupKeyOverride(), getMessageGroupDefaultGroup(), this);
            break;
        default:
            throw new IllegalArgumentException("Unknown messageGroupType type " + _messageGroupType);
    }
    _mimeTypeToFileExtension = getContextValue(Map.class, MAP_OF_STRING_STRING, MIME_TYPE_TO_FILE_EXTENSION);
    _messageConversionExceptionHandlingPolicy = getContextValue(MessageConversionExceptionHandlingPolicy.class, MESSAGE_CONVERSION_EXCEPTION_HANDLING_POLICY);
    _flowToDiskThreshold = getAncestor(Broker.class).getFlowToDiskThreshold();
    if (_defaultFilters != null) {
        final QpidServiceLoader qpidServiceLoader = new QpidServiceLoader();
        final Map<String, MessageFilterFactory> messageFilterFactories = qpidServiceLoader.getInstancesByType(MessageFilterFactory.class);
        for (Map.Entry<String, Map<String, List<String>>> entry : _defaultFilters.entrySet()) {
            final String name = String.valueOf(entry.getKey());
            final Map<String, List<String>> filterValue = entry.getValue();
            if (filterValue.size() == 1) {
                final String filterTypeName = String.valueOf(filterValue.keySet().iterator().next());
                final MessageFilterFactory filterFactory = messageFilterFactories.get(filterTypeName);
                if (filterFactory != null) {
                    final List<String> filterArguments = filterValue.values().iterator().next();
                    // check the arguments are valid
                    filterFactory.newInstance(filterArguments);
                    _defaultFiltersMap.put(name, new Callable<MessageFilter>() {

                        @Override
                        public MessageFilter call() {
                            return filterFactory.newInstance(filterArguments);
                        }
                    });
                } else {
                    throw new IllegalArgumentException("Unknown filter type " + filterTypeName + ", known types are: " + messageFilterFactories.keySet());
                }
            } else {
                throw new IllegalArgumentException("Filter value should be a map with one entry, having the type as key and the value being the filter arguments, not " + filterValue);
            }
        }
    }
    if (isHoldOnPublishEnabled()) {
        _holdMethods.add(new HoldMethod() {

            @Override
            public boolean isHeld(final MessageReference<?> messageReference, final long evaluationTime) {
                return messageReference.getMessage().getMessageHeader().getNotValidBefore() >= evaluationTime;
            }
        });
    }
    if (getAlternateBinding() != null) {
        final String alternateDestination = getAlternateBinding().getDestination();
        _alternateBindingDestination = getOpenedMessageDestination(alternateDestination);
        if (_alternateBindingDestination != null) {
            _alternateBindingDestination.addReference(this);
        } else {
            LOGGER.warn("Cannot find alternate binding destination '{}' for queue '{}'", alternateDestination, toString());
        }
    }
    createOverflowPolicyHandlers(_overflowPolicy);
    updateAlertChecks();
}
Also used : QpidServiceLoader(org.apache.qpid.server.plugin.QpidServiceLoader) SessionPrincipal(org.apache.qpid.server.connection.SessionPrincipal) LinkModel(org.apache.qpid.server.protocol.LinkModel) LinkedHashMap(java.util.LinkedHashMap) ServerScopedRuntimeException(org.apache.qpid.server.util.ServerScopedRuntimeException) AuthenticatedPrincipal(org.apache.qpid.server.security.auth.AuthenticatedPrincipal) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) MessageFilterFactory(org.apache.qpid.server.plugin.MessageFilterFactory) GenericPrincipal(org.apache.qpid.server.model.preferences.GenericPrincipal) MessageFilter(org.apache.qpid.server.filter.MessageFilter) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) GenericPrincipal(org.apache.qpid.server.model.preferences.GenericPrincipal) SessionPrincipal(org.apache.qpid.server.connection.SessionPrincipal) Principal(java.security.Principal) AuthenticatedPrincipal(org.apache.qpid.server.security.auth.AuthenticatedPrincipal)

Example 2 with MessageFilter

use of org.apache.qpid.server.filter.MessageFilter in project qpid-broker-j by apache.

the class ServerSessionDelegate method messageSubscribe.

@Override
public void messageSubscribe(ServerSession session, MessageSubscribe method) {
    /*
          TODO - work around broken Python tests
          Correct code should read like
          if not hasAcceptMode() exception ILLEGAL_ARGUMENT "Accept-mode not supplied"
          else if not method.hasAcquireMode() exception ExecutionErrorCode.ILLEGAL_ARGUMENT, "Acquire-mode not supplied"
        */
    if (!method.hasAcceptMode()) {
        method.setAcceptMode(MessageAcceptMode.EXPLICIT);
    }
    if (!method.hasAcquireMode()) {
        method.setAcquireMode(MessageAcquireMode.PRE_ACQUIRED);
    }
    if (!method.hasQueue()) {
        exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "queue not supplied");
    } else {
        String destination = method.getDestination();
        if (destination == null) {
            exception(session, method, ExecutionErrorCode.INVALID_ARGUMENT, "Subscriber must provide a destination. The protocol specification marking the destination argument as optional is considered a mistake.");
        } else if (session.getSubscription(destination) != null) {
            exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Subscription already exists with destination '" + destination + "'");
        } else {
            String queueName = method.getQueue();
            NamedAddressSpace addressSpace = getAddressSpace(session);
            final Collection<MessageSource> sources = new HashSet<>();
            final MessageSource queue = addressSpace.getAttainedMessageSource(queueName);
            if (method.getArguments() != null && method.getArguments().get("x-multiqueue") instanceof Collection) {
                for (Object object : (Collection<Object>) method.getArguments().get("x-multiqueue")) {
                    String sourceName = String.valueOf(object);
                    sourceName = sourceName.trim();
                    if (sourceName.length() != 0) {
                        MessageSource source = addressSpace.getAttainedMessageSource(sourceName);
                        if (source == null) {
                            sources.clear();
                            break;
                        } else {
                            sources.add(source);
                        }
                    }
                }
                queueName = method.getArguments().get("x-multiqueue").toString();
            } else if (queue != null) {
                sources.add(queue);
            }
            if (sources.isEmpty()) {
                exception(session, method, ExecutionErrorCode.NOT_FOUND, "Queue: " + queueName + " not found");
            } else if (!verifySessionAccess(session, sources)) {
                exception(session, method, ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session");
            } else {
                ProtocolEngine protocolEngine = getServerConnection(session).getAmqpConnection();
                FlowCreditManager_0_10 creditManager = new WindowCreditManager(0L, 0L);
                FilterManager filterManager = null;
                try {
                    filterManager = FilterManagerFactory.createManager(method.getArguments());
                } catch (AMQInvalidArgumentException amqe) {
                    exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "Exception Creating FilterManager");
                    return;
                }
                if (method.hasArguments() && method.getArguments().containsKey(AMQPFilterTypes.REPLAY_PERIOD.toString())) {
                    Object value = method.getArguments().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) {
                            exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "Cannot parse value " + value + " as a number for filter " + AMQPFilterTypes.REPLAY_PERIOD.toString());
                            return;
                        }
                    } else {
                        exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "Cannot parse value " + value + " as a number for filter " + AMQPFilterTypes.REPLAY_PERIOD.toString());
                        return;
                    }
                    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);
                }
                boolean multiQueue = sources.size() > 1;
                ConsumerTarget_0_10 target = new ConsumerTarget_0_10(session, destination, method.getAcceptMode(), method.getAcquireMode(), MessageFlowMode.WINDOW, creditManager, method.getArguments(), multiQueue);
                Integer priority = null;
                if (method.hasArguments() && method.getArguments().containsKey("x-priority")) {
                    Object value = method.getArguments().get("x-priority");
                    if (value instanceof Number) {
                        priority = ((Number) value).intValue();
                    } else if (value instanceof String) {
                        try {
                            priority = Integer.parseInt(value.toString());
                        } catch (NumberFormatException e) {
                        }
                    }
                }
                session.register(destination, target);
                try {
                    EnumSet<ConsumerOption> options = EnumSet.noneOf(ConsumerOption.class);
                    if (method.getAcquireMode() == MessageAcquireMode.PRE_ACQUIRED) {
                        options.add(ConsumerOption.ACQUIRES);
                    }
                    if (method.getAcquireMode() != MessageAcquireMode.NOT_ACQUIRED || method.getAcceptMode() == MessageAcceptMode.EXPLICIT) {
                        options.add(ConsumerOption.SEES_REQUEUES);
                    }
                    if (method.getExclusive()) {
                        options.add(ConsumerOption.EXCLUSIVE);
                    }
                    for (MessageSource source : sources) {
                        source.addConsumer(target, filterManager, MessageTransferMessage.class, destination, options, priority);
                    }
                    target.updateNotifyWorkDesired();
                } catch (Queue.ExistingExclusiveConsumer existing) {
                    exception(session, method, ExecutionErrorCode.RESOURCE_LOCKED, "Queue has an exclusive consumer");
                } catch (Queue.ExistingConsumerPreventsExclusive exclusive) {
                    exception(session, method, ExecutionErrorCode.RESOURCE_LOCKED, "Queue has an existing consumer - can't subscribe exclusively");
                } catch (AccessControlException e) {
                    exception(session, method, ExecutionErrorCode.UNAUTHORIZED_ACCESS, e.getMessage());
                } catch (MessageSource.ConsumerAccessRefused consumerAccessRefused) {
                    exception(session, method, ExecutionErrorCode.RESOURCE_LOCKED, "Queue has an incompatible exclusivity policy");
                } catch (MessageSource.QueueDeleted queueDeleted) {
                    exception(session, method, ExecutionErrorCode.NOT_FOUND, "Queue was deleted");
                }
            }
        }
    }
}
Also used : ProtocolEngine(org.apache.qpid.server.transport.ProtocolEngine) AMQInvalidArgumentException(org.apache.qpid.server.filter.AMQInvalidArgumentException) ConsumerOption(org.apache.qpid.server.consumer.ConsumerOption) FilterManager(org.apache.qpid.server.filter.FilterManager) Queue(org.apache.qpid.server.model.Queue) ArrivalTimeFilter(org.apache.qpid.server.filter.ArrivalTimeFilter) NamedAddressSpace(org.apache.qpid.server.model.NamedAddressSpace) MessageSource(org.apache.qpid.server.message.MessageSource) AccessControlException(java.security.AccessControlException) Collection(java.util.Collection) AbstractConfiguredObject(org.apache.qpid.server.model.AbstractConfiguredObject) MessageFilter(org.apache.qpid.server.filter.MessageFilter)

Example 3 with MessageFilter

use of org.apache.qpid.server.filter.MessageFilter in project qpid-broker-j by apache.

the class AbstractQueue method addConsumerInternal.

private <T extends ConsumerTarget<T>> QueueConsumerImpl<T> addConsumerInternal(final T target, FilterManager filters, final Class<? extends ServerMessage> messageClass, final String consumerName, EnumSet<ConsumerOption> optionSet, final Integer priority) throws ExistingExclusiveConsumer, ConsumerAccessRefused, ExistingConsumerPreventsExclusive, QueueDeleted {
    if (isDeleted()) {
        throw new QueueDeleted();
    }
    if (hasExclusiveConsumer()) {
        throw new ExistingExclusiveConsumer();
    }
    Object exclusiveOwner = _exclusiveOwner;
    final AMQPSession<?, T> session = target.getSession();
    switch(_exclusive) {
        case CONNECTION:
            if (exclusiveOwner == null) {
                exclusiveOwner = session.getAMQPConnection();
                addExclusivityConstraint(session.getAMQPConnection());
            } else {
                if (exclusiveOwner != session.getAMQPConnection()) {
                    throw new ConsumerAccessRefused();
                }
            }
            break;
        case SESSION:
            if (exclusiveOwner == null) {
                exclusiveOwner = session;
                addExclusivityConstraint(session);
            } else {
                if (exclusiveOwner != session) {
                    throw new ConsumerAccessRefused();
                }
            }
            break;
        case LINK:
            if (getConsumerCount() != 0) {
                throw new ConsumerAccessRefused();
            }
            break;
        case PRINCIPAL:
            Principal currentAuthorizedPrincipal = session.getAMQPConnection().getAuthorizedPrincipal();
            if (exclusiveOwner == null) {
                exclusiveOwner = currentAuthorizedPrincipal;
            } else {
                if (!Objects.equals(((Principal) exclusiveOwner).getName(), currentAuthorizedPrincipal.getName())) {
                    throw new ConsumerAccessRefused();
                }
            }
            break;
        case CONTAINER:
            if (exclusiveOwner == null) {
                exclusiveOwner = session.getAMQPConnection().getRemoteContainerName();
            } else {
                if (!exclusiveOwner.equals(session.getAMQPConnection().getRemoteContainerName())) {
                    throw new ConsumerAccessRefused();
                }
            }
            break;
        case SHARED_SUBSCRIPTION:
            break;
        case NONE:
            break;
        default:
            throw new ServerScopedRuntimeException("Unknown exclusivity policy " + _exclusive);
    }
    boolean exclusive = optionSet.contains(ConsumerOption.EXCLUSIVE);
    boolean isTransient = optionSet.contains(ConsumerOption.TRANSIENT);
    if (_noLocal && !optionSet.contains(ConsumerOption.NO_LOCAL)) {
        optionSet = EnumSet.copyOf(optionSet);
        optionSet.add(ConsumerOption.NO_LOCAL);
    }
    if (exclusive && getConsumerCount() != 0) {
        throw new ExistingConsumerPreventsExclusive();
    }
    if (!_defaultFiltersMap.isEmpty()) {
        if (filters == null) {
            filters = new FilterManager();
        }
        for (Map.Entry<String, Callable<MessageFilter>> filter : _defaultFiltersMap.entrySet()) {
            if (!filters.hasFilter(filter.getKey())) {
                MessageFilter f;
                try {
                    f = filter.getValue().call();
                } catch (Exception e) {
                    if (e instanceof RuntimeException) {
                        throw (RuntimeException) e;
                    } else {
                        // Should never happen
                        throw new ServerScopedRuntimeException(e);
                    }
                }
                filters.add(filter.getKey(), f);
            }
        }
    }
    if (_ensureNondestructiveConsumers) {
        optionSet = EnumSet.copyOf(optionSet);
        optionSet.removeAll(EnumSet.of(ConsumerOption.SEES_REQUEUES, ConsumerOption.ACQUIRES));
    }
    QueueConsumerImpl<T> consumer = new QueueConsumerImpl<>(this, target, consumerName, filters, messageClass, optionSet, priority);
    _exclusiveOwner = exclusiveOwner;
    if (exclusive && !isTransient) {
        _exclusiveSubscriber = consumer;
    }
    QueueContext queueContext;
    if (filters == null || !filters.startAtTail()) {
        queueContext = new QueueContext(getEntries().getHead());
    } else {
        queueContext = new QueueContext(getEntries().getTail());
    }
    consumer.setQueueContext(queueContext);
    if (_maximumLiveConsumers > 0 && !incrementNumberOfLiveConsumersIfApplicable()) {
        consumer.setNonLive(true);
    }
    _queueConsumerManager.addConsumer(consumer);
    if (consumer.isNotifyWorkDesired()) {
        _activeSubscriberCount.incrementAndGet();
    }
    childAdded(consumer);
    consumer.addChangeListener(_deletedChildListener);
    session.consumerAdded(consumer);
    addChangeListener(new AbstractConfigurationChangeListener() {

        @Override
        public void childRemoved(final ConfiguredObject<?> object, final ConfiguredObject<?> child) {
            if (child.equals(consumer)) {
                session.consumerRemoved(consumer);
                removeChangeListener(this);
            }
        }
    });
    return consumer;
}
Also used : Callable(java.util.concurrent.Callable) SelectorParsingException(org.apache.qpid.server.filter.SelectorParsingException) MessageDestinationIsAlternateException(org.apache.qpid.server.virtualhost.MessageDestinationIsAlternateException) ParseException(org.apache.qpid.server.filter.selector.ParseException) VirtualHostUnavailableException(org.apache.qpid.server.virtualhost.VirtualHostUnavailableException) ConnectionScopedRuntimeException(org.apache.qpid.server.util.ConnectionScopedRuntimeException) UnknownAlternateBindingException(org.apache.qpid.server.virtualhost.UnknownAlternateBindingException) MessageDeletedException(org.apache.qpid.server.message.MessageDeletedException) IOException(java.io.IOException) AccessControlException(java.security.AccessControlException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ServerScopedRuntimeException(org.apache.qpid.server.util.ServerScopedRuntimeException) IllegalConfigurationException(org.apache.qpid.server.configuration.IllegalConfigurationException) ServerScopedRuntimeException(org.apache.qpid.server.util.ServerScopedRuntimeException) FilterManager(org.apache.qpid.server.filter.FilterManager) ConnectionScopedRuntimeException(org.apache.qpid.server.util.ConnectionScopedRuntimeException) ServerScopedRuntimeException(org.apache.qpid.server.util.ServerScopedRuntimeException) MessageFilter(org.apache.qpid.server.filter.MessageFilter) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) GenericPrincipal(org.apache.qpid.server.model.preferences.GenericPrincipal) SessionPrincipal(org.apache.qpid.server.connection.SessionPrincipal) Principal(java.security.Principal) AuthenticatedPrincipal(org.apache.qpid.server.security.auth.AuthenticatedPrincipal)

Example 4 with MessageFilter

use of org.apache.qpid.server.filter.MessageFilter in project qpid-broker-j by apache.

the class QueueConsumerImpl method createAttributeMap.

private static Map<String, Object> createAttributeMap(final AMQPSession<?, ?> session, String linkName, FilterManager filters, EnumSet<ConsumerOption> optionSet, Integer priority) {
    Map<String, Object> attributes = new HashMap<String, Object>();
    attributes.put(ID, UUID.randomUUID());
    String name = session.getAMQPConnection().getConnectionId() + "|" + session.getChannelId() + "|" + linkName;
    attributes.put(NAME, name);
    attributes.put(EXCLUSIVE, optionSet.contains(ConsumerOption.EXCLUSIVE));
    attributes.put(NO_LOCAL, optionSet.contains(ConsumerOption.NO_LOCAL));
    attributes.put(DISTRIBUTION_MODE, optionSet.contains(ConsumerOption.ACQUIRES) ? "MOVE" : "COPY");
    attributes.put(DURABLE, optionSet.contains(ConsumerOption.DURABLE));
    attributes.put(LIFETIME_POLICY, LifetimePolicy.DELETE_ON_SESSION_END);
    if (priority != null) {
        attributes.put(PRIORITY, priority);
    }
    if (filters != null) {
        Iterator<MessageFilter> iter = filters.filters();
        while (iter.hasNext()) {
            MessageFilter filter = iter.next();
            if (filter instanceof JMSSelectorFilter) {
                attributes.put(SELECTOR, ((JMSSelectorFilter) filter).getSelector());
                break;
            }
        }
    }
    return attributes;
}
Also used : JMSSelectorFilter(org.apache.qpid.server.filter.JMSSelectorFilter) HashMap(java.util.HashMap) AbstractConfiguredObject(org.apache.qpid.server.model.AbstractConfiguredObject) MessageFilter(org.apache.qpid.server.filter.MessageFilter)

Example 5 with MessageFilter

use of org.apache.qpid.server.filter.MessageFilter 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 = AMQShortString.createAMQShortString("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)

Aggregations

MessageFilter (org.apache.qpid.server.filter.MessageFilter)5 AccessControlException (java.security.AccessControlException)3 FilterManager (org.apache.qpid.server.filter.FilterManager)3 AbstractConfiguredObject (org.apache.qpid.server.model.AbstractConfiguredObject)3 Principal (java.security.Principal)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ConcurrentMap (java.util.concurrent.ConcurrentMap)2 SessionPrincipal (org.apache.qpid.server.connection.SessionPrincipal)2 ConsumerOption (org.apache.qpid.server.consumer.ConsumerOption)2 AMQInvalidArgumentException (org.apache.qpid.server.filter.AMQInvalidArgumentException)2 ArrivalTimeFilter (org.apache.qpid.server.filter.ArrivalTimeFilter)2 MessageSource (org.apache.qpid.server.message.MessageSource)2 GenericPrincipal (org.apache.qpid.server.model.preferences.GenericPrincipal)2 AuthenticatedPrincipal (org.apache.qpid.server.security.auth.AuthenticatedPrincipal)2 ServerScopedRuntimeException (org.apache.qpid.server.util.ServerScopedRuntimeException)2 IOException (java.io.IOException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 ArrayList (java.util.ArrayList)1