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;
}
use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.
the class ConsumerTarget_1_0Test method testTTLAdjustedOnSend.
public void testTTLAdjustedOnSend() throws Exception {
final MessageInstanceConsumer comsumer = mock(MessageInstanceConsumer.class);
long ttl = 2000L;
long arrivalTime = System.currentTimeMillis() - 1000L;
final Header header = new Header();
header.setTtl(UnsignedInteger.valueOf(ttl));
final Message_1_0 message = createTestMessage(header, arrivalTime);
final MessageInstance messageInstance = mock(MessageInstance.class);
when(messageInstance.getMessage()).thenReturn(message);
AtomicReference<QpidByteBuffer> payloadRef = new AtomicReference<>();
doAnswer(invocation -> {
final Object[] args = invocation.getArguments();
Transfer transfer = (Transfer) args[0];
QpidByteBuffer transferPayload = transfer.getPayload();
QpidByteBuffer payloadCopy = transferPayload.duplicate();
payloadRef.set(payloadCopy);
return null;
}).when(_sendingLinkEndpoint).transfer(any(Transfer.class), anyBoolean());
_consumerTarget.doSend(comsumer, messageInstance, false);
verify(_sendingLinkEndpoint, times(1)).transfer(any(Transfer.class), anyBoolean());
final List<EncodingRetainingSection<?>> sections;
try (QpidByteBuffer payload = payloadRef.get()) {
sections = new SectionDecoderImpl(_describedTypeRegistry.getSectionDecoderRegistry()).parseAll(payload);
}
Header sentHeader = null;
for (EncodingRetainingSection<?> section : sections) {
if (section instanceof HeaderSection) {
sentHeader = ((HeaderSection) section).getValue();
}
}
assertNotNull("Header is not found", sentHeader);
assertNotNull("Ttl is not set", sentHeader.getTtl());
assertTrue("Unexpected ttl", sentHeader.getTtl().longValue() <= 1000);
}
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 sendFrame.
@Override
public int sendFrame(final int channel, final FrameBody body, final QpidByteBuffer payload) {
if (!_closedForOutput) {
ValueWriter<FrameBody> writer = _describedTypeRegistry.getValueWriter(body);
if (payload == null) {
send(AMQFrame.createAMQFrame(channel, body));
return 0;
} else {
int size = writer.getEncodedSize();
int maxPayloadSize = _maxFrameSize - (size + 9);
long payloadLength = (long) payload.remaining();
if (payloadLength <= maxPayloadSize) {
send(AMQFrame.createAMQFrame(channel, body, payload));
return (int) payloadLength;
} else {
((Transfer) body).setMore(Boolean.TRUE);
writer = _describedTypeRegistry.getValueWriter(body);
size = writer.getEncodedSize();
maxPayloadSize = _maxFrameSize - (size + 9);
try (QpidByteBuffer payloadDup = payload.view(0, maxPayloadSize)) {
payload.position(payload.position() + maxPayloadSize);
send(AMQFrame.createAMQFrame(channel, body, payloadDup));
}
return maxPayloadSize;
}
}
} else {
return -1;
}
}
use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.
the class Delivery method addTransfer.
final void addTransfer(Transfer transfer) {
if (_aborted) {
throw new IllegalStateException(String.format("Delivery '%s/%d' is already aborted", _deliveryTag, _deliveryId.intValue()));
}
if (_complete) {
throw new IllegalStateException(String.format("Delivery '%s/%d' is already completed", _deliveryTag, _deliveryId.intValue()));
}
_transfers.add(transfer);
if (Boolean.TRUE.equals(transfer.getAborted())) {
_aborted = true;
discard();
}
if (!Boolean.TRUE.equals(transfer.getMore())) {
_complete = true;
}
if (Boolean.TRUE.equals(transfer.getSettled())) {
_settled = true;
}
if (Boolean.TRUE.equals(transfer.getResume())) {
_resume = true;
}
if (transfer.getState() != null) {
DeliveryState currentState;
if (_state instanceof TransactionalState) {
currentState = ((TransactionalState) _state).getOutcome();
} else {
currentState = _state;
}
if (!(currentState instanceof Outcome)) {
_state = transfer.getState();
}
}
if (transfer.getRcvSettleMode() != null) {
if (_receiverSettleMode == null) {
_receiverSettleMode = transfer.getRcvSettleMode();
}
}
try (QpidByteBuffer payload = transfer.getPayload()) {
if (payload != null) {
_totalPayloadSize += (long) payload.remaining();
}
}
}
use of org.apache.qpid.server.protocol.v1_0.type.transport.Transfer in project qpid-broker-j by apache.
the class Session_1_0 method receiveTransfer.
public void receiveTransfer(final Transfer transfer) {
_nextIncomingId.incr();
_remoteOutgoingWindow = _remoteOutgoingWindow.subtract(UnsignedInteger.ONE);
UnsignedInteger inputHandle = transfer.getHandle();
LinkEndpoint<? extends BaseSource, ? extends BaseTarget> linkEndpoint = _inputHandleToEndpoint.get(inputHandle);
if (linkEndpoint == null) {
Error error = new Error();
error.setCondition(SessionError.UNATTACHED_HANDLE);
error.setDescription("TRANSFER called on Session for link handle " + inputHandle + " which is not attached.");
_connection.close(error);
} else if (!(linkEndpoint instanceof AbstractReceivingLinkEndpoint)) {
Error error = new Error();
error.setCondition(AmqpError.PRECONDITION_FAILED);
error.setDescription("Received TRANSFER for link handle " + inputHandle + " which is a sending link not a receiving link.");
_connection.close(error);
} else {
AbstractReceivingLinkEndpoint endpoint = ((AbstractReceivingLinkEndpoint) linkEndpoint);
endpoint.receiveTransfer(transfer);
}
}
Aggregations