Search in sources :

Example 1 with Transfer

use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.

the class TransferTest method transferWithoutDeliveryTag.

@Test
@SpecificationTest(section = "2.7.5", description = "[delivery-tag] MUST be specified for the first transfer " + "[...] and can only be omitted for continuation transfers.")
public void transferWithoutDeliveryTag() throws Exception {
    try (FrameTransport transport = new FrameTransport(_brokerAddress).connect()) {
        Interaction interaction = transport.newInteraction().negotiateProtocol().consumeResponse().open().consumeResponse(Open.class).begin().consumeResponse(Begin.class).attachRole(Role.SENDER).attachTargetAddress(BrokerAdmin.TEST_QUEUE_NAME).attach().consumeResponse(Attach.class).consumeResponse(Flow.class).transferDeliveryTag(null).transferPayloadData("testData").transfer();
        interaction.consumeResponse(Detach.class, End.class, Close.class);
    }
}
Also used : FrameTransport(org.apache.qpid.tests.protocol.v1_0.FrameTransport) Interaction(org.apache.qpid.tests.protocol.v1_0.Interaction) Flow(org.apache.qpid.server.protocol.v1_0.type.transport.Flow) SpecificationTest(org.apache.qpid.tests.protocol.SpecificationTest) Test(org.junit.Test) SpecificationTest(org.apache.qpid.tests.protocol.SpecificationTest)

Example 2 with Transfer

use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.

the class FrameHandler method parse.

@Override
public ProtocolHandler parse(QpidByteBuffer in) {
    try {
        LOGGER.debug("RECV {} bytes", in.remaining());
        Error frameParsingError = null;
        int size;
        int remaining;
        List<ChannelFrameBody> channelFrameBodies = new ArrayList<>();
        while ((remaining = in.remaining()) >= 8 && frameParsingError == null) {
            size = in.getInt();
            if (size < 8) {
                frameParsingError = createFramingError("specified frame size %d smaller than minimum frame header size %d", size, 8);
                break;
            }
            if (size > _connectionHandler.getMaxFrameSize()) {
                frameParsingError = createFramingError("specified frame size %d larger than maximum frame header size %d", size, _connectionHandler.getMaxFrameSize());
                break;
            }
            if (remaining < size) {
                in.position(in.position() - 4);
                break;
            }
            int dataOffset = (in.get() << 2) & 0x3FF;
            if (dataOffset < 8) {
                frameParsingError = createFramingError("specified frame data offset %d smaller than minimum frame header size %d", dataOffset, 8);
                break;
            }
            if (dataOffset > size) {
                frameParsingError = createFramingError("specified frame data offset %d larger than the frame size %d", dataOffset, size);
                break;
            }
            byte type = in.get();
            switch(type) {
                case 0:
                    if (_isSasl) {
                        frameParsingError = createFramingError("received an AMQP frame type when expecting an SASL frame");
                    }
                    break;
                case 1:
                    if (!_isSasl) {
                        frameParsingError = createFramingError("received a SASL frame type when expecting an AMQP frame");
                    }
                    break;
                default:
                    frameParsingError = createFramingError("unknown frame type: %d", type);
            }
            if (frameParsingError != null) {
                break;
            }
            int channel = in.getUnsignedShort();
            if (dataOffset != 8) {
                in.position(in.position() + dataOffset - 8);
            }
            try (QpidByteBuffer dup = in.slice()) {
                dup.limit(size - dataOffset);
                in.position(in.position() + size - dataOffset);
                final boolean hasFrameBody = dup.hasRemaining();
                Object frameBody;
                if (hasFrameBody) {
                    frameBody = _valueHandler.parse(dup);
                    if (dup.hasRemaining()) {
                        if (frameBody instanceof Transfer) {
                            try (QpidByteBuffer payload = dup.slice()) {
                                ((Transfer) frameBody).setPayload(payload);
                            }
                        } else {
                            frameParsingError = createFramingError("Frame length %d larger than contained frame body %s.", size, frameBody);
                            break;
                        }
                    }
                } else {
                    frameBody = null;
                    if (_isSasl) {
                        frameParsingError = createFramingError("Empty (heartbeat) frames are not permitted during SASL negotiation");
                        break;
                    }
                }
                channelFrameBodies.add(new ChannelFrameBody() {

                    @Override
                    public int getChannel() {
                        return channel;
                    }

                    @Override
                    public Object getFrameBody() {
                        return frameBody;
                    }
                });
                if (_isSasl) {
                    break;
                }
            } catch (AmqpErrorException ex) {
                frameParsingError = ex.getError();
            }
        }
        if (frameParsingError != null) {
            _connectionHandler.handleError(frameParsingError);
            _errored = true;
        } else {
            _connectionHandler.receive(channelFrameBodies);
        }
    } catch (RuntimeException e) {
        if (e instanceof ServerScopedRuntimeException) {
            throw e;
        }
        LOGGER.warn("Unexpected exception handling frame", e);
        // This exception is unexpected. The up layer should handle error condition gracefully
        _connectionHandler.handleError(this.createError(AmqpError.INTERNAL_ERROR, e.toString()));
    }
    return this;
}
Also used : ArrayList(java.util.ArrayList) Error(org.apache.qpid.server.protocol.v1_0.type.transport.Error) AmqpError(org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError) ConnectionError(org.apache.qpid.server.protocol.v1_0.type.transport.ConnectionError) AmqpErrorException(org.apache.qpid.server.protocol.v1_0.type.AmqpErrorException) ServerScopedRuntimeException(org.apache.qpid.server.util.ServerScopedRuntimeException) ServerScopedRuntimeException(org.apache.qpid.server.util.ServerScopedRuntimeException) ChannelFrameBody(org.apache.qpid.server.protocol.v1_0.type.transport.ChannelFrameBody) Transfer(org.apache.qpid.server.protocol.v1_0.type.transport.Transfer) QpidByteBuffer(org.apache.qpid.server.bytebuffer.QpidByteBuffer)

