use of org.apache.qpid.proton.amqp.messaging.Rejected in project azure-iot-sdk-java by Azure.
the class AmqpsMessageTest method acknowledgeSetsRejectedDispositionForReject.
// Tests_SRS_AMQPSMESSAGE_14_003: [If the ACK_TYPE is REJECT, the function shall set a Rejected disposition on the private Delivery object.]
@Test
public void acknowledgeSetsRejectedDispositionForReject(@Mocked final Rejected mockRejected) {
new NonStrictExpectations() {
{
new Rejected();
result = mockRejected;
}
};
AmqpsMessage message = new AmqpsMessage();
message.setDelivery(mockDelivery);
message.acknowledge(AmqpsMessage.ACK_TYPE.REJECT);
final Delivery expectedDelivery = mockDelivery;
new Verifications() {
{
expectedDelivery.disposition(mockRejected);
}
};
}
use of org.apache.qpid.proton.amqp.messaging.Rejected in project hono by eclipse.
the class MessageForwardingEndpointTest method testMessageHandlerRejectsMalformedMessage.
/**
* Verifies that the endpoint rejects messages that do not pass formal verification.
*/
@SuppressWarnings({ "unchecked" })
@Test
public void testMessageHandlerRejectsMalformedMessage() {
// GIVEN an endpoint with an attached client
final ResourceIdentifier targetAddress = ResourceIdentifier.fromString("telemetry/tenant");
final ProtonConnection connection = mock(ProtonConnection.class);
when(connection.getRemoteContainer()).thenReturn("test-client");
final ProtonReceiver receiver = mock(ProtonReceiver.class);
when(receiver.getRemoteQoS()).thenReturn(ProtonQoS.AT_MOST_ONCE);
final DownstreamAdapter adapter = mock(DownstreamAdapter.class);
doAnswer(invocation -> {
final Handler<AsyncResult<Void>> resultHandler = invocation.getArgument(1);
resultHandler.handle(Future.succeededFuture());
return null;
}).when(adapter).onClientAttach(any(UpstreamReceiver.class), any(Handler.class));
final MessageForwardingEndpoint<HonoMessagingConfigProperties> endpoint = getEndpoint(false);
endpoint.setDownstreamAdapter(adapter);
endpoint.onLinkAttach(connection, receiver, targetAddress);
final ArgumentCaptor<ProtonMessageHandler> messageHandler = ArgumentCaptor.forClass(ProtonMessageHandler.class);
verify(receiver).handler(messageHandler.capture());
// WHEN a client sends a malformed message
final Message message = ProtonHelper.message("malformed");
final ProtonDelivery upstreamDelivery = mock(ProtonDelivery.class);
messageHandler.getValue().handle(upstreamDelivery, message);
// THEN the endpoint rejects the message
final ArgumentCaptor<Rejected> deliveryState = ArgumentCaptor.forClass(Rejected.class);
verify(upstreamDelivery).disposition(deliveryState.capture(), eq(Boolean.TRUE));
assertThat(deliveryState.getValue().getError().getCondition(), is(AmqpError.DECODE_ERROR));
// but does not close the link
verify(receiver, never()).close();
// and the message is not forwarded to the downstream adapter
verify(adapter, never()).processMessage(any(UpstreamReceiver.class), eq(upstreamDelivery), eq(message));
}
use of org.apache.qpid.proton.amqp.messaging.Rejected in project hono by eclipse.
the class ForwardingTelemetryDownstreamAdapterTest method testProcessMessageForwardsDownstreamDisposition.
/**
* Verifies that an unsettled telemetry message received from an upstream client is
* forwarded to the downstream container and the downstream container's disposition
* is forwarded to the upstream client.
*
* @param ctx The test context.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testProcessMessageForwardsDownstreamDisposition(final TestContext ctx) {
final UpstreamReceiver client = TestSupport.newClient();
// GIVEN an adapter with a connection to a downstream container
final ProtonSender sender = TestSupport.newMockSender(false);
final ForwardingTelemetryDownstreamAdapter adapter = new ForwardingTelemetryDownstreamAdapter(vertx, TestSupport.newMockSenderFactory(sender));
adapter.setMetrics(mock(MessagingMetrics.class));
adapter.setDownstreamConnectionFactory(connectionFactory);
adapter.start(Future.future());
adapter.addSender(client, sender);
// WHEN processing an unsettled telemetry message
final Message msg = ProtonHelper.message(TELEMETRY_MSG_CONTENT);
MessageHelper.addDeviceId(msg, DEVICE_ID);
final ProtonDelivery upstreamDelivery = mock(ProtonDelivery.class);
when(upstreamDelivery.remotelySettled()).thenReturn(Boolean.FALSE);
adapter.processMessage(client, upstreamDelivery, msg);
// THEN the message is being delivered to the downstream container
final ArgumentCaptor<Handler> deliveryHandler = ArgumentCaptor.forClass(Handler.class);
verify(sender).send(eq(msg), deliveryHandler.capture());
// and when the downstream container rejects the message
final ProtonDelivery downstreamDelivery = mock(ProtonDelivery.class);
when(downstreamDelivery.remotelySettled()).thenReturn(Boolean.TRUE);
when(downstreamDelivery.getRemoteState()).thenReturn(new Rejected());
deliveryHandler.getValue().handle(downstreamDelivery);
// then the upstream delivery is settled with the rejected outcome
verify(upstreamDelivery).disposition(any(Rejected.class), eq(Boolean.TRUE));
}
use of org.apache.qpid.proton.amqp.messaging.Rejected in project hono by eclipse.
the class EventSenderImpl method sendMessage.
@Override
protected Future<ProtonDelivery> sendMessage(final Message message) {
Objects.requireNonNull(message);
final Future<ProtonDelivery> result = Future.future();
final String messageId = String.format("%s-%d", getClass().getSimpleName(), MESSAGE_COUNTER.getAndIncrement());
message.setMessageId(messageId);
sender.send(message, deliveryUpdated -> {
if (deliveryUpdated.remotelySettled()) {
if (Accepted.class.isInstance(deliveryUpdated.getRemoteState())) {
LOG.trace("event [message ID: {}] accepted by peer", messageId);
result.complete(deliveryUpdated);
} else if (Rejected.class.isInstance(deliveryUpdated.getRemoteState())) {
Rejected rejected = (Rejected) deliveryUpdated.getRemoteState();
if (rejected.getError() == null) {
LOG.debug("event [message ID: {}] rejected by peer", messageId);
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
} else {
LOG.debug("event [message ID: {}] rejected by peer: {}, {}", messageId, rejected.getError().getCondition(), rejected.getError().getDescription());
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, rejected.getError().getDescription()));
}
} else {
LOG.debug("event [message ID: {}] not accepted by peer: {}", messageId, deliveryUpdated.getRemoteState());
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
}
} else {
LOG.warn("peer did not settle event, failing delivery [new remote state: {}]", deliveryUpdated.getRemoteState());
result.fail(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR));
}
});
LOG.trace("sent event [ID: {}], remaining credit: {}, queued messages: {}", messageId, sender.getCredit(), sender.getQueued());
return result;
}
use of org.apache.qpid.proton.amqp.messaging.Rejected in project hono by eclipse.
the class TelemetrySenderImpl method sendMessage.
@Override
protected Future<ProtonDelivery> sendMessage(final Message message) {
Objects.requireNonNull(message);
final String messageId = String.format("%s-%d", getClass().getSimpleName(), MESSAGE_COUNTER.getAndIncrement());
message.setMessageId(messageId);
final ProtonDelivery result = sender.send(message, deliveryUpdated -> {
if (deliveryUpdated.remotelySettled()) {
if (Accepted.class.isInstance(deliveryUpdated.getRemoteState())) {
LOG.trace("message [message ID: {}] accepted by peer", messageId);
} else if (Rejected.class.isInstance(deliveryUpdated.getRemoteState())) {
Rejected remoteState = (Rejected) deliveryUpdated.getRemoteState();
if (remoteState.getError() == null) {
LOG.debug("message [message ID: {}] rejected by peer", messageId);
} else {
LOG.debug("message [message ID: {}] rejected by peer: {}, {}", messageId, remoteState.getError().getCondition(), remoteState.getError().getDescription());
}
} else {
LOG.debug("message [message ID: {}] not accepted by peer: {}", messageId, deliveryUpdated.getRemoteState());
}
} else {
LOG.warn("peer did not settle telemetry message [message ID: {}, remote state: {}]", messageId, deliveryUpdated.getRemoteState());
}
});
LOG.trace("sent telemetry message [ID: {}], remaining credit: {}, queued messages: {}", messageId, sender.getCredit(), sender.getQueued());
return Future.succeededFuture(result);
}
Aggregations