Search in sources :

Example 1 with TransactionMonitor

use of org.apache.qpid.server.txn.TransactionMonitor in project qpid-broker-j by apache.

the class ConsumerTarget_1_0 method doSend.

@Override
public void doSend(final MessageInstanceConsumer consumer, final MessageInstance entry, boolean batch) {
    ServerMessage serverMessage = entry.getMessage();
    Message_1_0 message;
    final MessageConverter<? super ServerMessage, Message_1_0> converter;
    if (serverMessage instanceof Message_1_0) {
        converter = null;
        message = (Message_1_0) serverMessage;
    } else {
        if (!serverMessage.checkValid()) {
            throw new MessageConversionException(String.format("Cannot convert malformed message '%s'", serverMessage));
        }
        converter = (MessageConverter<? super ServerMessage, Message_1_0>) MessageConverterRegistry.getConverter(serverMessage.getClass(), Message_1_0.class);
        if (converter == null) {
            throw new ServerScopedRuntimeException(String.format("Could not find message converter from '%s' to '%s'." + " This is unexpected since we should not try to send if the converter is not present.", serverMessage.getClass(), Message_1_0.class));
        }
        message = converter.convert(serverMessage, _linkEndpoint.getAddressSpace());
    }
    Transfer transfer = new Transfer();
    try {
        QpidByteBuffer bodyContent = message.getContent();
        HeaderSection headerSection = message.getHeaderSection();
        UnsignedInteger ttl = headerSection == null ? null : headerSection.getValue().getTtl();
        if (entry.getDeliveryCount() != 0 || ttl != null) {
            Header header = new Header();
            if (headerSection != null) {
                final Header oldHeader = headerSection.getValue();
                header.setDurable(oldHeader.getDurable());
                header.setPriority(oldHeader.getPriority());
                if (ttl != null) {
                    long timeSpentOnBroker = System.currentTimeMillis() - message.getArrivalTime();
                    final long adjustedTtl = Math.max(0L, ttl.longValue() - timeSpentOnBroker);
                    header.setTtl(UnsignedInteger.valueOf(adjustedTtl));
                }
                headerSection.dispose();
            }
            if (entry.getDeliveryCount() != 0) {
                header.setDeliveryCount(UnsignedInteger.valueOf(entry.getDeliveryCount()));
            }
            headerSection = header.createEncodingRetainingSection();
        }
        List<QpidByteBuffer> payload = new ArrayList<>();
        if (headerSection != null) {
            payload.add(headerSection.getEncodedForm());
            headerSection.dispose();
        }
        EncodingRetainingSection<?> section;
        if ((section = message.getDeliveryAnnotationsSection()) != null) {
            payload.add(section.getEncodedForm());
            section.dispose();
        }
        if ((section = message.getMessageAnnotationsSection()) != null) {
            payload.add(section.getEncodedForm());
            section.dispose();
        }
        if ((section = message.getPropertiesSection()) != null) {
            payload.add(section.getEncodedForm());
            section.dispose();
        }
        if ((section = message.getApplicationPropertiesSection()) != null) {
            payload.add(section.getEncodedForm());
            section.dispose();
        }
        payload.add(bodyContent);
        if ((section = message.getFooterSection()) != null) {
            payload.add(section.getEncodedForm());
            section.dispose();
        }
        try (QpidByteBuffer combined = QpidByteBuffer.concatenate(payload)) {
            transfer.setPayload(combined);
        }
        payload.forEach(QpidByteBuffer::dispose);
        byte[] data = new byte[8];
        ByteBuffer.wrap(data).putLong(_deliveryTag++);
        final Binary tag = new Binary(data);
        transfer.setDeliveryTag(tag);
        if (_linkEndpoint.isAttached()) {
            boolean sendPreSettled = SenderSettleMode.SETTLED.equals(getEndpoint().getSendingSettlementMode());
            if (sendPreSettled) {
                transfer.setSettled(true);
                if (_acquires && _transactionId == null) {
                    transfer.setState(new Accepted());
                }
            } else {
                final UnsettledAction action;
                if (_acquires) {
                    action = new DispositionAction(tag, entry, consumer);
                    addUnacknowledgedMessage(entry);
                } else {
                    action = new DoNothingAction();
                }
                _linkEndpoint.addUnsettled(tag, action, entry);
            }
            if (_transactionId != null) {
                TransactionalState state = new TransactionalState();
                state.setTxnId(_transactionId);
                transfer.setState(state);
            }
            if (_acquires && _transactionId != null) {
                try {
                    ServerTransaction txn = _linkEndpoint.getTransaction(_transactionId);
                    txn.addPostTransactionAction(new ServerTransaction.Action() {

                        @Override
                        public void postCommit() {
                        }

                        @Override
                        public void onRollback() {
                            entry.release(consumer);
                            _linkEndpoint.updateDisposition(tag, null, true);
                        }
                    });
                    final TransactionLogResource owningResource = entry.getOwningResource();
                    if (owningResource instanceof TransactionMonitor) {
                        ((TransactionMonitor) owningResource).registerTransaction(txn);
                    }
                } catch (UnknownTransactionException e) {
                    entry.release(consumer);
                    getEndpoint().close(new Error(TransactionError.UNKNOWN_ID, e.getMessage()));
                    return;
                }
            }
            getSession().getAMQPConnection().registerMessageDelivered(message.getSize());
            getEndpoint().transfer(transfer, false);
            if (sendPreSettled && _acquires && _transactionId == null) {
                handleAcquiredEntrySentPareSettledNonTransactional(entry, consumer);
            }
        } else {
            entry.release(consumer);
        }
    } finally {
        transfer.dispose();
        if (converter != null) {
            converter.dispose(message);
        }
    }
}
Also used : ServerMessage(org.apache.qpid.server.message.ServerMessage) ArrayList(java.util.ArrayList) HeaderSection(org.apache.qpid.server.protocol.v1_0.type.messaging.HeaderSection) ServerScopedRuntimeException(org.apache.qpid.server.util.ServerScopedRuntimeException) ServerTransaction(org.apache.qpid.server.txn.ServerTransaction) TransactionMonitor(org.apache.qpid.server.txn.TransactionMonitor) MessageConversionException(org.apache.qpid.server.protocol.converter.MessageConversionException) Error(org.apache.qpid.server.protocol.v1_0.type.transport.Error) AmqpError(org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError) TransactionError(org.apache.qpid.server.protocol.v1_0.type.transaction.TransactionError) Accepted(org.apache.qpid.server.protocol.v1_0.type.messaging.Accepted) TransactionalState(org.apache.qpid.server.protocol.v1_0.type.transaction.TransactionalState) Header(org.apache.qpid.server.protocol.v1_0.type.messaging.Header) Transfer(org.apache.qpid.server.protocol.v1_0.type.transport.Transfer) QpidByteBuffer(org.apache.qpid.server.bytebuffer.QpidByteBuffer) Binary(org.apache.qpid.server.protocol.v1_0.type.Binary) UnsignedInteger(org.apache.qpid.server.protocol.v1_0.type.UnsignedInteger) TransactionLogResource(org.apache.qpid.server.store.TransactionLogResource)

