Search in sources :

Example 71 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class CommandAndControlMqttIT method testSendOneWayCommandSucceeds.

/**
 * Verifies that the adapter forwards on-way commands from
 * an application to a device.
 *
 * @param endpointConfig The endpoints to use for sending/receiving commands.
 * @param ctx The vert.x test context.
 * @throws InterruptedException if not all commands and responses are exchanged in time.
 */
@ParameterizedTest(name = IntegrationTestSupport.PARAMETERIZED_TEST_NAME_PATTERN)
@MethodSource("allCombinations")
@Timeout(timeUnit = TimeUnit.SECONDS, value = 10)
public void testSendOneWayCommandSucceeds(final MqttCommandEndpointConfiguration endpointConfig, final VertxTestContext ctx) throws InterruptedException {
    final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway() ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5) : deviceId;
    final Checkpoint commandsReceived = ctx.checkpoint(COMMANDS_TO_SEND);
    final AtomicInteger counter = new AtomicInteger();
    testSendCommandSucceeds(ctx, commandTargetDeviceId, msg -> {
        LOGGER.trace("received one-way command [topic: {}]", msg.topicName());
        final ResourceIdentifier topic = ResourceIdentifier.fromString(msg.topicName());
        ctx.verify(() -> {
            endpointConfig.assertCommandPublishTopicStructure(topic, commandTargetDeviceId, true, "setValue");
        });
        commandsReceived.flag();
    }, payload -> {
        counter.incrementAndGet();
        return helper.sendOneWayCommand(tenantId, commandTargetDeviceId, "setValue", "text/plain", payload, helper.getSendCommandTimeout(counter.get() == 1));
    }, endpointConfig, COMMANDS_TO_SEND, MqttQoS.AT_MOST_ONCE);
}
Also used : ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Checkpoint(io.vertx.junit5.Checkpoint) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Timeout(io.vertx.junit5.Timeout) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 72 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class CommandAndControlMqttIT method testSendCommandSucceeds.

private void testSendCommandSucceeds(final VertxTestContext ctx, final MqttCommandEndpointConfiguration endpointConfig, final MqttQoS qos) throws InterruptedException {
    final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway() ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5) : deviceId;
    final AtomicInteger counter = new AtomicInteger();
    testSendCommandSucceeds(ctx, commandTargetDeviceId, msg -> {
        LOGGER.trace("received command [{}]", msg.topicName());
        final ResourceIdentifier topic = ResourceIdentifier.fromString(msg.topicName());
        ctx.verify(() -> {
            endpointConfig.assertCommandPublishTopicStructure(topic, commandTargetDeviceId, false, "setValue");
        });
        final String commandRequestId = topic.elementAt(4);
        final String command = topic.elementAt(5);
        // send response
        mqttClient.publish(endpointConfig.getResponseTopic(commandTargetDeviceId, commandRequestId, HttpURLConnection.HTTP_OK), Buffer.buffer(command + ": ok"), qos, false, false);
    }, payload -> {
        final String contentType = payload != null ? "text/plain" : null;
        counter.incrementAndGet();
        return helper.sendCommand(tenantId, commandTargetDeviceId, "setValue", contentType, payload, helper.getSendCommandTimeout(counter.get() == 1)).map(response -> {
            ctx.verify(() -> {
                assertThat(response.getDeviceId()).isEqualTo(commandTargetDeviceId);
                assertThat(response.getTenantId()).isEqualTo(tenantId);
                assertThat(response.getCreationTime()).isNotNull();
            });
            return (Void) null;
        });
    }, endpointConfig, COMMANDS_TO_SEND, qos);
}
Also used : ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 73 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class HttpBasedMessageMapping method mapDownstreamMessageRequest.