Example 3 with Transfer

use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.

the class AMQPConnection_1_0Impl method receive.

@Override
public final void receive(final List<ChannelFrameBody> channelFrameBodies) {
    if (!channelFrameBodies.isEmpty()) {
        final PeekingIterator<ChannelFrameBody> itr = Iterators.peekingIterator(channelFrameBodies.iterator());
        boolean cleanExit = false;
        try {
            while (itr.hasNext()) {
                final ChannelFrameBody channelFrameBody = itr.next();
                final int frameChannel = channelFrameBody.getChannel();
                final Session_1_0 session = _receivingSessions == null || frameChannel >= _receivingSessions.length ? null : _receivingSessions[frameChannel];
                if (session != null) {
                    final AccessControlContext context = session.getAccessControllerContext();
                    AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                        ChannelFrameBody channelFrame = channelFrameBody;
                        boolean nextIsSameChannel;
                        do {
                            received(frameChannel, channelFrame.getFrameBody());
                            nextIsSameChannel = itr.hasNext() && frameChannel == itr.peek().getChannel();
                            if (nextIsSameChannel) {
                                channelFrame = itr.next();
                            }
                        } while (nextIsSameChannel);
                        return null;
                    }, context);
                } else {
                    received(frameChannel, channelFrameBody.getFrameBody());
                }
            }
            cleanExit = true;
        } finally {
            if (!cleanExit) {
                while (itr.hasNext()) {
                    final Object frameBody = itr.next().getFrameBody();
                    if (frameBody instanceof Transfer) {
                        ((Transfer) frameBody).dispose();
                    }
                }
            }
        }
    }
}
Also used : AccessControlContext(java.security.AccessControlContext) ChannelFrameBody(org.apache.qpid.server.protocol.v1_0.type.transport.ChannelFrameBody) Transfer(org.apache.qpid.server.protocol.v1_0.type.transport.Transfer)

Example 4 with Transfer

use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.

the class AbstractReceivingLinkEndpoint method receiveTransfer.