Example 2 with TransactionMonitor

use of org.apache.qpid.server.txn.TransactionMonitor 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;
        }
    };
    final RoutingResult<? extends ServerMessage<? extends StorableMessageMetaData>> 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));
        }
    } else {
        result.getRoutes().stream().filter(q -> q instanceof TransactionMonitor).map(TransactionMonitor.class::cast).forEach(tm -> tm.registerTransaction(txn));
    }
}
Also used : InstanceProperties(org.apache.qpid.server.message.InstanceProperties) AmqpError(org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError) TransactionMonitor(org.apache.qpid.server.txn.TransactionMonitor)

Aggregations

AmqpError (org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError)2 TransactionMonitor (org.apache.qpid.server.txn.TransactionMonitor)2 ArrayList (java.util.ArrayList)1 QpidByteBuffer (org.apache.qpid.server.bytebuffer.QpidByteBuffer)1 InstanceProperties (org.apache.qpid.server.message.InstanceProperties)1 ServerMessage (org.apache.qpid.server.message.ServerMessage)1 MessageConversionException (org.apache.qpid.server.protocol.converter.MessageConversionException)1 Binary (org.apache.qpid.server.protocol.v1_0.type.Binary)1 UnsignedInteger (org.apache.qpid.server.protocol.v1_0.type.UnsignedInteger)1 Accepted (org.apache.qpid.server.protocol.v1_0.type.messaging.Accepted)1 Header (org.apache.qpid.server.protocol.v1_0.type.messaging.Header)1 HeaderSection (org.apache.qpid.server.protocol.v1_0.type.messaging.HeaderSection)1 TransactionError (org.apache.qpid.server.protocol.v1_0.type.transaction.TransactionError)1 TransactionalState (org.apache.qpid.server.protocol.v1_0.type.transaction.TransactionalState)1 Error (org.apache.qpid.server.protocol.v1_0.type.transport.Error)1 Transfer (org.apache.qpid.server.protocol.v1_0.type.transport.Transfer)1 TransactionLogResource (org.apache.qpid.server.store.TransactionLogResource)1 ServerTransaction (org.apache.qpid.server.txn.ServerTransaction)1 ServerScopedRuntimeException (org.apache.qpid.server.util.ServerScopedRuntimeException)1