Search in sources :

Example 6 with MqttTopicSubscription

use of io.vertx.mqtt.MqttTopicSubscription in project hono by eclipse.

the class ErrorSubscriptionTest method testSubscriptionSucceedsForAuthenticatedGateway.

/**
 * Verifies that an authenticated gateway can successfully subscribe for errors
 * targeted at one of devices that it is authorized to act on behalf of.
 *
 * @param endpointName The endpoint name used in the topic.
 * @param qos The requested QoS.
 */
@ParameterizedTest
@MethodSource("endpointNamesWithQoS")
public void testSubscriptionSucceedsForAuthenticatedGateway(final String endpointName, final MqttQoS qos) {
    final String gatewayManagedDeviceId = "gatewayManagedDevice";
    final Integer messageId = 123;
    final int errorCode = 503;
    final String errorCausingMsgEndpoint = TelemetryConstants.TELEMETRY_ENDPOINT;
    final MqttPublishMessage message = mock(MqttPublishMessage.class);
    when(message.messageId()).thenReturn(messageId);
    when(message.topicName()).thenReturn(ResourceIdentifier.from(errorCausingMsgEndpoint, gw.getTenantId(), gatewayManagedDeviceId).toString());
    when(message.qosLevel()).thenReturn(MqttQoS.AT_LEAST_ONCE);
    final MqttContext context = MqttContext.fromPublishPacket(message, mock(MqttEndpoint.class), mock(Span.class), gw);
    // WHEN subscribing to errors for a specific device omitting tenant
    MqttTopicSubscription mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s//%s/#", endpointName, gatewayManagedDeviceId), qos);
    ErrorSubscription subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, gw);
    assertThat(subscription).isNotNull();
    assertThat(subscription.getTenant()).isEqualTo(gw.getTenantId());
    assertThat(subscription.getDeviceId()).isEqualTo(gatewayManagedDeviceId);
    assertThat(subscription.getAuthenticatedDeviceId()).isEqualTo(gw.getDeviceId());
    assertThat(subscription.getQos()).isEqualTo(qos);
    assertThat(subscription.isGatewaySubscriptionForSpecificDevice()).isEqualTo(true);
    // THEN the error topic does not include the tenant either
    assertThat(subscription.getErrorPublishTopic(context, errorCode)).isEqualTo(String.format("%s//%s/%s/%s/%s", endpointName, gatewayManagedDeviceId, errorCausingMsgEndpoint, messageId, errorCode));
    // WHEN subscribing to errors for a specific device including the tenant
    mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s/%s/%s/#", endpointName, device.getTenantId(), gatewayManagedDeviceId), qos);
    subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, gw);
    assertThat(subscription).isNotNull();
    assertThat(subscription.getTenant()).isEqualTo(gw.getTenantId());
    assertThat(subscription.getDeviceId()).isEqualTo(gatewayManagedDeviceId);
    assertThat(subscription.getAuthenticatedDeviceId()).isEqualTo(gw.getDeviceId());
    assertThat(subscription.getQos()).isEqualTo(qos);
    assertThat(subscription.isGatewaySubscriptionForSpecificDevice()).isEqualTo(true);
    // THEN the error topic does include the tenant as well
    assertThat(subscription.getErrorPublishTopic(context, errorCode)).isEqualTo(String.format("%s/%s/%s/%s/%s/%s", endpointName, gw.getTenantId(), gatewayManagedDeviceId, errorCausingMsgEndpoint, messageId, errorCode));
    // WHEN subscribing to errors for all devices omitting tenant
    mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s//+/#", endpointName), qos);
    subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, gw);
    assertThat(subscription).isNotNull();
    assertThat(subscription.getTenant()).isEqualTo(gw.getTenantId());
    assertThat(subscription.getDeviceId()).isEqualTo(gw.getDeviceId());
    assertThat(subscription.getAuthenticatedDeviceId()).isEqualTo(gw.getDeviceId());
    assertThat(subscription.getQos()).isEqualTo(qos);
    assertThat(subscription.isGatewaySubscriptionForSpecificDevice()).isEqualTo(false);
    // THEN the error topic does not include the tenant either
    assertThat(subscription.getErrorPublishTopic(context, errorCode)).isEqualTo(String.format("%s//%s/%s/%s/%s", endpointName, gatewayManagedDeviceId, errorCausingMsgEndpoint, messageId, errorCode));
    // WHEN subscribing to errors for all devices including the tenant
    mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s/%s/+/#", endpointName, device.getTenantId()), qos);
    subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, gw);
    assertThat(subscription).isNotNull();
    assertThat(subscription.getTenant()).isEqualTo(gw.getTenantId());
    assertThat(subscription.getDeviceId()).isEqualTo(gw.getDeviceId());
    assertThat(subscription.getAuthenticatedDeviceId()).isEqualTo(gw.getDeviceId());
    assertThat(subscription.getQos()).isEqualTo(qos);
    assertThat(subscription.isGatewaySubscriptionForSpecificDevice()).isEqualTo(false);
    // THEN the error topic does include the tenant as well
    assertThat(subscription.getErrorPublishTopic(context, errorCode)).isEqualTo(String.format("%s/%s/%s/%s/%s/%s", endpointName, gw.getTenantId(), gatewayManagedDeviceId, errorCausingMsgEndpoint, messageId, errorCode));
    // using a tenant other than the tenant that the gateway belongs to should fail
    mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s/otherTenant/+/#", endpointName), qos);
    assertThat(ErrorSubscription.fromTopic(mqttTopicSubscription, gw)).isNull();
}
Also used : MqttTopicSubscriptionImpl(io.vertx.mqtt.impl.MqttTopicSubscriptionImpl) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttTopicSubscription(io.vertx.mqtt.MqttTopicSubscription) Span(io.opentracing.Span) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 7 with MqttTopicSubscription

