Search in sources :

Example 1 with RoutingResult

use of org.apache.qpid.server.message.RoutingResult in project qpid-broker-j by apache.

the class AbstractExchange method route.

@Override
public <M extends ServerMessage<? extends StorableMessageMetaData>> RoutingResult<M> route(final M message, final String routingAddress, final InstanceProperties instanceProperties) {
    if (_virtualHost.getState() != State.ACTIVE) {
        throw new VirtualHostUnavailableException(this._virtualHost);
    }
    final RoutingResult<M> routingResult = new RoutingResult<>(message);
    Map<AbstractExchange<?>, Set<String>> currentThreadMap = CURRENT_ROUTING.get();
    boolean topLevel = currentThreadMap == null;
    try {
        if (topLevel) {
            currentThreadMap = new HashMap<>();
            CURRENT_ROUTING.set(currentThreadMap);
        }
        Set<String> existingRoutes = currentThreadMap.get(this);
        if (existingRoutes == null) {
            currentThreadMap.put(this, Collections.singleton(routingAddress));
        } else if (existingRoutes.contains(routingAddress)) {
            return routingResult;
        } else {
            existingRoutes = new HashSet<>(existingRoutes);
            existingRoutes.add(routingAddress);
            currentThreadMap.put(this, existingRoutes);
        }
        _receivedMessageCount.incrementAndGet();
        _receivedMessageSize.addAndGet(message.getSizeIncludingHeader());
        doRoute(message, routingAddress, instanceProperties, routingResult);
        if (!routingResult.hasRoutes()) {
            MessageDestination alternateBindingDestination = getAlternateBindingDestination();
            if (alternateBindingDestination != null) {
                routingResult.add(alternateBindingDestination.route(message, routingAddress, instanceProperties));
            }
        }
        if (routingResult.hasRoutes()) {
            _routedMessageCount.incrementAndGet();
            _routedMessageSize.addAndGet(message.getSizeIncludingHeader());
        } else {
            _droppedMessageCount.incrementAndGet();
            _droppedMessageSize.addAndGet(message.getSizeIncludingHeader());
        }
        return routingResult;
    } finally {
        if (topLevel) {
            CURRENT_ROUTING.set(null);
        }
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) MessageDestination(org.apache.qpid.server.message.MessageDestination) RoutingResult(org.apache.qpid.server.message.RoutingResult) VirtualHostUnavailableException(org.apache.qpid.server.virtualhost.VirtualHostUnavailableException) HashSet(java.util.HashSet)

Example 2 with RoutingResult

use of org.apache.qpid.server.message.RoutingResult in project qpid-broker-j by apache.

the class DefaultDestination method route.

@Override
public <M extends ServerMessage<? extends StorableMessageMetaData>> RoutingResult<M> route(M message, String routingAddress, InstanceProperties instanceProperties) {
    RoutingResult<M> result = new RoutingResult<>(message);
    DestinationAddress destinationAddress = new DestinationAddress(_virtualHost, routingAddress);
    MessageDestination messageDestination = destinationAddress.getMessageDestination();
    if (messageDestination != null) {
        result.add(messageDestination.route(message, destinationAddress.getRoutingKey(), instanceProperties));
    }
    return result;
}
Also used : RoutingResult(org.apache.qpid.server.message.RoutingResult) MessageDestination(org.apache.qpid.server.message.MessageDestination) DestinationAddress(org.apache.qpid.server.model.DestinationAddress)

Example 3 with RoutingResult

use of org.apache.qpid.server.message.RoutingResult in project qpid-broker-j by apache.

the class NodeReceivingDestination method send.

@Override
public void send(final ServerMessage<?> message, final ServerTransaction txn, final SecurityToken securityToken) throws UnroutableMessageException {
    final String routingAddress = "".equals(_routingAddress) ? getRoutingAddress(message) : _routingAddress;
    _destination.authorisePublish(securityToken, Collections.singletonMap("routingKey", routingAddress));
    final InstanceProperties instanceProperties = new InstanceProperties() {

        @Override
        public Object getProperty(final Property prop) {
            switch(prop) {
                case MANDATORY:
                    return false;
                case REDELIVERED:
                    return false;
                case PERSISTENT:
                    return message.isPersistent();
                case IMMEDIATE:
                    return false;
                case EXPIRATION:
                    return message.getExpiration();
            }
            return null;
        }
    };
    RoutingResult result = _destination.route(message, routingAddress, instanceProperties);
    final int enqueues = result.send(txn, null);
    if (enqueues == 0) {
        if (!_discardUnroutable) {
            final String errorMessage;
            final AmqpError errorCode;
            if (result.isRejected()) {
                if (result.containsReject(RejectType.LIMIT_EXCEEDED)) {
                    errorCode = AmqpError.RESOURCE_LIMIT_EXCEEDED;
                } else if (result.containsReject(RejectType.PRECONDITION_FAILED)) {
                    errorCode = AmqpError.PRECONDITION_FAILED;
                } else {
                    errorCode = AmqpError.ILLEGAL_STATE;
                }
                errorMessage = result.getRejectReason();
            } else {
                errorCode = AmqpError.NOT_FOUND;
                errorMessage = String.format("Unknown destination '%s'", routingAddress);
            }
            throw new UnroutableMessageException(errorCode, errorMessage);
        } else {
            _eventLogger.message(ExchangeMessages.DISCARDMSG(_destination.getName(), routingAddress));
        }
    }
}
Also used : RoutingResult(org.apache.qpid.server.message.RoutingResult) InstanceProperties(org.apache.qpid.server.message.InstanceProperties) AmqpError(org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError)

Example 4 with RoutingResult

use of org.apache.qpid.server.message.RoutingResult in project qpid-broker-j by apache.

the class AMQChannelTest method testPublishContentHeaderWhenMessageAuthorizationSucceeds.

public void testPublishContentHeaderWhenMessageAuthorizationSucceeds() throws Exception {
    when(_virtualHost.getDefaultDestination()).thenReturn(_messageDestination);
    when(_virtualHost.getMessageStore()).thenReturn(new NullMessageStore() {

        @Override
        public <T extends StorableMessageMetaData> MessageHandle<T> addMessage(final T metaData) {
            MessageHandle messageHandle = new StoredMemoryMessage(1, metaData);
            return messageHandle;
        }
    });
    final ArgumentCaptor<ServerMessage> messageCaptor = ArgumentCaptor.forClass(ServerMessage.class);
    doAnswer(new Answer() {

        @Override
        public Object answer(final InvocationOnMock invocation) throws Throwable {
            ServerMessage message = messageCaptor.getValue();
            return new RoutingResult(message);
        }
    }).when(_messageDestination).route(messageCaptor.capture(), eq(ROUTING_KEY.toString()), any(InstanceProperties.class));
    AMQChannel channel = new AMQChannel(_amqConnection, 1, _virtualHost.getMessageStore());
    BasicContentHeaderProperties properties = new BasicContentHeaderProperties();
    properties.setUserId(_amqConnection.getAuthorizedPrincipal().getName());
    channel.receiveBasicPublish(AMQShortString.EMPTY_STRING, ROUTING_KEY, false, false);
    channel.receiveMessageHeader(properties, 0);
    verify(_messageDestination).route((ServerMessage) any(), eq(ROUTING_KEY.toString()), any(InstanceProperties.class));
}
Also used : InstanceProperties(org.apache.qpid.server.message.InstanceProperties) ServerMessage(org.apache.qpid.server.message.ServerMessage) StoredMemoryMessage(org.apache.qpid.server.store.StoredMemoryMessage) NullMessageStore(org.apache.qpid.server.store.NullMessageStore) BasicContentHeaderProperties(org.apache.qpid.server.protocol.v0_8.transport.BasicContentHeaderProperties) RoutingResult(org.apache.qpid.server.message.RoutingResult) Answer(org.mockito.stubbing.Answer) Mockito.doAnswer(org.mockito.Mockito.doAnswer) MessageHandle(org.apache.qpid.server.store.MessageHandle) InvocationOnMock(org.mockito.invocation.InvocationOnMock)

Example 5 with RoutingResult

use of org.apache.qpid.server.message.RoutingResult in project qpid-broker-j by apache.

the class ServerSessionDelegate method messageTransfer.

@Override
public void messageTransfer(ServerSession ssn, final MessageTransfer xfr) {
    try {
        if (ssn.blockingTimeoutExceeded()) {
            getEventLogger(ssn).message(ChannelMessages.FLOW_CONTROL_IGNORED());
            ssn.close(ErrorCodes.MESSAGE_TOO_LARGE, "Session flow control was requested, but not enforced by sender");
        } else if (xfr.getBodySize() > ssn.getConnection().getMaxMessageSize()) {
            exception(ssn, xfr, ExecutionErrorCode.RESOURCE_LIMIT_EXCEEDED, "Message size of " + xfr.getBodySize() + " greater than allowed maximum of " + ssn.getConnection().getMaxMessageSize());
        } else {
            final MessageDestination destination = getDestinationForMessage(ssn, xfr);
            final DeliveryProperties delvProps = xfr.getHeader() == null ? null : xfr.getHeader().getDeliveryProperties();
            if (delvProps != null && delvProps.hasTtl() && !delvProps.hasExpiration()) {
                delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl());
            }
            final MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr);
            final NamedAddressSpace virtualHost = getAddressSpace(ssn);
            try {
                ssn.getAMQPConnection().checkAuthorizedMessagePrincipal(getMessageUserId(xfr));
                ssn.authorisePublish(destination, messageMetaData.getRoutingKey(), messageMetaData.isImmediate(), ssn.getAMQPConnection().getLastReadTime());
            } catch (AccessControlException e) {
                ExecutionErrorCode errorCode = ExecutionErrorCode.UNAUTHORIZED_ACCESS;
                exception(ssn, xfr, errorCode, e.getMessage());
                return;
            }
            final MessageStore store = virtualHost.getMessageStore();
            final StoredMessage<MessageMetaData_0_10> storeMessage = createStoreMessage(xfr, messageMetaData, store);
            final MessageTransferMessage message = new MessageTransferMessage(storeMessage, ssn.getReference());
            MessageReference<MessageTransferMessage> reference = message.newReference();
            try {
                final InstanceProperties instanceProperties = new InstanceProperties() {

                    @Override
                    public Object getProperty(final Property prop) {
                        switch(prop) {
                            case EXPIRATION:
                                return message.getExpiration();
                            case IMMEDIATE:
                                return message.isImmediate();
                            case MANDATORY:
                                return (delvProps == null || !delvProps.getDiscardUnroutable()) && xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT;
                            case PERSISTENT:
                                return message.isPersistent();
                            case REDELIVERED:
                                return delvProps.getRedelivered();
                        }
                        return null;
                    }
                };
                RoutingResult<MessageTransferMessage> routingResult = ssn.enqueue(message, instanceProperties, destination);
                boolean explictlyRejected = routingResult.containsReject(RejectType.LIMIT_EXCEEDED);
                if (!routingResult.hasRoutes() || explictlyRejected) {
                    boolean closeWhenNoRoute = ssn.getAMQPConnection().getPort().getCloseWhenNoRoute();
                    boolean discardUnroutable = delvProps != null && delvProps.getDiscardUnroutable();
                    if (!discardUnroutable && xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT) {
                        RangeSet rejects = RangeSetFactory.createRangeSet();
                        rejects.add(xfr.getId());
                        MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable");
                        ssn.invoke(reject);
                    } else if (!discardUnroutable && closeWhenNoRoute && explictlyRejected) {
                        ExecutionErrorCode code = ExecutionErrorCode.RESOURCE_LIMIT_EXCEEDED;
                        String errorMessage = String.format("No route for message with destination '%s' and routing key '%s' : %s", xfr.getDestination(), message.getInitialRoutingAddress(), routingResult.getRejectReason());
                        ExecutionException ex = new ExecutionException();
                        ex.setErrorCode(code);
                        ex.setDescription(errorMessage);
                        ssn.invoke(ex);
                        ssn.close(ErrorCodes.RESOURCE_ERROR, errorMessage);
                        return;
                    } else {
                        getEventLogger(ssn).message(ExchangeMessages.DISCARDMSG(destination.getName(), messageMetaData.getRoutingKey()));
                    }
                }
                // TODO: we currently do not send MessageAccept when AcceptMode is EXPLICIT
                if (ssn.isTransactional()) {
                    ssn.processed(xfr);
                } else {
                    ssn.recordFuture(Futures.immediateFuture(null), new CommandProcessedAction(ssn, xfr));
                }
            } catch (VirtualHostUnavailableException e) {
                getServerConnection(ssn).sendConnectionCloseAsync(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
            } finally {
                reference.release();
            }
        }
    } finally {
        xfr.dispose();
    }
}
Also used : MessageStore(org.apache.qpid.server.store.MessageStore) MessageDestination(org.apache.qpid.server.message.MessageDestination) InstanceProperties(org.apache.qpid.server.message.InstanceProperties) NamedAddressSpace(org.apache.qpid.server.model.NamedAddressSpace) AccessControlException(java.security.AccessControlException) MessageReference(org.apache.qpid.server.message.MessageReference) RoutingResult(org.apache.qpid.server.message.RoutingResult) VirtualHostUnavailableException(org.apache.qpid.server.virtualhost.VirtualHostUnavailableException) StoredMessage(org.apache.qpid.server.store.StoredMessage) AbstractConfiguredObject(org.apache.qpid.server.model.AbstractConfiguredObject)