private void mapDownstreamMessageRequest(final MqttContext ctx, final ResourceIdentifier targetAddress, final RegistrationAssertion registrationInfo, final MapperEndpoint mapperEndpoint, final Handler<AsyncResult<MappedMessage>> resultHandler) {
    final MultiMap headers = MultiMap.caseInsensitiveMultiMap();
    JsonObject.mapFrom(registrationInfo).forEach(property -> {
        final Object value = property.getValue();
        if (value instanceof String) {
            // prevent strings from being enclosed in quotes
            headers.add(property.getKey(), (String) value);
        } else {
            headers.add(property.getKey(), Json.encode(value));
        }
    });
    headers.add(MessageHelper.APP_PROPERTY_ORIG_ADDRESS, ctx.message().topicName());
    if (ctx.contentType() != null) {
        headers.add(HttpHeaders.CONTENT_TYPE.toString(), ctx.contentType());
    }
    final Promise<MappedMessage> result = Promise.promise();
    webClient.post(mapperEndpoint.getPort(), mapperEndpoint.getHost(), mapperEndpoint.getUri()).putHeaders(headers).ssl(mapperEndpoint.isTlsEnabled()).sendBuffer(ctx.message().payload(), httpResponseAsyncResult -> {
        if (httpResponseAsyncResult.failed()) {
            LOG.debug("failed to map message [origin: {}] using mapping service [host: {}, port: {}, URI: {}]", ctx.authenticatedDevice(), mapperEndpoint.getHost(), mapperEndpoint.getPort(), mapperEndpoint.getUri(), httpResponseAsyncResult.cause());
            result.fail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, httpResponseAsyncResult.cause()));
        } else {
            final HttpResponse<Buffer> httpResponse = httpResponseAsyncResult.result();
            if (httpResponse.statusCode() == HttpURLConnection.HTTP_OK) {
                final Map<String, String> additionalProperties = new HashMap<>();
                httpResponse.headers().forEach(entry -> additionalProperties.put(entry.getKey(), entry.getValue()));
                final String mappedDeviceId = Optional.ofNullable(additionalProperties.remove(MessageHelper.APP_PROPERTY_DEVICE_ID)).map(id -> {
                    LOG.debug("original {} has been mapped to [device-id: {}]", ctx.authenticatedDevice(), id);
                    return id;
                }).orElseGet(() -> targetAddress.getResourceId());
                result.complete(new MappedMessage(ResourceIdentifier.from(targetAddress.getEndpoint(), targetAddress.getTenantId(), mappedDeviceId), httpResponse.bodyAsBuffer(), additionalProperties));
            } else {
                LOG.debug("mapping service [host: {}, port: {}, URI: {}] returned unexpected status code: {}", mapperEndpoint.getHost(), mapperEndpoint.getPort(), mapperEndpoint.getUri(), httpResponse.statusCode());
                result.fail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "could not invoke configured mapping service"));
            }
        }
        resultHandler.handle(result.future());
    });
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpURLConnection(java.net.HttpURLConnection) Json(io.vertx.core.json.Json) HttpResponse(io.vertx.ext.web.client.HttpResponse) WebClient(io.vertx.ext.web.client.WebClient) Command(org.eclipse.hono.client.command.Command) LoggerFactory(org.slf4j.LoggerFactory) MultiMap(io.vertx.core.MultiMap) HashMap(java.util.HashMap) Map(java.util.Map) MqttContext(org.eclipse.hono.adapter.mqtt.MqttContext) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) JsonObject(io.vertx.core.json.JsonObject) MappedMessage(org.eclipse.hono.adapter.mqtt.MappedMessage) AsyncResult(io.vertx.core.AsyncResult) Strings(org.eclipse.hono.util.Strings) Logger(org.slf4j.Logger) MapperEndpoint(org.eclipse.hono.config.MapperEndpoint) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) HttpHeaders(io.vertx.core.http.HttpHeaders) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) MessageHelper(org.eclipse.hono.util.MessageHelper) Future(io.vertx.core.Future) Objects(java.util.Objects) Buffer(io.vertx.core.buffer.Buffer) MqttProtocolAdapterProperties(org.eclipse.hono.adapter.mqtt.MqttProtocolAdapterProperties) Optional(java.util.Optional) Handler(io.vertx.core.Handler) MessageMapping(org.eclipse.hono.adapter.mqtt.MessageMapping) MultiMap(io.vertx.core.MultiMap) MappedMessage(org.eclipse.hono.adapter.mqtt.MappedMessage) HashMap(java.util.HashMap) JsonObject(io.vertx.core.json.JsonObject) ServerErrorException(org.eclipse.hono.client.ServerErrorException)

Example 74 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method testUploadEmptyCommandResponseSucceeds.

