Search in sources :

Example 51 with Device

use of org.eclipse.hono.auth.Device in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method testDeviceConnectionIsClosedOnTenantDisabledNotification.

/**
 * Verifies that the adapter closes the connection to an authenticated device when a notification
 * has been received that the tenant of the device has been disabled.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testDeviceConnectionIsClosedOnTenantDisabledNotification(final VertxTestContext ctx) {
    final Device device = new Device("tenant", "deviceId");
    testDeviceConnectionIsClosedOnDeviceOrTenantChangeNotification(ctx, device, new TenantChangeNotification(LifecycleChange.UPDATE, "tenant", Instant.now(), false));
}
Also used : Device(org.eclipse.hono.auth.Device) TenantChangeNotification(org.eclipse.hono.notification.deviceregistry.TenantChangeNotification) Test(org.junit.jupiter.api.Test)

Example 52 with Device

use of org.eclipse.hono.auth.Device in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method testUploadTelemetryMessageIncludesRetainAnnotation.

/**
 * Verifies that the adapter includes a message annotation in a downstream message if the device publishes a message
 * with its <em>retain</em> flag set.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testUploadTelemetryMessageIncludesRetainAnnotation(final VertxTestContext ctx) {
    // GIVEN an adapter with a downstream telemetry consumer
    givenAnAdapter(properties);
    givenATelemetrySenderForAnyTenant();
    // WHEN a device publishes a message with its retain flag set
    final MqttEndpoint endpoint = mockEndpoint();
    when(endpoint.isConnected()).thenReturn(Boolean.TRUE);
    final Buffer payload = Buffer.buffer("hello");
    final MqttPublishMessage messageFromDevice = mock(MqttPublishMessage.class);
    when(messageFromDevice.qosLevel()).thenReturn(MqttQoS.AT_LEAST_ONCE);
    when(messageFromDevice.messageId()).thenReturn(5555555);
    when(messageFromDevice.topicName()).thenReturn("t/my-tenant/4712");
    when(messageFromDevice.isRetain()).thenReturn(Boolean.TRUE);
    when(messageFromDevice.payload()).thenReturn(payload);
    final MqttContext context = newMqttContext(messageFromDevice, endpoint, span);
    adapter.uploadTelemetryMessage(context, "my-tenant", "4712", payload).onComplete(ctx.succeeding(ok -> {
        ctx.verify(() -> {
            // THEN the device has received a PUBACK
            verify(endpoint).publishAcknowledge(5555555);
            // and the message has been sent downstream
            // including the "retain" annotation
            verify(telemetrySender).sendTelemetry(argThat(tenant -> tenant.getTenantId().equals("my-tenant")), argThat(assertion -> assertion.getDeviceId().equals("4712")), eq(QoS.AT_LEAST_ONCE), any(), any(), argThat(props -> props.get(MessageHelper.ANNOTATION_X_OPT_RETAIN).equals(Boolean.TRUE)), any());
            verify(metrics).reportTelemetry(eq(MetricsTags.EndpointType.TELEMETRY), eq("my-tenant"), any(), eq(MetricsTags.ProcessingOutcome.FORWARDED), eq(MetricsTags.QoS.AT_LEAST_ONCE), eq(payload.length()), any());
        });
        ctx.completeNow();
    }));
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpURLConnection(java.net.HttpURLConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) Context(io.vertx.core.Context) Timeout(io.vertx.junit5.Timeout) AfterAll(org.junit.jupiter.api.AfterAll) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) MessagingType(org.eclipse.hono.util.MessagingType) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) BeforeAll(org.junit.jupiter.api.BeforeAll) Mockito.doAnswer(org.mockito.Mockito.doAnswer) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) AuthHandler(org.eclipse.hono.adapter.auth.device.AuthHandler) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) 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) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) Span(io.opentracing.Span) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) QoS(org.eclipse.hono.util.QoS) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AbstractNotification(org.eclipse.hono.notification.AbstractNotification) VertxTestContext(io.vertx.junit5.VertxTestContext) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) ClientErrorException(org.eclipse.hono.client.ClientErrorException) OptionalInt(java.util.OptionalInt) CommandResponseSender(org.eclipse.hono.client.command.CommandResponseSender) Commands(org.eclipse.hono.client.command.Commands) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) DeviceUser(org.eclipse.hono.service.auth.DeviceUser) MqttServer(io.vertx.mqtt.MqttServer) ProtocolAdapterTestSupport(org.eclipse.hono.adapter.test.ProtocolAdapterTestSupport) SSLSession(javax.net.ssl.SSLSession) ArgumentCaptor(org.mockito.ArgumentCaptor) MqttTopicSubscription(io.vertx.mqtt.MqttTopicSubscription) BiConsumer(java.util.function.BiConsumer) HttpUtils(org.eclipse.hono.service.http.HttpUtils) AsyncResult(io.vertx.core.AsyncResult) CommandConstants(org.eclipse.hono.util.CommandConstants) ArgumentMatchers.anyInt(org.mockito.ArgumentMatchers.anyInt) TenantChangeNotification(org.eclipse.hono.notification.deviceregistry.TenantChangeNotification) Promise(io.vertx.core.Promise) MqttSubscribeMessage(io.vertx.mqtt.messages.MqttSubscribeMessage) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Mockito.times(org.mockito.Mockito.times) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) TimeUnit(java.util.concurrent.TimeUnit) Mockito.never(org.mockito.Mockito.never) Adapter(org.eclipse.hono.util.Adapter) ConnectionAttemptOutcome(org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome) MqttAuth(io.vertx.mqtt.MqttAuth) ResourceLimitChecks(org.eclipse.hono.adapter.resourcelimits.ResourceLimitChecks) Handler(io.vertx.core.Handler) Collections(java.util.Collections) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) Test(org.junit.jupiter.api.Test)

Example 53 with Device

use of org.eclipse.hono.auth.Device in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapter method uploadMessage.

private Future<Void> uploadMessage(final MqttContext ctx, final TenantObject tenantObject, final String deviceId, final Buffer payload, final MetricsTags.EndpointType endpoint) {
    if (!isPayloadOfIndicatedType(payload, ctx.contentType())) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, String.format("Content-Type %s does not match payload", ctx.contentType())));
    }
    final Span currentSpan = TracingHelper.buildChildSpan(tracer, ctx.getTracingContext(), "upload " + endpoint, getTypeName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_TENANT_ID, tenantObject.getTenantId()).withTag(TracingHelper.TAG_DEVICE_ID, deviceId).withTag(TracingHelper.TAG_AUTHENTICATED.getKey(), ctx.authenticatedDevice() != null).start();
    final Future<RegistrationAssertion> tokenTracker = getRegistrationAssertion(tenantObject.getTenantId(), deviceId, ctx.authenticatedDevice(), currentSpan.context());
    final Future<TenantObject> tenantValidationTracker = CompositeFuture.all(isAdapterEnabled(tenantObject), checkMessageLimit(tenantObject, payload.length(), currentSpan.context())).map(tenantObject);
    return CompositeFuture.all(tokenTracker, tenantValidationTracker).compose(ok -> {
        final Map<String, Object> props = getDownstreamMessageProperties(ctx);
        props.put(MessageHelper.APP_PROPERTY_QOS, ctx.getRequestedQos().ordinal());
        addRetainAnnotation(ctx, props, currentSpan);
        customizeDownstreamMessageProperties(props, ctx);
        if (endpoint == EndpointType.EVENT) {
            return getEventSender(tenantObject).sendEvent(tenantObject, tokenTracker.result(), ctx.contentType(), payload, props, currentSpan.context());
        } else {
            return getTelemetrySender(tenantObject).sendTelemetry(tenantObject, tokenTracker.result(), ctx.getRequestedQos(), ctx.contentType(), payload, props, currentSpan.context());
        }
    }).map(ok -> {
        log.trace("successfully processed message [topic: {}, QoS: {}] from device [tenantId: {}, deviceId: {}]", ctx.message().topicName(), ctx.message().qosLevel(), tenantObject.getTenantId(), deviceId);
        // check that the remote MQTT client is still connected before sending PUBACK
        if (ctx.isAtLeastOnce() && ctx.deviceEndpoint().isConnected()) {
            currentSpan.log(EVENT_SENDING_PUBACK);
            ctx.acknowledge();
        }
        currentSpan.finish();
        return ok;
    }).recover(t -> {
        if (ClientErrorException.class.isInstance(t)) {
            final ClientErrorException e = (ClientErrorException) t;
            log.debug("cannot process message [endpoint: {}] from device [tenantId: {}, deviceId: {}]: {} - {}", endpoint, tenantObject.getTenantId(), deviceId, e.getErrorCode(), e.getMessage());
        } else {
            log.debug("cannot process message [endpoint: {}] from device [tenantId: {}, deviceId: {}]", endpoint, tenantObject.getTenantId(), deviceId, t);
        }
        TracingHelper.logError(currentSpan, t);
        currentSpan.finish();
        return Future.failedFuture(t);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) ZonedDateTime(java.time.ZonedDateTime) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) Tags(io.opentracing.tag.Tags) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) DeviceCredentials(org.eclipse.hono.adapter.auth.device.DeviceCredentials) Map(java.util.Map) Pair(org.eclipse.hono.util.Pair) AuthorizationException(org.eclipse.hono.adapter.AuthorizationException) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Fields(io.opentracing.log.Fields) JsonObject(io.vertx.core.json.JsonObject) MqttConnectionException(io.vertx.mqtt.MqttConnectionException) ZoneOffset(java.time.ZoneOffset) TracingHelper(org.eclipse.hono.tracing.TracingHelper) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) AuthHandler(org.eclipse.hono.adapter.auth.device.AuthHandler) Futures(org.eclipse.hono.util.Futures) TenantServiceBasedX509Authentication(org.eclipse.hono.adapter.auth.device.TenantServiceBasedX509Authentication) Predicate(java.util.function.Predicate) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CommandContext(org.eclipse.hono.client.command.CommandContext) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) Set(java.util.Set) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) 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) List(java.util.List) TenantTraceSamplingHelper(org.eclipse.hono.tracing.TenantTraceSamplingHelper) Buffer(io.vertx.core.buffer.Buffer) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Optional(java.util.Optional) Span(io.opentracing.Span) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) 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) Deque(java.util.Deque) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) OptionalInt(java.util.OptionalInt) AtomicReference(java.util.concurrent.atomic.AtomicReference) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) DeviceUser(org.eclipse.hono.service.auth.DeviceUser) MqttServer(io.vertx.mqtt.MqttServer) HashSet(java.util.HashSet) CompositeFuture(io.vertx.core.CompositeFuture) SSLSession(javax.net.ssl.SSLSession) MqttTopicSubscription(io.vertx.mqtt.MqttTopicSubscription) AdapterConnectionsExceededException(org.eclipse.hono.adapter.AdapterConnectionsExceededException) LinkedList(java.util.LinkedList) CommandConstants(org.eclipse.hono.util.CommandConstants) TenantChangeNotification(org.eclipse.hono.notification.deviceregistry.TenantChangeNotification) ChainAuthHandler(org.eclipse.hono.adapter.auth.device.ChainAuthHandler) 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) MqttServerOptions(io.vertx.mqtt.MqttServerOptions) Promise(io.vertx.core.Promise) MqttSubscribeMessage(io.vertx.mqtt.messages.MqttSubscribeMessage) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Sample(io.micrometer.core.instrument.Timer.Sample) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) ErrorHandlingMode(org.eclipse.hono.adapter.mqtt.MqttContext.ErrorHandlingMode) MqttUnsubscribeMessage(io.vertx.mqtt.messages.MqttUnsubscribeMessage) ChronoUnit(java.time.temporal.ChronoUnit) ConnectionAttemptOutcome(org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome) MemoryBasedConnectionLimitStrategy(org.eclipse.hono.adapter.limiting.MemoryBasedConnectionLimitStrategy) X509AuthProvider(org.eclipse.hono.adapter.auth.device.X509AuthProvider) DateTimeFormatter(java.time.format.DateTimeFormatter) ArrayDeque(java.util.ArrayDeque) Handler(io.vertx.core.Handler) DefaultConnectionLimitManager(org.eclipse.hono.adapter.limiting.DefaultConnectionLimitManager) TenantObject(org.eclipse.hono.util.TenantObject) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) ClientErrorException(org.eclipse.hono.client.ClientErrorException) JsonObject(io.vertx.core.json.JsonObject) TenantObject(org.eclipse.hono.util.TenantObject) Span(io.opentracing.Span)

Example 54 with Device

use of org.eclipse.hono.auth.Device in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapter method uploadCommandResponseMessage.

/**
 * Uploads a command response message.
 *
 * @param ctx The context in which the MQTT message has been published.
 * @param targetAddress The address that the response should be forwarded to.
 * @return A future indicating the outcome of the operation.
 *         <p>
 *         The future will succeed if the message has been uploaded successfully.
 *         Otherwise, the future will fail with a {@link ServiceInvocationException}.
 * @throws NullPointerException if any of the parameters are {@code null}.
 */
