Search in sources :

Example 1 with ProtonQoS

use of io.vertx.proton.ProtonQoS in project hono by eclipse.

the class AmqpUploadTestBase method testUploadMessagesUsingSaslExternal.

/**
 * Verifies that a number of messages uploaded to the AMQP adapter using client certificate
 * based authentication can be successfully consumed via the AMQP Messaging Network.
 *
 * @param senderQos The delivery semantics used by the device for uploading messages.
 * @throws InterruptedException if test execution is interrupted.
 */
@ParameterizedTest(name = IntegrationTestSupport.PARAMETERIZED_TEST_NAME_PATTERN)
@MethodSource("senderQoSTypes")
public void testUploadMessagesUsingSaslExternal(final ProtonQoS senderQos) throws InterruptedException {
    final String tenantId = helper.getRandomTenantId();
    final String deviceId = helper.getRandomDeviceId(tenantId);
    final SelfSignedCertificate deviceCert = SelfSignedCertificate.create(deviceId + ".iot.eclipse.org");
    final VertxTestContext setup = new VertxTestContext();
    helper.getCertificate(deviceCert.certificatePath()).compose(cert -> {
        final var tenant = Tenants.createTenantForTrustAnchor(cert);
        prepareTenantConfig(tenant);
        return helper.registry.addDeviceForTenant(tenantId, tenant, deviceId, cert);
    }).compose(ok -> connectToAdapter(deviceCert)).compose(con -> createProducer(null, senderQos)).onComplete(setup.succeeding(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;
        setup.completeNow();
    }));
    assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
    assertWithMessage("adapter connection failure occurred").that(setup.failed()).isFalse();
    testUploadMessages(tenantId, senderQos);
}
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) SelfSignedCertificate(io.vertx.core.net.SelfSignedCertificate) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) VertxTestContext(io.vertx.junit5.VertxTestContext) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 2 with ProtonQoS

use of io.vertx.proton.ProtonQoS in project hono by eclipse.

the class HonoConnectionImpl method createReceiver.