/**
 * Verifies that the adapter accepts a command response message with an empty body.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testUploadEmptyCommandResponseSucceeds(final VertxTestContext ctx) {
    // GIVEN an adapter with a command response consumer
    final CommandResponseSender sender = givenACommandResponseSenderForAnyTenant();
    // WHEN forwarding a command response that has been published
    givenAnAdapter(properties);
    final MqttEndpoint endpoint = mockEndpoint();
    when(endpoint.isConnected()).thenReturn(Boolean.TRUE);
    final MqttPublishMessage messageFromDevice = mock(MqttPublishMessage.class);
    when(messageFromDevice.qosLevel()).thenReturn(MqttQoS.AT_MOST_ONCE);
    when(messageFromDevice.messageId()).thenReturn(5555555);
    when(messageFromDevice.topicName()).thenReturn("command/my-tenant/4712/res/1010f8ab0b53-bd96-4d99-9d9c-56b868474a6a/200");
    // ... with an empty payload
    when(messageFromDevice.payload()).thenReturn(null);
    final ResourceIdentifier address = ResourceIdentifier.fromString("command/my-tenant/4712/res/1010f8ab0b53-bd96-4d99-9d9c-56b868474a6a/200");
    adapter.uploadCommandResponseMessage(newMqttContext(messageFromDevice, endpoint, span), address).onComplete(ctx.succeeding(result -> {
        ctx.verify(() -> {
            verify(sender).sendCommandResponse(any(TenantObject.class), any(RegistrationAssertion.class), any(CommandResponse.class), any());
            // then it is forwarded successfully
            verify(metrics).reportCommand(eq(MetricsTags.Direction.RESPONSE), eq("my-tenant"), any(TenantObject.class), eq(MetricsTags.ProcessingOutcome.FORWARDED), eq(0), any());
            ctx.completeNow();
        });
    }));
}
Also used : 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) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) CommandResponseSender(org.eclipse.hono.client.command.CommandResponseSender) Test(org.junit.jupiter.api.Test)

Example 75 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method getAdapter.

private AbstractVertxBasedMqttProtocolAdapter<MqttProtocolAdapterProperties> getAdapter(final MqttServer server, final MqttProtocolAdapterProperties configuration) {
    final AbstractVertxBasedMqttProtocolAdapter<MqttProtocolAdapterProperties> adapter = new AbstractVertxBasedMqttProtocolAdapter<>() {

        @Override
        public String getTypeName() {
            return ADAPTER_TYPE;
        }

        @Override
        protected Future<Void> onPublishedMessage(final MqttContext ctx) {
            final ResourceIdentifier topic = ResourceIdentifier.fromString(ctx.message().topicName());
            return uploadTelemetryMessage(ctx, topic.getTenantId(), topic.getResourceId(), ctx.message().payload());
        }
    };
    adapter.setConfig(configuration);
    adapter.setMetrics(metrics);
    adapter.setAuthHandler(authHandler);
    adapter.setResourceLimitChecks(resourceLimitChecks);
    setServiceClients(adapter);
    if (server != null) {
        adapter.setMqttInsecureServer(server);
        adapter.init(vertx, context);
    }
    return adapter;
}
Also used : ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier)

Aggregations

ResourceIdentifier (org.eclipse.hono.util.ResourceIdentifier)82 Message (org.apache.qpid.proton.message.Message)30 Future (io.vertx.core.Future)24 HttpURLConnection (java.net.HttpURLConnection)22 MessageHelper (org.eclipse.hono.util.MessageHelper)22 ClientErrorException (org.eclipse.hono.client.ClientErrorException)20 Test (org.junit.Test)20 Test (org.junit.jupiter.api.Test)19 Handler (io.vertx.core.Handler)18 Map (java.util.Map)18 Span (io.opentracing.Span)17 Buffer (io.vertx.core.buffer.Buffer)17 SpanContext (io.opentracing.SpanContext)16 Constants (org.eclipse.hono.util.Constants)16 Promise (io.vertx.core.Promise)15 Objects (java.util.Objects)14 AsyncResult (io.vertx.core.AsyncResult)13 Vertx (io.vertx.core.Vertx)13 ProtonConnection (io.vertx.proton.ProtonConnection)13 ProtonReceiver (io.vertx.proton.ProtonReceiver)13