use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project hono by eclipse.
the class ProtonBasedInternalCommandConsumer method handleCommandMessage.
void handleCommandMessage(final ProtonDelivery delivery, final Message msg) {
final ProtonBasedCommand command;
try {
command = ProtonBasedCommand.fromRoutedCommandMessage(msg);
} catch (final IllegalArgumentException e) {
log.debug("address of command message is invalid: {}", msg.getAddress());
final Rejected rejected = new Rejected();
rejected.setError(new ErrorCondition(Constants.AMQP_BAD_REQUEST, "invalid command target address"));
delivery.disposition(rejected, true);
return;
}
final CommandHandlerWrapper commandHandler = commandHandlers.getCommandHandler(command.getTenant(), command.getGatewayOrDeviceId());
if (commandHandler != null && commandHandler.getGatewayId() != null) {
// Gateway information set in command handler means a gateway has subscribed for commands for a specific device.
// This information isn't getting set in the message (by the Command Router) and therefore has to be adopted manually here.
command.setGatewayId(commandHandler.getGatewayId());
}
final SpanContext spanContext = TracingHelper.extractSpanContext(tracer, msg);
final SpanContext followsFromSpanContext = commandHandler != null ? commandHandler.getConsumerCreationSpanContext() : null;
final Span currentSpan = CommandContext.createSpan(tracer, command, spanContext, followsFromSpanContext, getClass().getSimpleName());
currentSpan.setTag(MessageHelper.APP_PROPERTY_ADAPTER_INSTANCE_ID, adapterInstanceId);
final CommandContext commandContext = new ProtonBasedCommandContext(command, delivery, currentSpan);
if (commandHandler != null) {
log.trace("using [{}] for received command [{}]", commandHandler, command);
// command.isValid() check not done here - it is to be done in the command handler
commandHandler.handleCommand(commandContext);
} else {
log.info("no command handler found for command [{}]", command);
commandContext.release(new NoConsumerException("no command handler found for command"));
}
}
use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project hono by eclipse.
the class GenericSenderLinkTest method testSendAndWaitForOutcomeFailsForRejectedOutcome.
private void testSendAndWaitForOutcomeFailsForRejectedOutcome(final Symbol errorCondition, final Consumer<Throwable> failureAssertions) {
// GIVEN a sender that has credit
when(sender.sendQueueFull()).thenReturn(Boolean.FALSE);
// WHEN trying to send a message
final Span span = mock(Span.class);
final Message message = ProtonHelper.message("some payload");
message.setContentType("text/plain");
MessageHelper.addDeviceId(message, "device");
final Future<ProtonDelivery> result = messageSender.sendAndWaitForOutcome(message, span);
// THEN the message has been sent
final ArgumentCaptor<Handler<ProtonDelivery>> deliveryUpdateHandler = VertxMockSupport.argumentCaptorHandler();
verify(sender).send(any(Message.class), deliveryUpdateHandler.capture());
// but the request is not completed
assertThat(result.isComplete()).isFalse();
// and when the peer rejects the message
final var condition = new ErrorCondition();
condition.setCondition(errorCondition);
final var error = new Rejected();
error.setError(condition);
final ProtonDelivery rejected = mock(ProtonDelivery.class);
when(rejected.remotelySettled()).thenReturn(Boolean.TRUE);
when(rejected.getRemoteState()).thenReturn(error);
deliveryUpdateHandler.getValue().handle(rejected);
// the request is failed
assertThat(result.failed()).isTrue();
// with the expected error
failureAssertions.accept(result.cause());
}
use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project hono by eclipse.
the class AmqpUploadTestBase method testAdapterRejectsBadInboundMessage.
/**
* Verifies that a message containing a payload which has the <em>empty notification</em>
* content type is rejected by the adapter.
*
* @param context The Vert.x context for running asynchronous tests.
* @throws InterruptedException if test is interrupted while running.
*/
@Test
@Timeout(timeUnit = TimeUnit.SECONDS, value = 10)
public void testAdapterRejectsBadInboundMessage(final VertxTestContext context) throws InterruptedException {
final String tenantId = helper.getRandomTenantId();
final String deviceId = helper.getRandomDeviceId(tenantId);
final VertxTestContext setup = new VertxTestContext();
setupProtocolAdapter(tenantId, new Tenant(), deviceId, ProtonQoS.AT_LEAST_ONCE).map(s -> {
setup.verify(() -> {
final UnsignedLong maxMessageSize = s.getRemoteMaxMessageSize();
assertWithMessage("max-message-size included in adapter's attach frame").that(maxMessageSize).isNotNull();
assertWithMessage("max-message-size").that(maxMessageSize.longValue()).isGreaterThan(0);
});
sender = s;
return s;
}).onComplete(setup.succeedingThenComplete());
assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
if (setup.failed()) {
context.failNow(setup.causeOfFailure());
return;
}
final Message msg = ProtonHelper.message("some payload");
msg.setContentType(EventConstants.CONTENT_TYPE_EMPTY_NOTIFICATION);
msg.setAddress(getEndpointName());
sender.send(msg, delivery -> {
context.verify(() -> {
assertThat(delivery.getRemoteState()).isInstanceOf(Rejected.class);
final Rejected rejected = (Rejected) delivery.getRemoteState();
final ErrorCondition error = rejected.getError();
assertThat((Object) error.getCondition()).isEqualTo(Constants.AMQP_BAD_REQUEST);
});
context.completeNow();
});
}
use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project azure-iot-sdk-java by Azure.
the class AmqpsIotHubConnection method onConnectionRemoteClose.
@Override
public void onConnectionRemoteClose(Event event) {
Connection connection = event.getConnection();
if (connection.getLocalState() == EndpointState.ACTIVE) {
ErrorCondition errorCondition = connection.getRemoteCondition();
this.savedException = AmqpsExceptionTranslator.convertFromAmqpException(errorCondition);
log.error("Amqp connection was closed remotely", this.savedException);
this.connection.close();
} else {
log.trace("Closing reactor since connection has closed");
event.getReactor().stop();
}
}
use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project azure-iot-sdk-java by Azure.
the class AmqpsIotHubConnection method onTransportError.
@Override
public void onTransportError(Event event) {
super.onTransportError(event);
this.state = IotHubConnectionStatus.DISCONNECTED;
// Error may be on remote, and it may be local
ErrorCondition errorCondition = event.getTransport().getRemoteCondition();
// Sometimes the remote errorCondition object is not null, but all of its fields are null. In this case, check the local error condition
// for the error details.
boolean isALocalErrorCondition = false;
if (errorCondition == null || (errorCondition.getCondition() == null && errorCondition.getDescription() == null && errorCondition.getInfo() == null)) {
errorCondition = event.getTransport().getCondition();
isALocalErrorCondition = true;
}
this.savedException = AmqpsExceptionTranslator.convertFromAmqpException(errorCondition);
// onConnectionLocalClose. Proton will not queue the CONNECTION_LOCAL_CLOSE event since the Endpoint status is CLOSED
if (event.getConnection().getLocalState() == EndpointState.CLOSED && isALocalErrorCondition) {
log.error("Amqp transport error occurred, calling onConnectionLocalClose", this.savedException);
onConnectionLocalClose(event);
} else {
log.error("Amqp transport error occurred, closing the AMQPS connection", this.savedException);
event.getConnection().close();
}
}
Aggregations