Search in sources :

Example 96 with Span

use of io.opentracing.Span in project hono by eclipse.

the class VertxBasedAmqpProtocolAdapter method closeDeviceConnection.

/**
 * Actively closes the connection to the device.
 */
private void closeDeviceConnection(final ProtonConnection con, final String reason, final boolean sendDisconnectedEvent) {
    final Device authenticatedDevice = getAuthenticatedDevice(con);
    final Span span = newSpan("close device connection", authenticatedDevice, getTraceSamplingPriority(con));
    final Map<String, String> logFields = new HashMap<>(2);
    logFields.put(Fields.EVENT, "closing device connection");
    Optional.ofNullable(reason).ifPresent(r -> logFields.put("reason", r));
    span.log(logFields);
    log.debug("closing device connection [container: {}, {}]; reason: {}", con.getRemoteContainer(), authenticatedDevice, reason);
    con.closeHandler(connection -> {
    });
    con.disconnectHandler(connection -> {
    });
    con.close();
    con.disconnect();
    handleConnectionLossInternal(con, span, authenticatedDevice, sendDisconnectedEvent).onComplete(ar -> span.finish());
}
Also used : HashMap(java.util.HashMap) Device(org.eclipse.hono.auth.Device) Span(io.opentracing.Span)

Example 97 with Span

use of io.opentracing.Span in project hono by eclipse.

the class VertxBasedAmqpProtocolAdapter method createCommandConsumer.

