Search in sources :

Example 1 with MessageSender

use of org.eclipse.hono.client.MessageSender in project hono by eclipse.

the class StandaloneEventApiTest method testMalformedMessageGetsRejected.

/**
 * Verifies that malformed messages are not forwarded downstream.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testMalformedMessageGetsRejected(final TestContext ctx) {
    final Message msg = ProtonHelper.message("malformed");
    msg.setMessageId("malformed-message");
    final Future<MessageSender> senderTracker = getSender(Constants.DEFAULT_TENANT);
    senderTracker.compose(sender -> {
        return sender.send(msg);
    }).setHandler(ctx.asyncAssertFailure(t -> {
        ctx.assertTrue(ClientErrorException.class.isInstance(t));
        ctx.assertTrue(senderTracker.result().isOpen());
    }));
}
Also used : TestContext(io.vertx.ext.unit.TestContext) AuthoritiesImpl(org.eclipse.hono.auth.AuthoritiesImpl) HonoUserAdapter(org.eclipse.hono.auth.HonoUserAdapter) BeforeClass(org.junit.BeforeClass) RunWith(org.junit.runner.RunWith) ClientErrorException(org.eclipse.hono.client.ClientErrorException) HonoUser(org.eclipse.hono.auth.HonoUser) Constants(org.eclipse.hono.util.Constants) ProtonClientOptions(io.vertx.proton.ProtonClientOptions) MessageSender(org.eclipse.hono.client.MessageSender) Message(org.apache.qpid.proton.message.Message) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) Vertx(io.vertx.core.Vertx) Test(org.junit.Test) ProtonHelper(io.vertx.proton.ProtonHelper) VertxUnitRunner(io.vertx.ext.unit.junit.VertxUnitRunner) Activity(org.eclipse.hono.auth.Activity) HonoClientImpl(org.eclipse.hono.client.impl.HonoClientImpl) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) TestSupport(org.eclipse.hono.TestSupport) Authorities(org.eclipse.hono.auth.Authorities) HonoSaslAuthenticatorFactory(org.eclipse.hono.service.auth.HonoSaslAuthenticatorFactory) Mockito.mock(org.mockito.Mockito.mock) EventEndpoint(org.eclipse.hono.event.impl.EventEndpoint) Message(org.apache.qpid.proton.message.Message) MessageSender(org.eclipse.hono.client.MessageSender) Test(org.junit.Test)

Example 2 with MessageSender

use of org.eclipse.hono.client.MessageSender in project hono by eclipse.

the class ClientTestBase method connect.

/**
 * Sets up the environment:
 * <ol>
 * <li>connect to the AMQP messaging network</li>
 * <li>connects to the Hono Server</li>
 * <li>connects to the Hono Device Registry</li>
 * <li>creates a RegistrationClient for TEST_TENANT_ID</li>
 * <li>creates a MessageSender for TEST_TENANT_ID</li>
 * </ul>
 *
 * @param ctx The test context
 */