@Override
public Future<ProtonReceiver> createReceiver(final String sourceAddress, final ProtonQoS qos, final ProtonMessageHandler messageHandler, final int preFetchSize, final boolean autoAccept, final Handler<String> remoteCloseHook) {
    Objects.requireNonNull(sourceAddress);
    Objects.requireNonNull(qos);
    Objects.requireNonNull(messageHandler);
    if (preFetchSize < 0) {
        throw new IllegalArgumentException("pre-fetch size must be >= 0");
    }
    return executeOnContext(result -> {
        checkConnected().compose(v -> {
            final Promise<ProtonReceiver> receiverPromise = Promise.promise();
            final ProtonReceiver receiver = session.createReceiver(sourceAddress);
            if (clientConfigProperties.getMaxMessageSize() > ClientConfigProperties.MAX_MESSAGE_SIZE_UNLIMITED) {
                receiver.setMaxMessageSize(new UnsignedLong(clientConfigProperties.getMaxMessageSize()));
            }
            receiver.setAutoAccept(autoAccept);
            receiver.setQoS(qos);
            receiver.setPrefetch(preFetchSize);
            receiver.handler((delivery, message) -> {
                HonoProtonHelper.onReceivedMessageDeliveryUpdatedFromRemote(delivery, d -> log.debug("got unexpected disposition update for received message [remote state: {}]", delivery.getRemoteState()));
                try {
                    messageHandler.handle(delivery, message);
                    if (log.isTraceEnabled()) {
                        final int remainingCredits = receiver.getCredit() - receiver.getQueued();
                        log.trace("handling message [remotely settled: {}, queued messages: {}, remaining credit: {}]", delivery.remotelySettled(), receiver.getQueued(), remainingCredits);
                    }
                } catch (final Exception ex) {
                    log.warn("error handling message", ex);
                    ProtonHelper.released(delivery, true);
                }
            });
            final DisconnectListener<HonoConnection> disconnectBeforeOpenListener = (con) -> {
                log.debug("opening receiver [{}] failed: got disconnected", sourceAddress);
                receiverPromise.tryFail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "not connected"));
            };
            oneTimeDisconnectListeners.add(disconnectBeforeOpenListener);
            receiver.openHandler(recvOpen -> {
                oneTimeDisconnectListeners.remove(disconnectBeforeOpenListener);
                // the result future may have already been completed here in case of a link establishment timeout
                if (receiverPromise.future().isComplete()) {
                    log.debug("ignoring server response for opening receiver [{}]: receiver creation already timed out", sourceAddress);
                } else if (recvOpen.failed()) {
                    // this means that we have received the peer's attach
                    // and the subsequent detach frame in one TCP read
                    final ErrorCondition error = receiver.getRemoteCondition();
                    if (error == null) {
                        log.debug("opening receiver [{}] failed", sourceAddress, recvOpen.cause());
                        receiverPromise.tryFail(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, "cannot open receiver", recvOpen.cause()));
                    } else {
                        log.debug("opening receiver [{}] failed: {} - {}", sourceAddress, error.getCondition(), error.getDescription());
                        receiverPromise.tryFail(StatusCodeMapper.fromAttachError(error));
                    }
                } else if (HonoProtonHelper.isLinkEstablished(receiver)) {
                    log.debug("receiver open [source: {}]", sourceAddress);
                    receiverPromise.tryComplete(recvOpen.result());
                } else {
                    // this means that the peer did not create a local terminus for the link
                    // and will send a detach frame for closing the link very shortly
                    // see AMQP 1.0 spec section 2.6.3
                    log.debug("peer did not create terminus for source [{}] and will detach the link", sourceAddress);
                    receiverPromise.tryFail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE));
                }
            });
            HonoProtonHelper.setDetachHandler(receiver, remoteDetached -> onRemoteDetach(receiver, connection.getRemoteContainer(), false, remoteCloseHook));
            HonoProtonHelper.setCloseHandler(receiver, remoteClosed -> onRemoteDetach(receiver, connection.getRemoteContainer(), true, remoteCloseHook));
            receiver.open();
            vertx.setTimer(clientConfigProperties.getLinkEstablishmentTimeout(), tid -> {
                final boolean notOpenedAndNotDisconnectedYet = oneTimeDisconnectListeners.remove(disconnectBeforeOpenListener);
                if (notOpenedAndNotDisconnectedYet) {
                    onLinkEstablishmentTimeout(receiver, clientConfigProperties, receiverPromise);
                }
            });
            return receiverPromise.future();
        }).onComplete(result);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) Arrays(java.util.Arrays) LoggerFactory(org.slf4j.LoggerFactory) Context(io.vertx.core.Context) HonoProtonHelper(org.eclipse.hono.util.HonoProtonHelper) ConnectionFactory(org.eclipse.hono.connection.ConnectionFactory) SaslSystemException(io.vertx.proton.sasl.SaslSystemException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) DisconnectListener(org.eclipse.hono.client.DisconnectListener) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) MechanismMismatchException(io.vertx.proton.sasl.MechanismMismatchException) ProtonQoS(io.vertx.proton.ProtonQoS) UUID(java.util.UUID) Future(io.vertx.core.Future) Objects(java.util.Objects) CountDownLatch(java.util.concurrent.CountDownLatch) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ReconnectListener(org.eclipse.hono.client.ReconnectListener) List(java.util.List) SSLException(javax.net.ssl.SSLException) Optional(java.util.Optional) ProtonSender(io.vertx.proton.ProtonSender) AuthenticationException(javax.security.sasl.AuthenticationException) ProtonLink(io.vertx.proton.ProtonLink) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) ProtonSession(io.vertx.proton.ProtonSession) ProtonClientOptions(io.vertx.proton.ProtonClientOptions) Symbol(org.apache.qpid.proton.amqp.Symbol) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) AsyncResult(io.vertx.core.AsyncResult) HonoConnection(org.eclipse.hono.client.HonoConnection) Logger(org.slf4j.Logger) VertxInternal(io.vertx.core.impl.VertxInternal) Iterator(java.util.Iterator) Tracer(io.opentracing.Tracer) NoopTracerFactory(io.opentracing.noop.NoopTracerFactory) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) TimeUnit(java.util.concurrent.TimeUnit) Handler(io.vertx.core.Handler) Collections(java.util.Collections) ProtonReceiver(io.vertx.proton.ProtonReceiver) Promise(io.vertx.core.Promise) DisconnectListener(org.eclipse.hono.client.DisconnectListener) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServerErrorException(org.eclipse.hono.client.ServerErrorException) SaslSystemException(io.vertx.proton.sasl.SaslSystemException) MechanismMismatchException(io.vertx.proton.sasl.MechanismMismatchException) SSLException(javax.net.ssl.SSLException) AuthenticationException(javax.security.sasl.AuthenticationException) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) ServerErrorException(org.eclipse.hono.client.ServerErrorException)