private Future<CommandConsumer> createCommandConsumer(final ProtonSender sender, final ResourceIdentifier sourceAddress, final Device authenticatedDevice, final Span span) {
    final Handler<CommandContext> commandHandler = commandContext -> {
        final Sample timer = metrics.startTimer();
        addMicrometerSample(commandContext, timer);
        Tags.COMPONENT.set(commandContext.getTracingSpan(), getTypeName());
        final Command command = commandContext.getCommand();
        final Future<TenantObject> tenantTracker = getTenantConfiguration(sourceAddress.getTenantId(), commandContext.getTracingContext());
        tenantTracker.compose(tenantObject -> {
            if (!command.isValid()) {
                return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "malformed command message"));
            }
            if (!HonoProtonHelper.isLinkOpenAndConnected(sender)) {
                return Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "sender link is not open"));
            }
            return checkMessageLimit(tenantObject, command.getPayloadSize(), commandContext.getTracingContext());
        }).compose(success -> {
            // check the via-gateways, ensuring that the gateway may act on behalf of the device at this point in time
            if (authenticatedDevice != null && !authenticatedDevice.getDeviceId().equals(sourceAddress.getResourceId())) {
                return getRegistrationAssertion(authenticatedDevice.getTenantId(), sourceAddress.getResourceId(), authenticatedDevice, commandContext.getTracingContext());
            }
            return Future.succeededFuture();
        }).compose(success -> {
            onCommandReceived(tenantTracker.result(), sender, commandContext);
            return Future.succeededFuture();
        }).otherwise(failure -> {
            if (failure instanceof ClientErrorException) {
                commandContext.reject(failure);
            } else {
                commandContext.release(failure);
            }
            metrics.reportCommand(command.isOneWay() ? Direction.ONE_WAY : Direction.REQUEST, sourceAddress.getTenantId(), tenantTracker.result(), ProcessingOutcome.from(failure), command.getPayloadSize(), timer);
            return null;
        });
    };
    final Future<RegistrationAssertion> tokenTracker = Optional.ofNullable(authenticatedDevice).map(v -> getRegistrationAssertion(authenticatedDevice.getTenantId(), sourceAddress.getResourceId(), authenticatedDevice, span.context())).orElseGet(Future::succeededFuture);
    if (authenticatedDevice != null && !authenticatedDevice.getDeviceId().equals(sourceAddress.getResourceId())) {
        // gateway scenario
        return tokenTracker.compose(v -> getCommandConsumerFactory().createCommandConsumer(sourceAddress.getTenantId(), sourceAddress.getResourceId(), authenticatedDevice.getDeviceId(), commandHandler, null, span.context()));
    } else {
        return tokenTracker.compose(v -> getCommandConsumerFactory().createCommandConsumer(sourceAddress.getTenantId(), sourceAddress.getResourceId(), commandHandler, null, span.context()));
    }
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) Tags(io.opentracing.tag.Tags) ProtonServer(io.vertx.proton.ProtonServer) HonoProtonHelper(org.eclipse.hono.util.HonoProtonHelper) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) Modified(org.apache.qpid.proton.amqp.messaging.Modified) DeviceCredentials(org.eclipse.hono.adapter.auth.device.DeviceCredentials) Map(java.util.Map) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) AuthorizationException(org.eclipse.hono.adapter.AuthorizationException) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Fields(io.opentracing.log.Fields) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) TracingHelper(org.eclipse.hono.tracing.TracingHelper) ProtonSaslAuthenticatorFactory(io.vertx.proton.sasl.ProtonSaslAuthenticatorFactory) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) TenantServiceBasedX509Authentication(org.eclipse.hono.adapter.auth.device.TenantServiceBasedX509Authentication) Predicate(java.util.function.Predicate) Collection(java.util.Collection) CommandContext(org.eclipse.hono.client.command.CommandContext) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) ProtonQoS(io.vertx.proton.ProtonQoS) MessageHelper(org.eclipse.hono.util.MessageHelper) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) Objects(java.util.Objects) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) List(java.util.List) QoS(org.eclipse.hono.service.metric.MetricsTags.QoS) TenantTraceSamplingHelper(org.eclipse.hono.tracing.TenantTraceSamplingHelper) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Optional(java.util.Optional) Span(io.opentracing.Span) ProtonSender(io.vertx.proton.ProtonSender) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) ProtonLink(io.vertx.proton.ProtonLink) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) ProtonServerOptions(io.vertx.proton.ProtonServerOptions) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) ConnectionLimitManager(org.eclipse.hono.adapter.limiting.ConnectionLimitManager) Command(org.eclipse.hono.client.command.Command) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) ClientErrorException(org.eclipse.hono.client.ClientErrorException) AdapterDisabledException(org.eclipse.hono.adapter.AdapterDisabledException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) OptionalInt(java.util.OptionalInt) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Commands(org.eclipse.hono.client.command.Commands) Constants(org.eclipse.hono.util.Constants) CompositeFuture(io.vertx.core.CompositeFuture) ProtonSession(io.vertx.proton.ProtonSession) Symbol(org.apache.qpid.proton.amqp.Symbol) AdapterConnectionsExceededException(org.eclipse.hono.adapter.AdapterConnectionsExceededException) Target(org.apache.qpid.proton.amqp.transport.Target) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) Message(org.apache.qpid.proton.message.Message) HttpUtils(org.eclipse.hono.service.http.HttpUtils) AsyncResult(io.vertx.core.AsyncResult) CommandConstants(org.eclipse.hono.util.CommandConstants) TenantChangeNotification(org.eclipse.hono.notification.deviceregistry.TenantChangeNotification) Strings(org.eclipse.hono.util.Strings) UsernamePasswordAuthProvider(org.eclipse.hono.adapter.auth.device.UsernamePasswordAuthProvider) CredentialsApiAuthProvider(org.eclipse.hono.adapter.auth.device.CredentialsApiAuthProvider) AbstractProtocolAdapterBase(org.eclipse.hono.adapter.AbstractProtocolAdapterBase) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) Sample(io.micrometer.core.instrument.Timer.Sample) Released(org.apache.qpid.proton.amqp.messaging.Released) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) Source(org.apache.qpid.proton.amqp.transport.Source) ConnectionAttemptOutcome(org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome) MemoryBasedConnectionLimitStrategy(org.eclipse.hono.adapter.limiting.MemoryBasedConnectionLimitStrategy) X509AuthProvider(org.eclipse.hono.adapter.auth.device.X509AuthProvider) Handler(io.vertx.core.Handler) Collections(java.util.Collections) DefaultConnectionLimitManager(org.eclipse.hono.adapter.limiting.DefaultConnectionLimitManager) CommandContext(org.eclipse.hono.client.command.CommandContext) Command(org.eclipse.hono.client.command.Command) Sample(io.micrometer.core.instrument.Timer.Sample) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) Future(io.vertx.core.Future) CompositeFuture(io.vertx.core.CompositeFuture) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServerErrorException(org.eclipse.hono.client.ServerErrorException)

Example 98 with Span

use of io.opentracing.Span in project hono by eclipse.

the class AbstractHonoResource method doUploadMessage.