@Before
public void connect(final TestContext ctx) {
    final ClientConfigProperties downstreamProps = new ClientConfigProperties();
    downstreamProps.setHost(IntegrationTestSupport.DOWNSTREAM_HOST);
    downstreamProps.setPort(IntegrationTestSupport.DOWNSTREAM_PORT);
    downstreamProps.setPathSeparator(IntegrationTestSupport.PATH_SEPARATOR);
    downstreamProps.setUsername(IntegrationTestSupport.RESTRICTED_CONSUMER_NAME);
    downstreamProps.setPassword(IntegrationTestSupport.RESTRICTED_CONSUMER_PWD);
    downstreamClient = new HonoClientImpl(vertx, ConnectionFactoryBuilder.newBuilder(downstreamProps).vertx(vertx).build(), downstreamProps);
    final ClientConfigProperties honoProps = new ClientConfigProperties();
    honoProps.setHost(IntegrationTestSupport.HONO_HOST);
    honoProps.setPort(IntegrationTestSupport.HONO_PORT);
    honoProps.setUsername(IntegrationTestSupport.HONO_USER);
    honoProps.setPassword(IntegrationTestSupport.HONO_PWD);
    honoClient = new HonoClientImpl(vertx, ConnectionFactoryBuilder.newBuilder(honoProps).vertx(vertx).build(), honoProps);
    final ClientConfigProperties registryProps = new ClientConfigProperties();
    registryProps.setHost(IntegrationTestSupport.HONO_DEVICEREGISTRY_HOST);
    registryProps.setPort(IntegrationTestSupport.HONO_DEVICEREGISTRY_AMQP_PORT);
    registryProps.setUsername(IntegrationTestSupport.HONO_USER);
    registryProps.setPassword(IntegrationTestSupport.HONO_PWD);
    honoDeviceRegistryClient = new HonoClientImpl(vertx, ConnectionFactoryBuilder.newBuilder(registryProps).vertx(vertx).build(), registryProps);
    final ProtonClientOptions options = new ProtonClientOptions();
    // connect to AMQP messaging network
    final Future<HonoClient> downstreamTracker = downstreamClient.connect(options);
    // create sender
    final Future<MessageSender> senderTracker = honoClient.connect(options).compose(connectedClient -> createProducer(TEST_TENANT_ID)).map(s -> {
        sender = s;
        return s;
    });
    // create registration client
    final Future<RegistrationClient> registrationClientTracker = honoDeviceRegistryClient.connect(options).compose(connectedClient -> connectedClient.getOrCreateRegistrationClient(TEST_TENANT_ID)).map(c -> {
        registrationClient = c;
        return c;
    });
    CompositeFuture.all(downstreamTracker, senderTracker, registrationClientTracker).setHandler(ctx.asyncAssertSuccess(s -> {
        LOGGER.info("connections to Hono server, Hono device registry and AMQP messaging network established");
    }));
}
Also used : TestContext(io.vertx.ext.unit.TestContext) Async(io.vertx.ext.unit.Async) LoggerFactory(org.slf4j.LoggerFactory) MessageConsumer(org.eclipse.hono.client.MessageConsumer) AtomicReference(java.util.concurrent.atomic.AtomicReference) Constants(org.eclipse.hono.util.Constants) CompositeFuture(io.vertx.core.CompositeFuture) ProtonClientOptions(io.vertx.proton.ProtonClientOptions) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConnectionFactoryBuilder(org.eclipse.hono.connection.ConnectionFactoryImpl.ConnectionFactoryBuilder) MessageSender(org.eclipse.hono.client.MessageSender) After(org.junit.After) Message(org.apache.qpid.proton.message.Message) RegistrationClient(org.eclipse.hono.client.RegistrationClient) HonoClient(org.eclipse.hono.client.HonoClient) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) Before(org.junit.Before) Logger(org.slf4j.Logger) Vertx(io.vertx.core.Vertx) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) Test(org.junit.Test) HonoClientImpl(org.eclipse.hono.client.impl.HonoClientImpl) MessageHelper(org.eclipse.hono.util.MessageHelper) Future(io.vertx.core.Future) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CountDownLatch(java.util.concurrent.CountDownLatch) HonoClientImpl(org.eclipse.hono.client.impl.HonoClientImpl) HonoClient(org.eclipse.hono.client.HonoClient) MessageSender(org.eclipse.hono.client.MessageSender) RegistrationClient(org.eclipse.hono.client.RegistrationClient) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) ProtonClientOptions(io.vertx.proton.ProtonClientOptions) Before(org.junit.Before)

Example 3 with MessageSender

use of org.eclipse.hono.client.MessageSender in project hono by eclipse.

the class AbstractVertxBasedHttpProtocolAdapterTest method givenATelemetrySenderForOutcome.

private void givenATelemetrySenderForOutcome(final Future<ProtonDelivery> outcome) {
    final MessageSender sender = mock(MessageSender.class);
    when(sender.send(any(Message.class))).thenReturn(outcome);
    when(messagingClient.getOrCreateTelemetrySender(anyString())).thenReturn(Future.succeededFuture(sender));
}
Also used : Message(org.apache.qpid.proton.message.Message) MessageSender(org.eclipse.hono.client.MessageSender)

Example 4 with MessageSender

use of org.eclipse.hono.client.MessageSender in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapter method uploadMessage.