Example 3 with ProtonQoS

use of io.vertx.proton.ProtonQoS in project hono by eclipse.

the class HonoConnectionImpl method createSender.

/**
 * Creates a sender link.
 *
 * @param targetAddress The target address of the link. If the address is {@code null}, the
 *                      sender link will be established to the 'anonymous relay' and each
 *                      message must specify its destination address.
 * @param qos The quality of service to use for the link.
 * @param closeHook The handler to invoke when the link is closed by the peer (may be {@code null}).
 * @return A future for the created link. The future will be completed once the link is open.
 *         The future will fail with a {@link ServiceInvocationException} if the link cannot be opened.
 * @throws NullPointerException if qos is {@code null}.
 */
@Override
public final Future<ProtonSender> createSender(final String targetAddress, final ProtonQoS qos, final Handler<String> closeHook) {
    Objects.requireNonNull(qos);
    return executeOnContext(result -> {
        checkConnected().compose(v -> {
            if (targetAddress == null && !supportsCapability(Constants.CAP_ANONYMOUS_RELAY)) {
                // before a client can use anonymous terminus
                return Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_NOT_IMPLEMENTED, "server does not support anonymous terminus"));
            }
            final Promise<ProtonSender> senderPromise = Promise.promise();
            final ProtonSender sender = session.createSender(targetAddress);
            sender.setQoS(qos);
            sender.setAutoSettle(true);
            final DisconnectListener<HonoConnection> disconnectBeforeOpenListener = (con) -> {
                log.debug("opening sender [{}] failed: got disconnected", targetAddress);
                senderPromise.tryFail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "not connected"));
            };
            oneTimeDisconnectListeners.add(disconnectBeforeOpenListener);
            sender.openHandler(senderOpen -> {
                oneTimeDisconnectListeners.remove(disconnectBeforeOpenListener);
                // the result future may have already been completed here in case of a link establishment timeout
                if (senderPromise.future().isComplete()) {
                    log.debug("ignoring server response for opening sender [{}]: sender creation already timed out", targetAddress);
                } else if (senderOpen.failed()) {
                    // this means that we have received the peer's attach
                    // and the subsequent detach frame in one TCP read
                    final ErrorCondition error = sender.getRemoteCondition();
                    if (error == null) {
                        log.debug("opening sender [{}] failed", targetAddress, senderOpen.cause());
                        senderPromise.tryFail(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, "cannot open sender", senderOpen.cause()));
                    } else {
                        log.debug("opening sender [{}] failed: {} - {}", targetAddress, error.getCondition(), error.getDescription());
                        senderPromise.tryFail(StatusCodeMapper.fromAttachError(error));
                    }
                } else if (HonoProtonHelper.isLinkEstablished(sender)) {
                    log.debug("sender open [target: {}, sendQueueFull: {}, remote max-message-size: {}]", targetAddress, sender.sendQueueFull(), sender.getRemoteMaxMessageSize());
                    final long remoteMaxMessageSize = Optional.ofNullable(sender.getRemoteMaxMessageSize()).map(UnsignedLong::longValue).orElse(0L);
                    if (remoteMaxMessageSize > 0 && remoteMaxMessageSize < clientConfigProperties.getMinMaxMessageSize()) {
                        // peer won't accept our (biggest) messages
                        sender.close();
                        final String msg = String.format("peer does not support minimum max-message-size [required: %d, supported: %d", clientConfigProperties.getMinMaxMessageSize(), remoteMaxMessageSize);
                        log.debug(msg);
                        senderPromise.tryFail(new ClientErrorException(HttpURLConnection.HTTP_PRECON_FAILED, msg));
                    } else if (sender.getCredit() <= 0) {
                        // wait on credits a little time, if not already given
                        final long waitOnCreditsTimerId = vertx.setTimer(clientConfigProperties.getFlowLatency(), timerID -> {
                            log.debug("sender [target: {}] has {} credits after grace period of {}ms", targetAddress, sender.getCredit(), clientConfigProperties.getFlowLatency());
                            sender.sendQueueDrainHandler(null);
                            senderPromise.tryComplete(sender);
                        });
                        sender.sendQueueDrainHandler(replenishedSender -> {
                            log.debug("sender [target: {}] has received {} initial credits", targetAddress, replenishedSender.getCredit());
                            if (vertx.cancelTimer(waitOnCreditsTimerId)) {
                                result.tryComplete(replenishedSender);
                                replenishedSender.sendQueueDrainHandler(null);
                            }
                        // otherwise the timer has already completed the future and cleaned up
                        // sendQueueDrainHandler
                        });
                    } else {
                        senderPromise.tryComplete(sender);
                    }
                } else {
                    // this means that the peer did not create a local terminus for the link
                    // and will send a detach frame for closing the link very shortly
                    // see AMQP 1.0 spec section 2.6.3
                    log.debug("peer did not create terminus for target [{}] and will detach the link", targetAddress);
                    senderPromise.tryFail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE));
                }
            });
            HonoProtonHelper.setDetachHandler(sender, remoteDetached -> onRemoteDetach(sender, connection.getRemoteContainer(), false, closeHook));
            HonoProtonHelper.setCloseHandler(sender, remoteClosed -> onRemoteDetach(sender, connection.getRemoteContainer(), true, closeHook));
            sender.open();
            vertx.setTimer(clientConfigProperties.getLinkEstablishmentTimeout(), tid -> {
                final boolean notOpenedAndNotDisconnectedYet = oneTimeDisconnectListeners.remove(disconnectBeforeOpenListener);
                if (notOpenedAndNotDisconnectedYet) {
                    onLinkEstablishmentTimeout(sender, clientConfigProperties, senderPromise);
                }
            });
            return senderPromise.future();
        }).onComplete(result);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) Arrays(java.util.Arrays) LoggerFactory(org.slf4j.LoggerFactory) Context(io.vertx.core.Context) HonoProtonHelper(org.eclipse.hono.util.HonoProtonHelper) ConnectionFactory(org.eclipse.hono.connection.ConnectionFactory) SaslSystemException(io.vertx.proton.sasl.SaslSystemException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) DisconnectListener(org.eclipse.hono.client.DisconnectListener) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) MechanismMismatchException(io.vertx.proton.sasl.MechanismMismatchException) ProtonQoS(io.vertx.proton.ProtonQoS) UUID(java.util.UUID) Future(io.vertx.core.Future) Objects(java.util.Objects) CountDownLatch(java.util.concurrent.CountDownLatch) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ReconnectListener(org.eclipse.hono.client.ReconnectListener) List(java.util.List) SSLException(javax.net.ssl.SSLException) Optional(java.util.Optional) ProtonSender(io.vertx.proton.ProtonSender) AuthenticationException(javax.security.sasl.AuthenticationException) ProtonLink(io.vertx.proton.ProtonLink) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) ProtonSession(io.vertx.proton.ProtonSession) ProtonClientOptions(io.vertx.proton.ProtonClientOptions) Symbol(org.apache.qpid.proton.amqp.Symbol) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) AsyncResult(io.vertx.core.AsyncResult) HonoConnection(org.eclipse.hono.client.HonoConnection) Logger(org.slf4j.Logger) VertxInternal(io.vertx.core.impl.VertxInternal) Iterator(java.util.Iterator) Tracer(io.opentracing.Tracer) NoopTracerFactory(io.opentracing.noop.NoopTracerFactory) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) TimeUnit(java.util.concurrent.TimeUnit) Handler(io.vertx.core.Handler) Collections(java.util.Collections) Promise(io.vertx.core.Promise) ProtonSender(io.vertx.proton.ProtonSender) DisconnectListener(org.eclipse.hono.client.DisconnectListener) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServerErrorException(org.eclipse.hono.client.ServerErrorException)