void receiveTransfer(final Transfer transfer) {
    if (!isErrored()) {
        Error error = validateTransfer(transfer);
        if (error != null) {
            transfer.dispose();
            if (_currentDelivery != null) {
                _currentDelivery.discard();
                _currentDelivery = null;
            }
            close(error);
            return;
        }
        if (_currentDelivery == null) {
            error = validateNewTransfer(transfer);
            if (error != null) {
                transfer.dispose();
                close(error);
                return;
            }
            _currentDelivery = new Delivery(transfer, this);
            setLinkCredit(getLinkCredit().subtract(UnsignedInteger.ONE));
            getDeliveryCount().incr();
            getSession().getIncomingDeliveryRegistry().addDelivery(transfer.getDeliveryId(), new UnsettledDelivery(transfer.getDeliveryTag(), this));
        } else {
            error = validateSubsequentTransfer(transfer);
            if (error != null) {
                transfer.dispose();
                _currentDelivery.discard();
                _currentDelivery = null;
                close(error);
                return;
            }
            _currentDelivery.addTransfer(transfer);
        }
        if (_currentDelivery.getTotalPayloadSize() > getSession().getConnection().getMaxMessageSize()) {
            error = new Error(LinkError.MESSAGE_SIZE_EXCEEDED, String.format("delivery '%s' exceeds max-message-size %d", _currentDelivery.getDeliveryTag(), getSession().getConnection().getMaxMessageSize()));
            _currentDelivery.discard();
            _currentDelivery = null;
            close(error);
            return;
        }
        if (!_currentDelivery.getResume()) {
            _unsettled.put(_currentDelivery.getDeliveryTag(), _currentDelivery.getState());
        }
        if (_currentDelivery.isAborted() || (_currentDelivery.getResume() && !_unsettled.containsKey(_currentDelivery.getDeliveryTag()))) {
            _unsettled.remove(_currentDelivery.getDeliveryTag());
            getSession().getIncomingDeliveryRegistry().removeDelivery(_currentDelivery.getDeliveryId());
            _currentDelivery = null;
            setLinkCredit(getLinkCredit().add(UnsignedInteger.ONE));
            getDeliveryCount().decr();
        } else if (_currentDelivery.isComplete()) {
            try {
                if (_currentDelivery.isSettled()) {
                    _unsettled.remove(_currentDelivery.getDeliveryTag());
                    getSession().getIncomingDeliveryRegistry().removeDelivery(_currentDelivery.getDeliveryId());
                }
                error = receiveDelivery(_currentDelivery);
                if (error != null) {
                    close(error);
                }
            } finally {
                _currentDelivery = null;
            }
        } else {
            getSession().sendFlowConditional();
        }
    } else {
        End end = new End();
        end.setError(new Error(SessionError.ERRANT_LINK, String.format("Received TRANSFER for link handle %s which is in errored state.", transfer.getHandle())));
        getSession().end(end);
    }
}
Also used : UnsettledDelivery(org.apache.qpid.server.protocol.v1_0.delivery.UnsettledDelivery) 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) SessionError(org.apache.qpid.server.protocol.v1_0.type.transport.SessionError) LinkError(org.apache.qpid.server.protocol.v1_0.type.transport.LinkError) End(org.apache.qpid.server.protocol.v1_0.type.transport.End) UnsettledDelivery(org.apache.qpid.server.protocol.v1_0.delivery.UnsettledDelivery)

Example 5 with Transfer

use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer 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)

Aggregations

Test (org.junit.Test)64 FrameTransport (org.apache.qpid.tests.protocol.v1_0.FrameTransport)61 SpecificationTest (org.apache.qpid.tests.protocol.SpecificationTest)60 Interaction (org.apache.qpid.tests.protocol.v1_0.Interaction)53 Attach (org.apache.qpid.server.protocol.v1_0.type.transport.Attach)44 Flow (org.apache.qpid.server.protocol.v1_0.type.transport.Flow)39 UnsignedInteger (org.apache.qpid.server.protocol.v1_0.type.UnsignedInteger)33 Begin (org.apache.qpid.server.protocol.v1_0.type.transport.Begin)31 Disposition (org.apache.qpid.server.protocol.v1_0.type.transport.Disposition)28 Transfer (org.apache.qpid.server.protocol.v1_0.type.transport.Transfer)26 Binary (org.apache.qpid.server.protocol.v1_0.type.Binary)25 QpidByteBuffer (org.apache.qpid.server.bytebuffer.QpidByteBuffer)24 Error (org.apache.qpid.server.protocol.v1_0.type.transport.Error)23 AmqpError (org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError)19 Detach (org.apache.qpid.server.protocol.v1_0.type.transport.Detach)15 Accepted (org.apache.qpid.server.protocol.v1_0.type.messaging.Accepted)14 DeliveryState (org.apache.qpid.server.protocol.v1_0.type.DeliveryState)13 TransactionError (org.apache.qpid.server.protocol.v1_0.type.transaction.TransactionError)12 ErrorCarryingFrameBody (org.apache.qpid.server.protocol.v1_0.type.ErrorCarryingFrameBody)8 LinkError (org.apache.qpid.server.protocol.v1_0.type.transport.LinkError)8