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();
}
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();
}
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);
}
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);
}
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);
}
Aggregations