Example 4 with ProtonQoS

use of io.vertx.proton.ProtonQoS in project hono by eclipse.

the class AmqpUploadTestBase method testUploadMessagesUsingSaslPlain.

/**
 * Verifies that a number of messages published through the AMQP adapter can be successfully consumed by
 * applications connected to the AMQP messaging network.
 *
 * @param senderQos The delivery semantics to use for the device.
 * @throws InterruptedException if test is interrupted while running.
 */
@ParameterizedTest(name = IntegrationTestSupport.PARAMETERIZED_TEST_NAME_PATTERN)
@MethodSource("senderQoSTypes")
public void testUploadMessagesUsingSaslPlain(final ProtonQoS senderQos) throws InterruptedException {
    final String tenantId = helper.getRandomTenantId();
    final String deviceId = helper.getRandomDeviceId(tenantId);
    final Tenant tenantConfig = new Tenant();
    prepareTenantConfig(tenantConfig);
    final VertxTestContext setup = new VertxTestContext();
    setupProtocolAdapter(tenantId, tenantConfig, deviceId, senderQos).onComplete(setup.succeeding(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;
        setup.completeNow();
    }));
    assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
    assertWithMessage("adapter connection failure occurred").that(setup.failed()).isFalse();
    testUploadMessages(tenantId, senderQos);
}
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) VertxTestContext(io.vertx.junit5.VertxTestContext) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 5 with ProtonQoS