/**
 * Forwards a message to the south bound Telemetry or Event API of the messaging infrastructure configured
 * for the tenant that the origin device belongs to.
 * <p>
 * Depending on the outcome of the attempt to upload the message, the CoAP response code is set as
 * described by the <a href="https://www.eclipse.org/hono/docs/user-guide/coap-adapter/">CoAP adapter user guide</a>
 *
 * @param context The request that contains the uploaded message.
 * @param endpoint The type of API endpoint to forward the message to.
 * @return A future indicating the outcome of the operation.
 *         The future will be succeeded if the message has been forwarded successfully.
 *         In this case one of the context's <em>respond</em> methods will have been invoked to send a CoAP response
 *         back to the device.
 *         Otherwise the future will be failed with a {@link org.eclipse.hono.client.ServiceInvocationException}.
 * @throws NullPointerException if any of the parameters are {@code null}.
 */
protected final Future<Void> doUploadMessage(final CoapContext context, final MetricsTags.EndpointType endpoint) {
    Objects.requireNonNull(context);
    Objects.requireNonNull(endpoint);
    final String contentType = context.getContentType();
    final Buffer payload = context.getPayload();
    if (contentType == null) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "request message must contain content-format option"));
    } else if (payload.length() == 0 && !context.isEmptyNotification()) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "request contains no body but is not marked as empty notification"));
    } else {
        final String gatewayId = context.getGatewayId();
        final String tenantId = context.getOriginDevice().getTenantId();
        final String deviceId = context.getOriginDevice().getDeviceId();
        final MetricsTags.QoS qos = context.isConfirmable() ? MetricsTags.QoS.AT_LEAST_ONCE : MetricsTags.QoS.AT_MOST_ONCE;
        final Span currentSpan = TracingHelper.buildChildSpan(getTracer(), context.getTracingContext(), "upload " + endpoint.getCanonicalName(), getAdapter().getTypeName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_TENANT_ID, tenantId).withTag(TracingHelper.TAG_DEVICE_ID, deviceId).withTag(TracingHelper.TAG_AUTHENTICATED.getKey(), context.isDeviceAuthenticated()).withTag(Constants.HEADER_QOS_LEVEL, qos.asTag().getValue()).start();
        final Promise<Void> responseReady = Promise.promise();
        final Future<RegistrationAssertion> tokenTracker = getAdapter().getRegistrationAssertion(tenantId, deviceId, context.getAuthenticatedDevice(), currentSpan.context());
        final Future<TenantObject> tenantTracker = getAdapter().getTenantClient().get(tenantId, currentSpan.context());
        final Future<TenantObject> tenantValidationTracker = tenantTracker.compose(tenantObject -> CompositeFuture.all(getAdapter().isAdapterEnabled(tenantObject), getAdapter().checkMessageLimit(tenantObject, payload.length(), currentSpan.context())).map(tenantObject));
        // we only need to consider TTD if the device and tenant are enabled and the adapter
        // is enabled for the tenant
        final Future<Integer> ttdTracker = CompositeFuture.all(tenantValidationTracker, tokenTracker).compose(ok -> {
            final Integer ttdParam = context.getTimeUntilDisconnect();
            return getAdapter().getTimeUntilDisconnect(tenantTracker.result(), ttdParam).map(effectiveTtd -> {
                if (effectiveTtd != null) {
                    currentSpan.setTag(MessageHelper.APP_PROPERTY_DEVICE_TTD, effectiveTtd);
                }
                return effectiveTtd;
            });
        });
        final Future<CommandConsumer> commandConsumerTracker = ttdTracker.compose(ttd -> createCommandConsumer(ttd, tenantTracker.result(), deviceId, gatewayId, context, responseReady, currentSpan));
        return commandConsumerTracker.compose(commandConsumer -> {
            final Map<String, Object> props = getAdapter().getDownstreamMessageProperties(context);
            Optional.ofNullable(commandConsumer).map(c -> ttdTracker.result()).ifPresent(ttd -> props.put(MessageHelper.APP_PROPERTY_DEVICE_TTD, ttd));
            customizeDownstreamMessageProperties(props, context);
            if (context.isConfirmable()) {
                context.startAcceptTimer(vertx, tenantTracker.result(), getAdapter().getConfig().getTimeoutToAck());
            }
            final Future<Void> sendResult;
            if (endpoint == EndpointType.EVENT) {
                sendResult = getAdapter().getEventSender(tenantValidationTracker.result()).sendEvent(tenantTracker.result(), tokenTracker.result(), contentType, payload, props, currentSpan.context());
            } else {
                sendResult = getAdapter().getTelemetrySender(tenantValidationTracker.result()).sendTelemetry(tenantTracker.result(), tokenTracker.result(), context.getRequestedQos(), contentType, payload, props, currentSpan.context());
            }
            return CompositeFuture.all(sendResult, responseReady.future()).mapEmpty();
        }).compose(proceed -> {
            // request and the CommandConsumer from the current request has not been closed yet
            return Optional.ofNullable(commandConsumerTracker.result()).map(consumer -> consumer.close(currentSpan.context()).otherwise(thr -> {
                TracingHelper.logError(currentSpan, thr);
                return (Void) null;
            })).orElseGet(Future::succeededFuture);
        }).map(proceed -> {
            final CommandContext commandContext = context.get(CommandContext.KEY_COMMAND_CONTEXT);
            final Response response = new Response(ResponseCode.CHANGED);
            if (commandContext != null) {
                addCommandToResponse(response, commandContext, currentSpan);
                commandContext.accept();
                getAdapter().getMetrics().reportCommand(commandContext.getCommand().isOneWay() ? Direction.ONE_WAY : Direction.REQUEST, tenantId, tenantTracker.result(), ProcessingOutcome.FORWARDED, commandContext.getCommand().getPayloadSize(), getMicrometerSample(commandContext));
            }
            LOG.trace("successfully processed message for device [tenantId: {}, deviceId: {}, endpoint: {}]", tenantId, deviceId, endpoint.getCanonicalName());
            getAdapter().getMetrics().reportTelemetry(endpoint, tenantId, tenantTracker.result(), MetricsTags.ProcessingOutcome.FORWARDED, qos, payload.length(), getTtdStatus(context), context.getTimer());
            context.respond(response);
            currentSpan.finish();
            return (Void) null;
        }).recover(t -> {
            LOG.debug("cannot process message from device [tenantId: {}, deviceId: {}, endpoint: {}]", tenantId, deviceId, endpoint.getCanonicalName(), t);
            final Future<Void> commandConsumerClosedTracker = Optional.ofNullable(commandConsumerTracker.result()).map(consumer -> consumer.close(currentSpan.context()).onFailure(thr -> TracingHelper.logError(currentSpan, thr))).orElseGet(Future::succeededFuture);
            final CommandContext commandContext = context.get(CommandContext.KEY_COMMAND_CONTEXT);
            if (commandContext != null) {
                TracingHelper.logError(commandContext.getTracingSpan(), "command won't be forwarded to device in CoAP response, CoAP request handling failed", t);
                commandContext.release(t);
                currentSpan.log("released command for device");
            }
            getAdapter().getMetrics().reportTelemetry(endpoint, tenantId, tenantTracker.result(), ClientErrorException.class.isInstance(t) ? MetricsTags.ProcessingOutcome.UNPROCESSABLE : MetricsTags.ProcessingOutcome.UNDELIVERABLE, qos, payload.length(), getTtdStatus(context), context.getTimer());
            TracingHelper.logError(currentSpan, t);
            commandConsumerClosedTracker.onComplete(res -> currentSpan.finish());
            return Future.failedFuture(t);
        });
    }
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpURLConnection(java.net.HttpURLConnection) ResponseCode(org.eclipse.californium.core.coap.CoAP.ResponseCode) CoapExchange(org.eclipse.californium.core.server.resources.CoapExchange) Response(org.eclipse.californium.core.coap.Response) Command(org.eclipse.hono.client.command.Command) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Constants(org.eclipse.hono.util.Constants) Tags(io.opentracing.tag.Tags) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) CompositeFuture(io.vertx.core.CompositeFuture) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) TtdStatus(org.eclipse.hono.service.metric.MetricsTags.TtdStatus) References(io.opentracing.References) Duration(java.time.Duration) Map(java.util.Map) MediaTypeRegistry(org.eclipse.californium.core.coap.MediaTypeRegistry) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) TracingHelper(org.eclipse.hono.tracing.TracingHelper) AsyncResult(io.vertx.core.AsyncResult) CommandConstants(org.eclipse.hono.util.CommandConstants) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) Promise(io.vertx.core.Promise) CommandContext(org.eclipse.hono.client.command.CommandContext) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) MessageHelper(org.eclipse.hono.util.MessageHelper) Sample(io.micrometer.core.instrument.Timer.Sample) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) List(java.util.List) Principal(java.security.Principal) Buffer(io.vertx.core.buffer.Buffer) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Optional(java.util.Optional) Span(io.opentracing.Span) OptionSet(org.eclipse.californium.core.coap.OptionSet) Handler(io.vertx.core.Handler) CommandContext(org.eclipse.hono.client.command.CommandContext) Span(io.opentracing.Span) Response(org.eclipse.californium.core.coap.Response) Promise(io.vertx.core.Promise) ClientErrorException(org.eclipse.hono.client.ClientErrorException) CompositeFuture(io.vertx.core.CompositeFuture) Future(io.vertx.core.Future) TenantObject(org.eclipse.hono.util.TenantObject)