use of io.vertx.mqtt.MqttTopicSubscription in project hono by eclipse.

the class ErrorSubscriptionTest method testSubscriptionSucceedsForAuthenticatedDevice.

/**
 * Verifies that an authenticated device can successfully subscribe for errors
 * targeted at itself using all variants of topic names.
 *
 * @param endpointName The endpoint name used in the topic.
 * @param qos The requested QoS.
 */
@ParameterizedTest
@MethodSource("endpointNamesWithQoS")
public void testSubscriptionSucceedsForAuthenticatedDevice(final String endpointName, final MqttQoS qos) {
    final Integer messageId = 123;
    final int errorCode = 503;
    final String errorCausingMsgEndpoint = TelemetryConstants.TELEMETRY_ENDPOINT;
    final MqttPublishMessage message = mock(MqttPublishMessage.class);
    when(message.messageId()).thenReturn(messageId);
    when(message.topicName()).thenReturn(errorCausingMsgEndpoint);
    when(message.qosLevel()).thenReturn(MqttQoS.AT_LEAST_ONCE);
    final MqttContext context = MqttContext.fromPublishPacket(message, mock(MqttEndpoint.class), mock(Span.class), device);
    // WHEN subscribing to errors using explicit topic
    MqttTopicSubscription mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s/tenant/device/#", endpointName), qos);
    ErrorSubscription subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, device);
    assertThat(subscription).isNotNull();
    assertThat(subscription.getTenant()).isEqualTo("tenant");
    assertThat(subscription.getDeviceId()).isEqualTo("device");
    assertThat(subscription.getEndpoint()).isEqualTo(endpointName);
    assertThat(subscription.getQos()).isEqualTo(qos);
    // THEN the error topic does include both the tenant and device ID
    assertThat(subscription.getErrorPublishTopic(context, errorCode)).isEqualTo(String.format("%s/%s/%s/%s/%s/%s", endpointName, device.getTenantId(), device.getDeviceId(), errorCausingMsgEndpoint, messageId, errorCode));
    // WHEN subscribing to errors including tenant only
    mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s/tenant//#", endpointName), qos);
    subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, device);
    assertThat(subscription).isNotNull();
    assertThat(subscription.getTenant()).isEqualTo("tenant");
    assertThat(subscription.getDeviceId()).isEqualTo("device");
    assertThat(subscription.getEndpoint()).isEqualTo(endpointName);
    assertThat(subscription.getQos()).isEqualTo(qos);
    // THEN the error topic does include the tenant as well
    assertThat(subscription.getErrorPublishTopic(context, errorCode)).isEqualTo(String.format("%s/%s//%s/%s/%s", endpointName, device.getTenantId(), errorCausingMsgEndpoint, messageId, errorCode));
    // WHEN subscribing to errors including device ID only
    mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s//device/#", endpointName), qos);
    subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, device);
    assertThat(subscription).isNotNull();
    assertThat(subscription.getTenant()).isEqualTo("tenant");
    assertThat(subscription.getDeviceId()).isEqualTo("device");
    assertThat(subscription.getEndpoint()).isEqualTo(endpointName);
    assertThat(subscription.getQos()).isEqualTo(qos);
    // THEN the error topic does include the device ID as well
    assertThat(subscription.getErrorPublishTopic(context, errorCode)).isEqualTo(String.format("%s//%s/%s/%s/%s", endpointName, device.getDeviceId(), errorCausingMsgEndpoint, messageId, errorCode));
    // using a tenant other than the tenant that the device belongs to should fail
    mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s/otherTenant/device/#", endpointName), qos);
    assertThat(ErrorSubscription.fromTopic(mqttTopicSubscription, device)).isNull();
}
Also used : MqttTopicSubscriptionImpl(io.vertx.mqtt.impl.MqttTopicSubscriptionImpl) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttTopicSubscription(io.vertx.mqtt.MqttTopicSubscription) Span(io.opentracing.Span) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 8 with MqttTopicSubscription

