use of org.apache.qpid.server.protocol.v1_0.type.messaging.Received in project qpid-broker-j by apache.
the class AbstractLinkEndpoint method receiveAttach.
@Override
public void receiveAttach(final Attach attach) throws AmqpErrorException {
_errored = false;
boolean isAttachingRemoteTerminusNull = (attach.getRole() == Role.SENDER ? attach.getSource() == null : attach.getTarget() == null);
boolean isAttachingLocalTerminusNull = (attach.getRole() == Role.SENDER ? attach.getTarget() == null : attach.getSource() == null);
boolean isLocalTerminusNull = (attach.getRole() == Role.SENDER ? getTarget() == null : getSource() == null);
if (isAttachingRemoteTerminusNull) {
throw new AmqpErrorException(AmqpError.INVALID_FIELD, "received Attach with remote null terminus.");
}
if (isAttachingLocalTerminusNull) {
recoverLink(attach);
} else if (isLocalTerminusNull) {
establishLink(attach);
} else if (attach.getUnsettled() != null) {
// TODO: QPID-7845 : Functionality for resuming links is not fully implemented
if (attach.getUnsettled().isEmpty()) {
resumeLink(attach);
} else {
throw new AmqpErrorException(new Error(AmqpError.NOT_IMPLEMENTED, "Resuming link is not implemented."));
}
} else {
reattachLink(attach);
}
}
use of org.apache.qpid.server.protocol.v1_0.type.messaging.Received 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.messaging.Received in project qpid-broker-j by apache.
the class TxnCoordinatorReceivingLinkEndpoint method receiveDelivery.
@Override
protected Error receiveDelivery(Delivery delivery) {
// Only interested in the amqp-value section that holds the message to the coordinator
try (QpidByteBuffer payload = delivery.getPayload()) {
List<EncodingRetainingSection<?>> sections = getSectionDecoder().parseAll(payload);
boolean amqpValueSectionFound = false;
for (EncodingRetainingSection section : sections) {
try {
if (section instanceof AmqpValueSection) {
if (amqpValueSectionFound) {
throw new ConnectionScopedRuntimeException("Received more than one AmqpValue sections");
}
amqpValueSectionFound = true;
Object command = section.getValue();
Session_1_0 session = getSession();
AMQPConnection_1_0<?> connection = session.getConnection();
connection.receivedComplete();
if (command instanceof Declare) {
final IdentifiedTransaction txn = connection.createIdentifiedTransaction();
_createdTransactions.put(txn.getId(), txn.getServerTransaction());
long notificationRepeatPeriod = getSession().getContextValue(Long.class, Session.TRANSACTION_TIMEOUT_NOTIFICATION_REPEAT_PERIOD);
connection.registerTransactionTickers(txn.getServerTransaction(), this::doTimeoutAction, notificationRepeatPeriod);
Declared state = new Declared();
state.setTxnId(Session_1_0.integerToTransactionId(txn.getId()));
updateDisposition(delivery.getDeliveryTag(), state, true);
} else if (command instanceof Discharge) {
Discharge discharge = (Discharge) command;
Error error = discharge(discharge.getTxnId(), Boolean.TRUE.equals(discharge.getFail()));
final DeliveryState outcome;
if (error == null) {
outcome = new Accepted();
} else if (Arrays.asList(getSource().getOutcomes()).contains(Rejected.REJECTED_SYMBOL)) {
final Rejected rejected = new Rejected();
rejected.setError(error);
outcome = rejected;
error = null;
} else {
outcome = null;
}
if (error == null) {
updateDisposition(delivery.getDeliveryTag(), outcome, true);
}
return error;
} else {
throw new ConnectionScopedRuntimeException(String.format("Received unknown command '%s'", command.getClass().getSimpleName()));
}
}
} finally {
section.dispose();
}
}
if (!amqpValueSectionFound) {
throw new ConnectionScopedRuntimeException("Received no AmqpValue section");
}
} catch (AmqpErrorException e) {
return e.getError();
}
return null;
}
use of org.apache.qpid.server.protocol.v1_0.type.messaging.Received 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.messaging.Received in project qpid-broker-j by apache.
the class AMQPConnection_1_0Impl method received.
private void received(int channel, Object val) {
if (channel > getChannelMax()) {
Error error = new Error(ConnectionError.FRAMING_ERROR, String.format("specified channel %d larger than maximum channel %d", channel, getChannelMax()));
handleError(error);
return;
}
FRAME_LOGGER.debug("RECV[{}|{}] : {}", _remoteAddress, channel, val);
if (val instanceof FrameBody) {
((FrameBody) val).invoke(channel, this);
} else if (val instanceof SaslFrameBody) {
((SaslFrameBody) val).invoke(channel, this);
}
}
Aggregations