private Future<Void> uploadMessage(final MqttContext ctx, final String tenant, final String deviceId, final Buffer payload, final Future<MessageSender> senderTracker, final String endpointName) {
    if (payload.length() == 0) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "payload must not be empty"));
    } else {
        final Future<JsonObject> tokenTracker = getRegistrationAssertion(tenant, deviceId, ctx.authenticatedDevice());
        final Future<TenantObject> tenantConfigTracker = getTenantConfiguration(tenant);
        return CompositeFuture.all(tokenTracker, tenantConfigTracker, senderTracker).compose(ok -> {
            if (tenantConfigTracker.result().isAdapterEnabled(getTypeName())) {
                final Message downstreamMessage = newMessage(String.format("%s/%s", endpointName, tenant), deviceId, ctx.message().topicName(), ctx.contentType(), payload, tokenTracker.result());
                customizeDownstreamMessage(downstreamMessage, ctx);
                return senderTracker.result().send(downstreamMessage);
            } else {
                // this adapter is not enabled for the tenant
                return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN));
            }
        }).compose(delivery -> {
            LOG.trace("successfully processed message [topic: {}, QoS: {}] for device [tenantId: {}, deviceId: {}]", ctx.message().topicName(), ctx.message().qosLevel(), tenant, deviceId);
            metrics.incrementProcessedMqttMessages(endpointName, tenant);
            onMessageSent(ctx);
            // check that the remote MQTT client is still connected before sending PUBACK
            if (ctx.deviceEndpoint().isConnected() && ctx.message().qosLevel() == MqttQoS.AT_LEAST_ONCE) {
                ctx.deviceEndpoint().publishAcknowledge(ctx.message().messageId());
            }
            return Future.<Void>succeededFuture();
        }).recover(t -> {
            if (ClientErrorException.class.isInstance(t)) {
                ClientErrorException e = (ClientErrorException) t;
                LOG.debug("cannot process message for device [tenantId: {}, deviceId: {}, endpoint: {}]: {} - {}", tenant, deviceId, endpointName, e.getErrorCode(), e.getMessage());
            } else {
                LOG.debug("cannot process message for device [tenantId: {}, deviceId: {}, endpoint: {}]", tenant, deviceId, endpointName, t);
                metrics.incrementUndeliverableMqttMessages(endpointName, tenant);
                onMessageUndeliverable(ctx);
            }
            return Future.failedFuture(t);
        });
    }
}
Also used : HttpURLConnection(java.net.HttpURLConnection) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) LoggerFactory(org.slf4j.LoggerFactory) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) Autowired(org.springframework.beans.factory.annotation.Autowired) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) Constants(org.eclipse.hono.util.Constants) MqttServer(io.vertx.mqtt.MqttServer) CompositeFuture(io.vertx.core.CompositeFuture) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) MessageSender(org.eclipse.hono.client.MessageSender) AbstractProtocolAdapterBase(org.eclipse.hono.service.AbstractProtocolAdapterBase) Message(org.apache.qpid.proton.message.Message) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) JsonObject(io.vertx.core.json.JsonObject) ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) UsernamePasswordCredentials(org.eclipse.hono.service.auth.device.UsernamePasswordCredentials) Logger(org.slf4j.Logger) MqttServerOptions(io.vertx.mqtt.MqttServerOptions) DeviceCredentials(org.eclipse.hono.service.auth.device.DeviceCredentials) ServerErrorException(org.eclipse.hono.client.ServerErrorException) EndpointType(org.eclipse.hono.util.EndpointType) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) TenantObject(org.eclipse.hono.util.TenantObject) Objects(java.util.Objects) Buffer(io.vertx.core.buffer.Buffer) MqttAuth(io.vertx.mqtt.MqttAuth) Device(org.eclipse.hono.service.auth.device.Device) TenantObject(org.eclipse.hono.util.TenantObject) Message(org.apache.qpid.proton.message.Message) ClientErrorException(org.eclipse.hono.client.ClientErrorException) JsonObject(io.vertx.core.json.JsonObject)

Example 5 with MessageSender

use of org.eclipse.hono.client.MessageSender in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method testUploadTelemetryMessageFailsForDisabledTenant.

