Search in sources :

Example 6 with InstanceProperties

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

the class AMQChannel method deliverCurrentMessageIfComplete.

private void deliverCurrentMessageIfComplete() {
    // check and deliver if header says body length is zero
    if (_currentMessage.allContentReceived()) {
        MessagePublishInfo info = _currentMessage.getMessagePublishInfo();
        String routingKey = AMQShortString.toString(info.getRoutingKey());
        String exchangeName = AMQShortString.toString(info.getExchange());
        try {
            final MessageDestination destination = _currentMessage.getDestination();
            ContentHeaderBody contentHeader = _currentMessage.getContentHeader();
            _connection.checkAuthorizedMessagePrincipal(AMQShortString.toString(contentHeader.getProperties().getUserId()));
            _publishAuthCache.authorisePublish(destination, routingKey, info.isImmediate(), _connection.getLastReadTime());
            if (_confirmOnPublish) {
                _confirmedMessageCounter++;
            }
            long bodySize = _currentMessage.getSize();
            long timestamp = contentHeader.getProperties().getTimestamp();
            try {
                final MessagePublishInfo messagePublishInfo = _currentMessage.getMessagePublishInfo();
                final MessageMetaData messageMetaData = new MessageMetaData(messagePublishInfo, contentHeader, getConnection().getLastReadTime());
                final MessageHandle<MessageMetaData> handle = _messageStore.addMessage(messageMetaData);
                int bodyCount = _currentMessage.getBodyCount();
                if (bodyCount > 0) {
                    for (int i = 0; i < bodyCount; i++) {
                        ContentBody contentChunk = _currentMessage.getContentChunk(i);
                        handle.addContent(contentChunk.getPayload());
                        contentChunk.dispose();
                    }
                }
                final StoredMessage<MessageMetaData> storedMessage = handle.allContentAdded();
                final AMQMessage amqMessage = new AMQMessage(storedMessage, _connection.getReference());
                try (MessageReference reference = amqMessage.newReference()) {
                    _currentMessage = null;
                    final boolean immediate = messagePublishInfo.isImmediate();
                    final InstanceProperties instanceProperties = new InstanceProperties() {

                        @Override
                        public Object getProperty(final Property prop) {
                            switch(prop) {
                                case EXPIRATION:
                                    return amqMessage.getExpiration();
                                case IMMEDIATE:
                                    return immediate;
                                case PERSISTENT:
                                    return amqMessage.isPersistent();
                                case MANDATORY:
                                    return messagePublishInfo.isMandatory();
                                case REDELIVERED:
                                    return false;
                            }
                            return null;
                        }
                    };
                    final RoutingResult<AMQMessage> result = destination.route(amqMessage, amqMessage.getInitialRoutingAddress(), instanceProperties);
                    int enqueues = result.send(_transaction, immediate ? _immediateAction : null);
                    if (enqueues == 0) {
                        boolean mandatory = amqMessage.isMandatory();
                        boolean closeOnNoRoute = _connection.isCloseWhenNoRoute();
                        if (LOGGER.isDebugEnabled()) {
                            LOGGER.debug("Unroutable message exchange='{}', routing key='{}', mandatory={}," + " transactionalSession={}, closeOnNoRoute={}, confirmOnPublish={}", exchangeName, routingKey, mandatory, isTransactional(), closeOnNoRoute, _confirmOnPublish);
                        }
                        int errorCode = ErrorCodes.NO_ROUTE;
                        String errorMessage = String.format("No route for message with exchange '%s' and routing key '%s'", exchangeName, routingKey);
                        if (result.containsReject(RejectType.LIMIT_EXCEEDED)) {
                            errorCode = ErrorCodes.RESOURCE_ERROR;
                            errorMessage = errorMessage + ":" + result.getRejectReason();
                        }
                        if (mandatory && isTransactional() && !_confirmOnPublish && _connection.isCloseWhenNoRoute()) {
                            _connection.sendConnectionClose(errorCode, errorMessage, _channelId);
                        } else {
                            if (mandatory || amqMessage.isImmediate()) {
                                if (_confirmOnPublish) {
                                    _connection.writeFrame(new AMQFrame(_channelId, new BasicNackBody(_confirmedMessageCounter, false, false)));
                                }
                                _transaction.addPostTransactionAction(new WriteReturnAction(errorCode, errorMessage, amqMessage));
                            } else {
                                if (_confirmOnPublish) {
                                    _connection.writeFrame(new AMQFrame(_channelId, new BasicAckBody(_confirmedMessageCounter, false)));
                                }
                                message(ExchangeMessages.DISCARDMSG(exchangeName, routingKey));
                            }
                        }
                    } else {
                        if (_confirmOnPublish) {
                            recordFuture(Futures.immediateFuture(null), new ServerTransaction.Action() {

                                private final long _deliveryTag = _confirmedMessageCounter;

                                @Override
                                public void postCommit() {
                                    BasicAckBody body = _connection.getMethodRegistry().createBasicAckBody(_deliveryTag, false);
                                    _connection.writeFrame(body.generateFrame(_channelId));
                                }

                                @Override
                                public void onRollback() {
                                    final BasicNackBody body = new BasicNackBody(_deliveryTag, false, false);
                                    _connection.writeFrame(new AMQFrame(_channelId, body));
                                }
                            });
                        }
                    }
                }
            } finally {
                _connection.registerMessageReceived(bodySize);
                if (isTransactional()) {
                    _connection.registerTransactedMessageReceived();
                }
                _currentMessage = null;
            }
        } catch (AccessControlException e) {
            _connection.sendConnectionClose(ErrorCodes.ACCESS_REFUSED, e.getMessage(), getChannelId());
        }
    }
}
Also used : MessageDestination(org.apache.qpid.server.message.MessageDestination) InstanceProperties(org.apache.qpid.server.message.InstanceProperties) AccessControlException(java.security.AccessControlException) MessageReference(org.apache.qpid.server.message.MessageReference) ServerTransaction(org.apache.qpid.server.txn.ServerTransaction)