use of io.vertx.proton.ProtonQoS in project hono by eclipse.

the class AmqpUploadTestBase method testUploadMessages.

// ------------------------------------------< private methods >---
private void testUploadMessages(final String tenantId, final ProtonQoS senderQoS) throws InterruptedException {
    final VertxTestContext messageSending = new VertxTestContext();
    final Function<Handler<Void>, Future<Void>> receiver = callback -> {
        return createConsumer(tenantId, msg -> {
            if (log.isTraceEnabled()) {
                log.trace("received message [{}]: {}", msg.getContentType(), msg.getPayload().toString());
            }
            messageSending.verify(() -> {
                DownstreamMessageAssertions.assertTelemetryMessageProperties(msg, tenantId);
                assertThat(msg.getQos()).isEqualTo(AmqpUploadTestBase.getQoS(senderQoS));
                assertAdditionalMessageProperties(msg);
                callback.handle(null);
            });
        }).mapEmpty();
    };
    doUploadMessages(messageSending, receiver, payload -> {
        final Message msg = ProtonHelper.message();
        MessageHelper.setPayload(msg, "opaque/binary", payload);
        msg.setAddress(getEndpointName());
        final Promise<Void> sendingComplete = Promise.promise();
        final Handler<ProtonSender> sendMsgHandler = replenishedSender -> {
            replenishedSender.sendQueueDrainHandler(null);
            switch(senderQoS) {
                case AT_LEAST_ONCE:
                    replenishedSender.send(msg, delivery -> {
                        if (Accepted.class.isInstance(delivery.getRemoteState())) {
                            sendingComplete.complete();
                        } else {
                            sendingComplete.fail(AmqpErrorException.from(delivery.getRemoteState()));
                        }
                    });
                    break;
                case AT_MOST_ONCE:
                    replenishedSender.send(msg);
                    sendingComplete.complete();
                    break;
            }
        };
        context.runOnContext(go -> {
            if (sender.getCredit() <= 0) {
                log.trace("wait for credit ...");
                sender.sendQueueDrainHandler(sendMsgHandler);
            } else {
                sendMsgHandler.handle(sender);
            }
        });
        return sendingComplete.future();
    });
}
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) ProtonSender(io.vertx.proton.ProtonSender) 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) Handler(io.vertx.core.Handler) Future(io.vertx.core.Future) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted)

Aggregations

Future (io.vertx.core.Future)5 Handler (io.vertx.core.Handler)5 Promise (io.vertx.core.Promise)5 ProtonHelper (io.vertx.proton.ProtonHelper)5 ProtonQoS (io.vertx.proton.ProtonQoS)5 ProtonSender (io.vertx.proton.ProtonSender)5 HttpURLConnection (java.net.HttpURLConnection)5 Collections (java.util.Collections)5 CountDownLatch (java.util.concurrent.CountDownLatch)5 TimeUnit (java.util.concurrent.TimeUnit)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 Symbol (org.apache.qpid.proton.amqp.Symbol)5 UnsignedLong (org.apache.qpid.proton.amqp.UnsignedLong)5 ErrorCondition (org.apache.qpid.proton.amqp.transport.ErrorCondition)5 ServerErrorException (org.eclipse.hono.client.ServerErrorException)5 Constants (org.eclipse.hono.util.Constants)5 Truth.assertThat (com.google.common.truth.Truth.assertThat)3 Truth.assertWithMessage (com.google.common.truth.Truth.assertWithMessage)3 Buffer (io.vertx.core.buffer.Buffer)3 SelfSignedCertificate (io.vertx.core.net.SelfSignedCertificate)3