public final Future<Void> uploadCommandResponseMessage(final MqttContext ctx, final ResourceIdentifier targetAddress) {
    Objects.requireNonNull(ctx);
    Objects.requireNonNull(targetAddress);
    final String[] addressPath = targetAddress.getResourcePath();
    Integer status = null;
    String reqId = null;
    final Future<CommandResponse> commandResponseTracker;
    if (addressPath.length <= CommandConstants.TOPIC_POSITION_RESPONSE_STATUS) {
        commandResponseTracker = Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "command response topic has too few segments"));
    } else {
        try {
            status = Integer.parseInt(addressPath[CommandConstants.TOPIC_POSITION_RESPONSE_STATUS]);
        } catch (final NumberFormatException e) {
            log.trace("got invalid status code [{}] [tenant-id: {}, device-id: {}]", addressPath[CommandConstants.TOPIC_POSITION_RESPONSE_STATUS], targetAddress.getTenantId(), targetAddress.getResourceId());
        }
        if (status != null) {
            reqId = addressPath[CommandConstants.TOPIC_POSITION_RESPONSE_REQ_ID];
            final CommandResponse commandResponse = CommandResponse.fromRequestId(reqId, targetAddress.getTenantId(), targetAddress.getResourceId(), ctx.message().payload(), ctx.contentType(), status);
            commandResponseTracker = commandResponse != null ? Future.succeededFuture(commandResponse) : Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "command response topic contains invalid data"));
        } else {
            // status code could not be parsed
            commandResponseTracker = Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "invalid status code"));
        }
    }
    final Span currentSpan = TracingHelper.buildChildSpan(tracer, ctx.getTracingContext(), "upload Command response", getTypeName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_TENANT_ID, targetAddress.getTenantId()).withTag(TracingHelper.TAG_DEVICE_ID, targetAddress.getResourceId()).withTag(Constants.HEADER_COMMAND_RESPONSE_STATUS, status).withTag(Constants.HEADER_COMMAND_REQUEST_ID, reqId).withTag(TracingHelper.TAG_AUTHENTICATED.getKey(), ctx.authenticatedDevice() != null).start();
    final int payloadSize = Optional.ofNullable(ctx.message().payload()).map(Buffer::length).orElse(0);
    final Future<TenantObject> tenantTracker = getTenantConfiguration(targetAddress.getTenantId(), ctx.getTracingContext());
    return CompositeFuture.all(tenantTracker, commandResponseTracker).compose(success -> {
        final Future<RegistrationAssertion> deviceRegistrationTracker = getRegistrationAssertion(targetAddress.getTenantId(), targetAddress.getResourceId(), ctx.authenticatedDevice(), currentSpan.context());
        final Future<Void> tenantValidationTracker = CompositeFuture.all(isAdapterEnabled(tenantTracker.result()), checkMessageLimit(tenantTracker.result(), payloadSize, currentSpan.context())).mapEmpty();
        return CompositeFuture.all(deviceRegistrationTracker, tenantValidationTracker).compose(ok -> sendCommandResponse(tenantTracker.result(), deviceRegistrationTracker.result(), commandResponseTracker.result(), currentSpan.context()));
    }).compose(delivery -> {
        log.trace("successfully forwarded command response from device [tenant-id: {}, device-id: {}]", targetAddress.getTenantId(), targetAddress.getResourceId());
        metrics.reportCommand(Direction.RESPONSE, targetAddress.getTenantId(), tenantTracker.result(), ProcessingOutcome.FORWARDED, payloadSize, ctx.getTimer());
        // check that the remote MQTT client is still connected before sending PUBACK
        if (ctx.isAtLeastOnce() && ctx.deviceEndpoint().isConnected()) {
            currentSpan.log(EVENT_SENDING_PUBACK);
            ctx.acknowledge();
        }
        currentSpan.finish();
        return Future.<Void>succeededFuture();
    }).recover(t -> {
        TracingHelper.logError(currentSpan, t);
        currentSpan.finish();
        metrics.reportCommand(Direction.RESPONSE, targetAddress.getTenantId(), tenantTracker.result(), ProcessingOutcome.from(t), payloadSize, ctx.getTimer());
        return Future.failedFuture(t);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) ZonedDateTime(java.time.ZonedDateTime) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) Tags(io.opentracing.tag.Tags) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) DeviceCredentials(org.eclipse.hono.adapter.auth.device.DeviceCredentials) Map(java.util.Map) Pair(org.eclipse.hono.util.Pair) AuthorizationException(org.eclipse.hono.adapter.AuthorizationException) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Fields(io.opentracing.log.Fields) JsonObject(io.vertx.core.json.JsonObject) MqttConnectionException(io.vertx.mqtt.MqttConnectionException) ZoneOffset(java.time.ZoneOffset) TracingHelper(org.eclipse.hono.tracing.TracingHelper) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) AuthHandler(org.eclipse.hono.adapter.auth.device.AuthHandler) Futures(org.eclipse.hono.util.Futures) TenantServiceBasedX509Authentication(org.eclipse.hono.adapter.auth.device.TenantServiceBasedX509Authentication) Predicate(java.util.function.Predicate) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CommandContext(org.eclipse.hono.client.command.CommandContext) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) Set(java.util.Set) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) 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) List(java.util.List) TenantTraceSamplingHelper(org.eclipse.hono.tracing.TenantTraceSamplingHelper) Buffer(io.vertx.core.buffer.Buffer) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Optional(java.util.Optional) Span(io.opentracing.Span) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) 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) Deque(java.util.Deque) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) OptionalInt(java.util.OptionalInt) AtomicReference(java.util.concurrent.atomic.AtomicReference) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) DeviceUser(org.eclipse.hono.service.auth.DeviceUser) MqttServer(io.vertx.mqtt.MqttServer) HashSet(java.util.HashSet) CompositeFuture(io.vertx.core.CompositeFuture) SSLSession(javax.net.ssl.SSLSession) MqttTopicSubscription(io.vertx.mqtt.MqttTopicSubscription) AdapterConnectionsExceededException(org.eclipse.hono.adapter.AdapterConnectionsExceededException) LinkedList(java.util.LinkedList) CommandConstants(org.eclipse.hono.util.CommandConstants) TenantChangeNotification(org.eclipse.hono.notification.deviceregistry.TenantChangeNotification) ChainAuthHandler(org.eclipse.hono.adapter.auth.device.ChainAuthHandler) 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) MqttServerOptions(io.vertx.mqtt.MqttServerOptions) Promise(io.vertx.core.Promise) MqttSubscribeMessage(io.vertx.mqtt.messages.MqttSubscribeMessage) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Sample(io.micrometer.core.instrument.Timer.Sample) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) ErrorHandlingMode(org.eclipse.hono.adapter.mqtt.MqttContext.ErrorHandlingMode) MqttUnsubscribeMessage(io.vertx.mqtt.messages.MqttUnsubscribeMessage) ChronoUnit(java.time.temporal.ChronoUnit) ConnectionAttemptOutcome(org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome) MemoryBasedConnectionLimitStrategy(org.eclipse.hono.adapter.limiting.MemoryBasedConnectionLimitStrategy) X509AuthProvider(org.eclipse.hono.adapter.auth.device.X509AuthProvider) DateTimeFormatter(java.time.format.DateTimeFormatter) ArrayDeque(java.util.ArrayDeque) Handler(io.vertx.core.Handler) DefaultConnectionLimitManager(org.eclipse.hono.adapter.limiting.DefaultConnectionLimitManager) CommandResponse(org.eclipse.hono.client.command.CommandResponse) Span(io.opentracing.Span) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) TenantObject(org.eclipse.hono.util.TenantObject) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) ClientErrorException(org.eclipse.hono.client.ClientErrorException)