use of io.vertx.mqtt.MqttTopicSubscription in project hono by eclipse.

the class ErrorSubscriptionTest method testGetErrorPublishTopicForMessageWithUnknownEndpoint.

/**
 * Verifies that the topic for an error caused by a message sent to a topic with
 * an unknown/invalid endpoint is "unknown".
 */
@Test
public void testGetErrorPublishTopicForMessageWithUnknownEndpoint() {
    final MqttTopicSubscription mqttTopicSubscription = new MqttTopicSubscriptionImpl("error///#", MqttQoS.AT_MOST_ONCE);
    final ErrorSubscription subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, device);
    assertThat(subscription).isNotNull();
    String errorPublishTopic = subscription.getErrorPublishTopic("something", null, null, 503);
    assertThat(errorPublishTopic.split("/")[3]).isEqualTo(ErrorSubscription.UNKNOWN_ENDPOINT);
    errorPublishTopic = subscription.getErrorPublishTopic("", null, null, 503);
    assertThat(errorPublishTopic.split("/")[3]).isEqualTo(ErrorSubscription.UNKNOWN_ENDPOINT);
    errorPublishTopic = subscription.getErrorPublishTopic(null, null, null, 503);
    assertThat(errorPublishTopic.split("/")[3]).isEqualTo(ErrorSubscription.UNKNOWN_ENDPOINT);
}
Also used : MqttTopicSubscriptionImpl(io.vertx.mqtt.impl.MqttTopicSubscriptionImpl) MqttTopicSubscription(io.vertx.mqtt.MqttTopicSubscription) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 9 with MqttTopicSubscription

use of io.vertx.mqtt.MqttTopicSubscription in project hono by eclipse.

the class ErrorSubscriptionTest method testGetErrorPublishTopicForCommandResponseMessage.

/**
 * Verifies that the topic for an error caused by a command response message is correct.
 */