/**
 * Verifies that the adapter does not forward a message published by a device
 * if the device belongs to a tenant for which the adapter has been disabled.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testUploadTelemetryMessageFailsForDisabledTenant(final TestContext ctx) {
    // GIVEN an adapter
    final MqttServer server = getMqttServer(false);
    // which is disabled for tenant "my-tenant"
    final TenantObject myTenantConfig = TenantObject.from("my-tenant", true);
    myTenantConfig.addAdapterConfiguration(new JsonObject().put(TenantConstants.FIELD_ADAPTERS_TYPE, ADAPTER_TYPE).put(TenantConstants.FIELD_ENABLED, false));
    when(tenantClient.get("my-tenant")).thenReturn(Future.succeededFuture(myTenantConfig));
    final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server);
    forceClientMocksToConnected();
    final MessageSender sender = mock(MessageSender.class);
    when(messagingClient.getOrCreateTelemetrySender(anyString())).thenReturn(Future.succeededFuture(sender));
    // WHEN a device of "my-tenant" publishes a telemetry message
    adapter.uploadTelemetryMessage(new MqttContext(mock(MqttPublishMessage.class), mock(MqttEndpoint.class)), "my-tenant", "the-device", Buffer.buffer("test")).setHandler(ctx.asyncAssertFailure(t -> {
        // THEN the message has not been sent downstream
        verify(sender, never()).send(any(Message.class));
        // because the tenant is not enabled
        ctx.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, ((ClientErrorException) t).getErrorCode());
    }));
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) HttpURLConnection(java.net.HttpURLConnection) TestContext(io.vertx.ext.unit.TestContext) Async(io.vertx.ext.unit.Async) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) ArgumentMatchers(org.mockito.ArgumentMatchers) ProtonDelivery(io.vertx.proton.ProtonDelivery) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) TenantConstants(org.eclipse.hono.util.TenantConstants) RunWith(org.junit.runner.RunWith) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Context(io.vertx.core.Context) MqttServer(io.vertx.mqtt.MqttServer) Assert.assertThat(org.junit.Assert.assertThat) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) ArgumentCaptor(org.mockito.ArgumentCaptor) TenantClient(org.eclipse.hono.client.TenantClient) MessageSender(org.eclipse.hono.client.MessageSender) BiConsumer(java.util.function.BiConsumer) Timeout(org.junit.rules.Timeout) Message(org.apache.qpid.proton.message.Message) RegistrationClient(org.eclipse.hono.client.RegistrationClient) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult) HonoClient(org.eclipse.hono.client.HonoClient) Before(org.junit.Before) ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) AfterClass(org.junit.AfterClass) UsernamePasswordCredentials(org.eclipse.hono.service.auth.device.UsernamePasswordCredentials) DeviceCredentials(org.eclipse.hono.service.auth.device.DeviceCredentials) Vertx(io.vertx.core.Vertx) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) Test(org.junit.Test) VertxUnitRunner(io.vertx.ext.unit.junit.VertxUnitRunner) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) TenantObject(org.eclipse.hono.util.TenantObject) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) HonoClientBasedAuthProvider(org.eclipse.hono.service.auth.device.HonoClientBasedAuthProvider) Rule(org.junit.Rule) Buffer(io.vertx.core.buffer.Buffer) MqttAuth(io.vertx.mqtt.MqttAuth) Device(org.eclipse.hono.service.auth.device.Device) Handler(io.vertx.core.Handler) ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) TenantObject(org.eclipse.hono.util.TenantObject) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MessageSender(org.eclipse.hono.client.MessageSender) MqttServer(io.vertx.mqtt.MqttServer) JsonObject(io.vertx.core.json.JsonObject) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Test(org.junit.Test)

Aggregations

MessageSender (org.eclipse.hono.client.MessageSender)16 Message (org.apache.qpid.proton.message.Message)15 Test (org.junit.Test)10 Handler (io.vertx.core.Handler)8 ProtonDelivery (io.vertx.proton.ProtonDelivery)8 Future (io.vertx.core.Future)7 Vertx (io.vertx.core.Vertx)6 TestContext (io.vertx.ext.unit.TestContext)5 TimeUnit (java.util.concurrent.TimeUnit)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)5 ClientErrorException (org.eclipse.hono.client.ClientErrorException)5 HonoClient (org.eclipse.hono.client.HonoClient)5 Constants (org.eclipse.hono.util.Constants)5 Async (io.vertx.ext.unit.Async)4 MqttPublishMessage (io.vertx.mqtt.messages.MqttPublishMessage)4 HttpURLConnection (java.net.HttpURLConnection)4 RegistrationClient (org.eclipse.hono.client.RegistrationClient)4 Before (org.junit.Before)4 MqttConnectReturnCode (io.netty.handler.codec.mqtt.MqttConnectReturnCode)3 MqttQoS (io.netty.handler.codec.mqtt.MqttQoS)3