Search in sources :

Example 61 with ErrorCondition

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"));
    }
}
Also used : SpanContext(io.opentracing.SpanContext) CommandContext(org.eclipse.hono.client.command.CommandContext) CommandHandlerWrapper(org.eclipse.hono.client.command.CommandHandlerWrapper) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) NoConsumerException(org.eclipse.hono.client.NoConsumerException) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) Span(io.opentracing.Span)

Example 62 with ErrorCondition

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());
}
Also used : Message(org.apache.qpid.proton.message.Message) ProtonDelivery(io.vertx.proton.ProtonDelivery) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Handler(io.vertx.core.Handler) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) Span(io.opentracing.Span)

Example 63 with ErrorCondition

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();
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) AmqpErrorException(org.eclipse.hono.util.AmqpErrorException) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) SelfSignedCertificate(io.vertx.core.net.SelfSignedCertificate) Function(java.util.function.Function) Constants(org.eclipse.hono.util.Constants) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Timeout(io.vertx.junit5.Timeout) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Symbol(org.apache.qpid.proton.amqp.Symbol) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) Message(org.apache.qpid.proton.message.Message) Binary(org.apache.qpid.proton.amqp.Binary) Tenants(org.eclipse.hono.tests.Tenants) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) MethodSource(org.junit.jupiter.params.provider.MethodSource) Data(org.apache.qpid.proton.amqp.messaging.Data) Device(org.eclipse.hono.service.management.device.Device) MessageContext(org.eclipse.hono.application.client.MessageContext) Truth.assertWithMessage(com.google.common.truth.Truth.assertWithMessage) LinkError(org.apache.qpid.proton.amqp.transport.LinkError) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) DownstreamMessageAssertions(org.eclipse.hono.tests.DownstreamMessageAssertions) ProtonHelper(io.vertx.proton.ProtonHelper) ProtonQoS(io.vertx.proton.ProtonQoS) Truth.assertThat(com.google.common.truth.Truth.assertThat) MessageHelper(org.eclipse.hono.util.MessageHelper) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Buffer(io.vertx.core.buffer.Buffer) Assertions(org.junit.jupiter.api.Assertions) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) ProtonSender(io.vertx.proton.ProtonSender) Handler(io.vertx.core.Handler) Collections(java.util.Collections) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) QoS(org.eclipse.hono.util.QoS) Tenant(org.eclipse.hono.service.management.tenant.Tenant) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) Message(org.apache.qpid.proton.message.Message) Truth.assertWithMessage(com.google.common.truth.Truth.assertWithMessage) VertxTestContext(io.vertx.junit5.VertxTestContext) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Timeout(io.vertx.junit5.Timeout)

Example 64 with ErrorCondition

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();
    }
}
Also used : ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition)

Example 65 with ErrorCondition

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();
    }
}
Also used : ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition)

Aggregations

ErrorCondition (org.apache.qpid.proton.amqp.transport.ErrorCondition)67 Handler (io.vertx.core.Handler)22 ProtonConnection (io.vertx.proton.ProtonConnection)20 Symbol (org.apache.qpid.proton.amqp.Symbol)20 Rejected (org.apache.qpid.proton.amqp.messaging.Rejected)17 Message (org.apache.qpid.proton.message.Message)17 TimeUnit (java.util.concurrent.TimeUnit)14 Vertx (io.vertx.core.Vertx)13 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)13 UnsignedLong (org.apache.qpid.proton.amqp.UnsignedLong)12 DeliveryState (org.apache.qpid.proton.amqp.transport.DeliveryState)12 ProtonReceiver (io.vertx.proton.ProtonReceiver)11 CountDownLatch (java.util.concurrent.CountDownLatch)11 AtomicReference (java.util.concurrent.atomic.AtomicReference)11 Test (org.junit.Test)11 Future (io.vertx.core.Future)10 Promise (io.vertx.core.Promise)10 ProtonSender (io.vertx.proton.ProtonSender)10 AsyncResult (io.vertx.core.AsyncResult)9 Map (java.util.Map)9