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 void receive(final List<ChannelFrameBody> channelFrameBodies) {
if (!channelFrameBodies.isEmpty()) {
PeekingIterator<ChannelFrameBody> itr = Iterators.peekingIterator(channelFrameBodies.iterator());
boolean cleanExit = false;
try {
while (itr.hasNext()) {
final ChannelFrameBody channelFrameBody = itr.next();
final int frameChannel = channelFrameBody.getChannel();
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();
}
}
}
}
}
}
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 {
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);
}
}
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 {
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()) {
if (SenderSettleMode.SETTLED.equals(getEndpoint().getSendingSettlementMode())) {
transfer.setSettled(true);
} 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);
}
});
} 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);
} else {
entry.release(consumer);
}
} finally {
transfer.dispose();
if (converter != null) {
converter.dispose(message);
}
}
}
use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.
the class Delivery method getPayload.
public QpidByteBuffer getPayload() {
List<QpidByteBuffer> transferBuffers = new ArrayList<>(_transfers.size());
for (Transfer t : _transfers) {
transferBuffers.add(t.getPayload());
t.dispose();
}
_transfers.clear();
final QpidByteBuffer combined = QpidByteBuffer.concatenate(transferBuffers);
transferBuffers.forEach(QpidByteBuffer::dispose);
return combined;
}
use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.
the class SendingLinkEndpoint method flowStateChanged.
@Override
public void flowStateChanged() {
if (Boolean.TRUE.equals(getDrain())) {
if (getLinkCredit().compareTo(UnsignedInteger.ZERO) > 0) {
_draining = true;
getSession().notifyWork(getConsumerTarget());
}
} else {
_draining = false;
}
while (!_resumeAcceptedTransfers.isEmpty() && hasCreditToSend()) {
Accepted accepted = new Accepted();
Transfer xfr = new Transfer();
Binary dt = _resumeAcceptedTransfers.remove(0);
xfr.setDeliveryTag(dt);
xfr.setState(accepted);
xfr.setResume(Boolean.TRUE);
transfer(xfr, true);
xfr.dispose();
}
if (_resumeAcceptedTransfers.isEmpty()) {
getConsumerTarget().flowStateChanged();
}
}
Aggregations