Example 55 with Device

use of org.eclipse.hono.auth.Device in project hono by eclipse.

the class LoraProtocolAdapter method handleProviderRoute.

void handleProviderRoute(final HttpContext ctx, final LoraProvider provider) {
    if (LOG.isDebugEnabled()) {
        LOG.debug("processing request from provider [name: {}, URI: {}]", provider.getProviderName(), ctx.getRoutingContext().normalizedPath());
    }
    final Span currentSpan = TracingHelper.buildServerChildSpan(tracer, TracingHandler.serverSpanContext(ctx.getRoutingContext()), SPAN_NAME_PROCESS_MESSAGE, getClass().getSimpleName()).start();
    TAG_LORA_PROVIDER.set(currentSpan, provider.getProviderName());
    ctx.put(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER, provider.getProviderName());
    if (!ctx.isDeviceAuthenticated()) {
        logUnsupportedUserType(ctx.getRoutingContext(), currentSpan);
        currentSpan.finish();
        handle401(ctx.getRoutingContext());
        return;
    }
    final Device gatewayDevice = ctx.getAuthenticatedDevice();
    TracingHelper.setDeviceTags(currentSpan, gatewayDevice.getTenantId(), gatewayDevice.getDeviceId());
    try {
        final LoraMessage loraMessage = provider.getMessage(ctx.getRoutingContext());
        final LoraMessageType type = loraMessage.getType();
        currentSpan.log(Map.of("message type", type));
        final String deviceId = loraMessage.getDevEUIAsString();
        currentSpan.setTag(TAG_LORA_DEVICE_ID, deviceId);
        switch(type) {
            case UPLINK:
                final UplinkLoraMessage uplinkMessage = (UplinkLoraMessage) loraMessage;
                final Buffer payload = uplinkMessage.getPayload();
                Optional.ofNullable(uplinkMessage.getMetaData()).ifPresent(metaData -> ctx.put(LoraConstants.APP_PROPERTY_META_DATA, metaData));
                Optional.ofNullable(uplinkMessage.getAdditionalData()).ifPresent(additionalData -> ctx.put(LoraConstants.APP_PROPERTY_ADDITIONAL_DATA, additionalData));
                final String contentType = payload.length() > 0 ? LoraConstants.CONTENT_TYPE_LORA_BASE + provider.getProviderName() : EventConstants.CONTENT_TYPE_EMPTY_NOTIFICATION;
                // uploadTelemetryMessage will finish the root span, therefore finish child span here already
                currentSpan.finish();
                uploadTelemetryMessage(ctx, gatewayDevice.getTenantId(), deviceId, payload, contentType);
                registerCommandConsumerIfNeeded(provider, gatewayDevice, currentSpan.context());
                break;
            default:
                LOG.debug("discarding message of unsupported type [tenant: {}, device-id: {}, type: {}]", gatewayDevice.getTenantId(), deviceId, type);
                currentSpan.log("discarding message of unsupported type");
                currentSpan.finish();
                // discard the message but return 202 to not cause errors on the LoRa provider side
                handle202(ctx.getRoutingContext());
        }
    } catch (final LoraProviderMalformedPayloadException e) {
        LOG.debug("error processing request from provider [name: {}]", provider.getProviderName(), e);
        TracingHelper.logError(currentSpan, "error processing request", e);
        currentSpan.finish();
        handle400(ctx.getRoutingContext(), ERROR_MSG_INVALID_PAYLOAD);
    }
}
Also used : Buffer(io.vertx.core.buffer.Buffer) Device(org.eclipse.hono.auth.Device) Span(io.opentracing.Span) LoraProviderMalformedPayloadException(org.eclipse.hono.adapter.lora.providers.LoraProviderMalformedPayloadException)

Aggregations

Device (org.eclipse.hono.auth.Device)115 HttpURLConnection (java.net.HttpURLConnection)74 Test (org.junit.jupiter.api.Test)72 Future (io.vertx.core.Future)69 ClientErrorException (org.eclipse.hono.client.ClientErrorException)67 Buffer (io.vertx.core.buffer.Buffer)66 Handler (io.vertx.core.Handler)63 TenantObject (org.eclipse.hono.util.TenantObject)63 Promise (io.vertx.core.Promise)59 Constants (org.eclipse.hono.util.Constants)58 Span (io.opentracing.Span)55 RegistrationAssertion (org.eclipse.hono.util.RegistrationAssertion)55 SpanContext (io.opentracing.SpanContext)53 VertxTestContext (io.vertx.junit5.VertxTestContext)52 VertxExtension (io.vertx.junit5.VertxExtension)51 MessageHelper (org.eclipse.hono.util.MessageHelper)51 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)51 Mockito.when (org.mockito.Mockito.when)51 Truth.assertThat (com.google.common.truth.Truth.assertThat)50 ResourceIdentifier (org.eclipse.hono.util.ResourceIdentifier)47