Example 7 with InstanceProperties

use of org.apache.qpid.server.message.InstanceProperties 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 8 with InstanceProperties

use of org.apache.qpid.server.message.InstanceProperties 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)

Example 9 with InstanceProperties

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

the class TopicExchangeTest method testRouteToQueueWithSelector.

public void testRouteToQueueWithSelector() {
    String bindingKey = "mybinding";
    Queue<?> queue = _vhost.createChild(Queue.class, Collections.singletonMap(Queue.NAME, getTestName() + "_queue"));
    InstanceProperties instanceProperties = mock(InstanceProperties.class);
    ServerMessage<?> matchingMessage = createTestMessage(Collections.singletonMap("prop", true));
    ServerMessage<?> unmatchingMessage = createTestMessage(Collections.singletonMap("prop", false));
    boolean bind = _exchange.bind(queue.getName(), bindingKey, Collections.singletonMap(JMS_SELECTOR.toString(), "prop = True"), false);
    assertTrue("Bind operation should be successful", bind);
    RoutingResult<ServerMessage<?>> result = _exchange.route(matchingMessage, "mybinding", instanceProperties);
    assertTrue("Message with matching selector not routed to queue", result.hasRoutes());
    result = _exchange.route(unmatchingMessage, "mybinding", instanceProperties);
    assertFalse("Message without matching selector unexpectedly routed to queue", result.hasRoutes());
    boolean unbind = _exchange.unbind(queue.getName(), bindingKey);
    assertTrue("Unbind operation should be successful", unbind);
    result = _exchange.route(matchingMessage, "mybinding", instanceProperties);
    assertFalse("Message with matching selector unexpectedly routed to queue after unbind", result.hasRoutes());
}
Also used : InstanceProperties(org.apache.qpid.server.message.InstanceProperties) ServerMessage(org.apache.qpid.server.message.ServerMessage)

Example 10 with InstanceProperties

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

the class TopicExchangeTest method testUpdateBindingAddingSelector.

public void testUpdateBindingAddingSelector() throws Exception {
    String bindingKey = "mybinding";
    Queue<?> queue = _vhost.createChild(Queue.class, Collections.singletonMap(Queue.NAME, getTestName() + "_queue"));
    InstanceProperties instanceProperties = mock(InstanceProperties.class);
    ServerMessage<?> message = createTestMessage(Collections.singletonMap("prop", false));
    boolean bind = _exchange.bind(queue.getName(), bindingKey, Collections.emptyMap(), false);
    assertTrue("Bind operation should be successful", bind);
    RoutingResult<ServerMessage<?>> result = _exchange.route(message, bindingKey, instanceProperties);
    assertTrue("Message not routed to queue", result.hasRoutes());
    _exchange.replaceBinding(bindingKey, queue, Collections.singletonMap(JMS_SELECTOR.toString(), "prop = false"));
    result = _exchange.route(message, bindingKey, instanceProperties);
    assertTrue("Message that matches selector not routed to queue after rebind", result.hasRoutes());
    result = _exchange.route(message = createTestMessage(Collections.singletonMap("prop", true)), bindingKey, instanceProperties);
    assertFalse("Message that does not match selector routed to queue after rebind", result.hasRoutes());
}
Also used : InstanceProperties(org.apache.qpid.server.message.InstanceProperties) ServerMessage(org.apache.qpid.server.message.ServerMessage)

Aggregations

InstanceProperties (org.apache.qpid.server.message.InstanceProperties)10 ServerMessage (org.apache.qpid.server.message.ServerMessage)6 MessageDestination (org.apache.qpid.server.message.MessageDestination)3 AccessControlException (java.security.AccessControlException)2 MessageReference (org.apache.qpid.server.message.MessageReference)2 RoutingResult (org.apache.qpid.server.message.RoutingResult)2 Serializable (java.io.Serializable)1 ArrayList (java.util.ArrayList)1 Collections.newSetFromMap (java.util.Collections.newSetFromMap)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 AMQMessageHeader (org.apache.qpid.server.message.AMQMessageHeader)1 InternalMessage (org.apache.qpid.server.message.internal.InternalMessage)1 AbstractConfiguredObject (org.apache.qpid.server.model.AbstractConfiguredObject)1 NamedAddressSpace (org.apache.qpid.server.model.NamedAddressSpace)1 AmqpError (org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError)1 MessageStore (org.apache.qpid.server.store.MessageStore)1