@Test
public void testGetErrorPublishTopicForCommandResponseMessage() {
    final MqttTopicSubscription mqttTopicSubscription = new MqttTopicSubscriptionImpl("error///#", MqttQoS.AT_MOST_ONCE);
    final ErrorSubscription subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, device);
    assertThat(subscription).isNotNull();
    String errorPublishTopic = subscription.getErrorPublishTopic(CommandConstants.COMMAND_ENDPOINT, null, null, 503);
    assertThat(errorPublishTopic.split("/")[3]).isEqualTo(ErrorSubscription.COMMAND_RESPONSE_ENDPOINT);
    errorPublishTopic = subscription.getErrorPublishTopic(CommandConstants.COMMAND_ENDPOINT_SHORT, null, null, 503);
    assertThat(errorPublishTopic.split("/")[3]).isEqualTo(ErrorSubscription.COMMAND_RESPONSE_ENDPOINT_SHORT);
}
Also used : MqttTopicSubscriptionImpl(io.vertx.mqtt.impl.MqttTopicSubscriptionImpl) MqttTopicSubscription(io.vertx.mqtt.MqttTopicSubscription) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 10 with MqttTopicSubscription

use of io.vertx.mqtt.MqttTopicSubscription in project hono by eclipse.

the class ErrorSubscriptionTest method testSubscriptionSucceedsForUnauthenticatedDevice.

/**
 * Verifies that an unauthenticated device can successfully subscribe for errors
 * using the default topic.
 *
 * @param endpointName The endpoint name used in the topic.
 * @param qos The requested QoS.
 */
@ParameterizedTest
@MethodSource("endpointNamesWithQoS")
public void testSubscriptionSucceedsForUnauthenticatedDevice(final String endpointName, final MqttQoS qos) {
    final MqttTopicSubscription mqttTopicSubscription = new MqttTopicSubscriptionImpl(String.format("%s/tenant1/deviceA/#", endpointName), qos);
    final ErrorSubscription subscription = ErrorSubscription.fromTopic(mqttTopicSubscription, null);
    assertThat(subscription).isNotNull();
    assertThat(subscription.getTenant()).isEqualTo("tenant1");
    assertThat(subscription.getDeviceId()).isEqualTo("deviceA");
    assertThat(subscription.getEndpoint()).isEqualTo(endpointName);
    assertThat(subscription.getQos()).isEqualTo(qos);
}
Also used : MqttTopicSubscriptionImpl(io.vertx.mqtt.impl.MqttTopicSubscriptionImpl) MqttTopicSubscription(io.vertx.mqtt.MqttTopicSubscription) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Aggregations

MqttTopicSubscription (io.vertx.mqtt.MqttTopicSubscription)14 MqttTopicSubscriptionImpl (io.vertx.mqtt.impl.MqttTopicSubscriptionImpl)8 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)8 MethodSource (org.junit.jupiter.params.provider.MethodSource)6 MqttEndpoint (io.vertx.mqtt.MqttEndpoint)5 Test (org.junit.jupiter.api.Test)4 MqttSubscribeMessage (io.vertx.mqtt.messages.MqttSubscribeMessage)3 ArrayList (java.util.ArrayList)3 CommandConsumer (org.eclipse.hono.client.command.CommandConsumer)3 MqttQoS (io.netty.handler.codec.mqtt.MqttQoS)2 Span (io.opentracing.Span)2 Handler (io.vertx.core.Handler)2 MqttPublishMessage (io.vertx.mqtt.messages.MqttPublishMessage)2 List (java.util.List)2 AuthHandler (org.eclipse.hono.adapter.auth.device.AuthHandler)2 Command (org.eclipse.hono.client.command.Command)2 AbstractVerticle (io.vertx.core.AbstractVerticle)1 Buffer (io.vertx.core.buffer.Buffer)1 Runner (io.vertx.example.mqtt.util.Runner)1 MqttServer (io.vertx.mqtt.MqttServer)1