Example 99 with Span

use of io.opentracing.Span in project hono by eclipse.

the class VertxBasedAmqpProtocolAdapterTest method testMessageLimitExceededForADownstreamMessage.

private void testMessageLimitExceededForADownstreamMessage(final VertxTestContext ctx, final Message message, final Consumer<Void> postUploadAssertions) {
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    // AT LEAST ONCE
    when(delivery.remotelySettled()).thenReturn(false);
    final AmqpContext amqpContext = AmqpContext.fromMessage(delivery, message, span, null);
    // GIVEN an AMQP adapter
    givenAnAdapter(properties);
    givenATelemetrySenderForAnyTenant();
    // which is enabled for a tenant with exceeded message limit
    when(resourceLimitChecks.isMessageLimitReached(any(TenantObject.class), anyLong(), any(SpanContext.class))).thenReturn(Future.succeededFuture(Boolean.TRUE));
    // WHEN a device uploads a message to the adapter with AT_LEAST_ONCE delivery semantics
    adapter.onMessageReceived(amqpContext).onComplete(ctx.failing(t -> {
        ctx.verify(() -> {
            // THEN the message limit is exceeded
            assertThat(((ClientErrorException) t).getErrorCode()).isEqualTo(HttpUtils.HTTP_TOO_MANY_REQUESTS);
            // AND the client receives a corresponding REJECTED disposition
            verify(delivery).disposition(argThat(s -> {
                if (s instanceof Rejected) {
                    return AmqpError.RESOURCE_LIMIT_EXCEEDED.equals(((Rejected) s).getError().getCondition());
                } else {
                    return false;
                }
            }), eq(true));
            // AND
            postUploadAssertions.accept(null);
        });
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) MessagingType(org.eclipse.hono.util.MessagingType) EventBus(io.vertx.core.eventbus.EventBus) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Map(java.util.Map) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) CommandContext(org.eclipse.hono.client.command.CommandContext) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) EventConstants(org.eclipse.hono.util.EventConstants) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) Span(io.opentracing.Span) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) Mockito.mock(org.mockito.Mockito.mock) VertxTestContext(io.vertx.junit5.VertxTestContext) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) Target(org.apache.qpid.proton.amqp.messaging.Target) ArgumentMatchers.anyBoolean(org.mockito.ArgumentMatchers.anyBoolean) Commands(org.eclipse.hono.client.command.Commands) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) AsyncResult(io.vertx.core.AsyncResult) CommandConstants(org.eclipse.hono.util.CommandConstants) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) Vertx(io.vertx.core.Vertx) Mockito.times(org.mockito.Mockito.times) ProtonHelper(io.vertx.proton.ProtonHelper) Released(org.apache.qpid.proton.amqp.messaging.Released) SpanContext(io.opentracing.SpanContext) Mockito.never(org.mockito.Mockito.never) ConnectionAttemptOutcome(org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome) ResourceLimitChecks(org.eclipse.hono.adapter.resourcelimits.ResourceLimitChecks) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ProtonReceiver(io.vertx.proton.ProtonReceiver) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) Context(io.vertx.core.Context) ProtonServer(io.vertx.proton.ProtonServer) Timeout(io.vertx.junit5.Timeout) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) NotificationType(org.eclipse.hono.notification.NotificationType) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Binary(org.apache.qpid.proton.amqp.Binary) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) Data(org.apache.qpid.proton.amqp.messaging.Data) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) ProtonQoS(io.vertx.proton.ProtonQoS) Instant(java.time.Instant) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) Test(org.junit.jupiter.api.Test) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Buffer(io.vertx.core.buffer.Buffer) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Mockito.inOrder(org.mockito.Mockito.inOrder) ProtonSender(io.vertx.proton.ProtonSender) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) QoS(org.eclipse.hono.util.QoS) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AbstractNotification(org.eclipse.hono.notification.AbstractNotification) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ProtonDelivery(io.vertx.proton.ProtonDelivery) ConnectionLimitManager(org.eclipse.hono.adapter.limiting.ConnectionLimitManager) HashMap(java.util.HashMap) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ConnectionEventProducer(org.eclipse.hono.adapter.monitoring.ConnectionEventProducer) CommandResponseSender(org.eclipse.hono.client.command.CommandResponseSender) Constants(org.eclipse.hono.util.Constants) ProtocolAdapterTestSupport(org.eclipse.hono.adapter.test.ProtocolAdapterTestSupport) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) ArgumentCaptor(org.mockito.ArgumentCaptor) RecordImpl(org.apache.qpid.proton.engine.impl.RecordImpl) Message(org.apache.qpid.proton.message.Message) HttpUtils(org.eclipse.hono.service.http.HttpUtils) TenantChangeNotification(org.eclipse.hono.notification.deviceregistry.TenantChangeNotification) InOrder(org.mockito.InOrder) Promise(io.vertx.core.Promise) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) ApplicationProperties(org.apache.qpid.proton.amqp.messaging.ApplicationProperties) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Source(org.apache.qpid.proton.amqp.transport.Source) Adapter(org.eclipse.hono.util.Adapter) Handler(io.vertx.core.Handler) Record(org.apache.qpid.proton.engine.Record) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) ProtonDelivery(io.vertx.proton.ProtonDelivery) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected)