Aggregations

RoutingResult (org.apache.qpid.server.message.RoutingResult)7 MessageDestination (org.apache.qpid.server.message.MessageDestination)4 InstanceProperties (org.apache.qpid.server.message.InstanceProperties)3 ServerMessage (org.apache.qpid.server.message.ServerMessage)2 VirtualHostUnavailableException (org.apache.qpid.server.virtualhost.VirtualHostUnavailableException)2 AccessControlException (java.security.AccessControlException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 MessageReference (org.apache.qpid.server.message.MessageReference)1 AbstractConfiguredObject (org.apache.qpid.server.model.AbstractConfiguredObject)1 DestinationAddress (org.apache.qpid.server.model.DestinationAddress)1 NamedAddressSpace (org.apache.qpid.server.model.NamedAddressSpace)1 BasicContentHeaderProperties (org.apache.qpid.server.protocol.v0_8.transport.BasicContentHeaderProperties)1 AmqpError (org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError)1 MessageHandle (org.apache.qpid.server.store.MessageHandle)1 MessageStore (org.apache.qpid.server.store.MessageStore)1 NullMessageStore (org.apache.qpid.server.store.NullMessageStore)1 StoredMemoryMessage (org.apache.qpid.server.store.StoredMemoryMessage)1 StoredMessage (org.apache.qpid.server.store.StoredMessage)1