Example 100 with Span

use of io.opentracing.Span in project hono by eclipse.

the class VertxBasedAmqpProtocolAdapterTest method testUploadTelemetryWithAtMostOnceDeliverySemantics.

/**
 * Verifies that a request to upload a pre-settled telemetry message results
 * in the downstream sender not waiting for the consumer's acknowledgment.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testUploadTelemetryWithAtMostOnceDeliverySemantics(final VertxTestContext ctx) {
    // GIVEN an AMQP adapter with a configured server
    givenAnAdapter(properties);
    // sending of downstream telemetry message succeeds
    givenATelemetrySenderForAnyTenant();
    // which is enabled for a tenant
    final TenantObject tenantObject = givenAConfiguredTenant(TEST_TENANT_ID, true);
    // IF a device sends a 'fire and forget' telemetry message
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    when(delivery.remotelySettled()).thenReturn(true);
    final Buffer payload = Buffer.buffer("payload");
    final String to = ResourceIdentifier.from(TelemetryConstants.TELEMETRY_ENDPOINT, TEST_TENANT_ID, TEST_DEVICE).toString();
    adapter.onMessageReceived(AmqpContext.fromMessage(delivery, getFakeMessage(to, payload), span, null)).onComplete(ctx.succeeding(d -> {
        ctx.verify(() -> {
            // THEN the adapter has forwarded the message downstream
            assertTelemetryMessageHasBeenSentDownstream(QoS.AT_MOST_ONCE, TEST_TENANT_ID, TEST_DEVICE, "text/plain");
            // and acknowledged the message to the device
            verify(delivery).disposition(any(Accepted.class), eq(true));
            // and has reported the telemetry message
            verify(metrics).reportTelemetry(eq(EndpointType.TELEMETRY), eq(TEST_TENANT_ID), eq(tenantObject), eq(ProcessingOutcome.FORWARDED), eq(MetricsTags.QoS.AT_MOST_ONCE), eq(payload.length()), any());
        });
        ctx.completeNow();
    }));
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) MessagingType(org.eclipse.hono.util.MessagingType) EventBus(io.vertx.core.eventbus.EventBus) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Map(java.util.Map) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) CommandContext(org.eclipse.hono.client.command.CommandContext) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) EventConstants(org.eclipse.hono.util.EventConstants) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) Span(io.opentracing.Span) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) Mockito.mock(org.mockito.Mockito.mock) VertxTestContext(io.vertx.junit5.VertxTestContext) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) Target(org.apache.qpid.proton.amqp.messaging.Target) ArgumentMatchers.anyBoolean(org.mockito.ArgumentMatchers.anyBoolean) Commands(org.eclipse.hono.client.command.Commands) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) AsyncResult(io.vertx.core.AsyncResult) CommandConstants(org.eclipse.hono.util.CommandConstants) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) Vertx(io.vertx.core.Vertx) Mockito.times(org.mockito.Mockito.times) ProtonHelper(io.vertx.proton.ProtonHelper) Released(org.apache.qpid.proton.amqp.messaging.Released) SpanContext(io.opentracing.SpanContext) Mockito.never(org.mockito.Mockito.never) ConnectionAttemptOutcome(org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome) ResourceLimitChecks(org.eclipse.hono.adapter.resourcelimits.ResourceLimitChecks) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ProtonReceiver(io.vertx.proton.ProtonReceiver) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) Context(io.vertx.core.Context) ProtonServer(io.vertx.proton.ProtonServer) Timeout(io.vertx.junit5.Timeout) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) NotificationType(org.eclipse.hono.notification.NotificationType) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Binary(org.apache.qpid.proton.amqp.Binary) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) Data(org.apache.qpid.proton.amqp.messaging.Data) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) ProtonQoS(io.vertx.proton.ProtonQoS) Instant(java.time.Instant) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) Test(org.junit.jupiter.api.Test) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Buffer(io.vertx.core.buffer.Buffer) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Mockito.inOrder(org.mockito.Mockito.inOrder) ProtonSender(io.vertx.proton.ProtonSender) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) QoS(org.eclipse.hono.util.QoS) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AbstractNotification(org.eclipse.hono.notification.AbstractNotification) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ProtonDelivery(io.vertx.proton.ProtonDelivery) ConnectionLimitManager(org.eclipse.hono.adapter.limiting.ConnectionLimitManager) HashMap(java.util.HashMap) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ConnectionEventProducer(org.eclipse.hono.adapter.monitoring.ConnectionEventProducer) CommandResponseSender(org.eclipse.hono.client.command.CommandResponseSender) Constants(org.eclipse.hono.util.Constants) ProtocolAdapterTestSupport(org.eclipse.hono.adapter.test.ProtocolAdapterTestSupport) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) ArgumentCaptor(org.mockito.ArgumentCaptor) RecordImpl(org.apache.qpid.proton.engine.impl.RecordImpl) Message(org.apache.qpid.proton.message.Message) HttpUtils(org.eclipse.hono.service.http.HttpUtils) TenantChangeNotification(org.eclipse.hono.notification.deviceregistry.TenantChangeNotification) InOrder(org.mockito.InOrder) Promise(io.vertx.core.Promise) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) ApplicationProperties(org.apache.qpid.proton.amqp.messaging.ApplicationProperties) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Source(org.apache.qpid.proton.amqp.transport.Source) Adapter(org.eclipse.hono.util.Adapter) Handler(io.vertx.core.Handler) Record(org.apache.qpid.proton.engine.Record) TenantObject(org.eclipse.hono.util.TenantObject) ProtonDelivery(io.vertx.proton.ProtonDelivery) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Test(org.junit.jupiter.api.Test)

Aggregations

Span (io.opentracing.Span)370 Future (io.vertx.core.Future)182 HttpURLConnection (java.net.HttpURLConnection)174 Tracer (io.opentracing.Tracer)123 JsonObject (io.vertx.core.json.JsonObject)119 ClientErrorException (org.eclipse.hono.client.ClientErrorException)117 Map (java.util.Map)116 SpanContext (io.opentracing.SpanContext)115 Objects (java.util.Objects)109 List (java.util.List)104 TracingHelper (org.eclipse.hono.tracing.TracingHelper)104 Optional (java.util.Optional)102 Promise (io.vertx.core.Promise)98 Test (org.junit.jupiter.api.Test)96 MessageHelper (org.eclipse.hono.util.MessageHelper)89 Vertx (io.vertx.core.Vertx)84 Constants (org.eclipse.hono.util.Constants)82 ServerErrorException (org.eclipse.hono.client.ServerErrorException)80 Truth.assertThat (com.google.common.truth.Truth.assertThat)79 Mockito.mock (org.mockito.Mockito.mock)79