Search in sources :

Example 6 with TenantObject

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

the class FileBasedTenantService method add.

/**
 * Adds a tenant.
 *
 * @param tenantId The identifier of the tenant.
 * @param tenantSpec The information to register for the tenant.
 * @return The outcome of the operation indicating success or failure.
 * @throws NullPointerException if any of the parameters are {@code null}.
 */
public TenantResult<JsonObject> add(final String tenantId, final JsonObject tenantSpec) {
    Objects.requireNonNull(tenantId);
    Objects.requireNonNull(tenantSpec);
    if (getConfig().isModificationEnabled()) {
        if (tenants.containsKey(tenantId)) {
            return TenantResult.from(HttpURLConnection.HTTP_CONFLICT);
        } else {
            try {
                final TenantObject tenant = tenantSpec.mapTo(TenantObject.class);
                tenant.setTenantId(tenantId);
                tenants.put(tenantId, tenant);
                dirty = true;
                return TenantResult.from(HttpURLConnection.HTTP_CREATED);
            } catch (IllegalArgumentException e) {
                return TenantResult.from(HttpURLConnection.HTTP_BAD_REQUEST);
            }
        }
    } else {
        return TenantResult.from(HttpURLConnection.HTTP_FORBIDDEN);
    }
}
Also used : TenantObject(org.eclipse.hono.util.TenantObject)

Example 7 with TenantObject

use of org.eclipse.hono.util.TenantObject 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 8 with TenantObject

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

the class AbstractVertxBasedMqttProtocolAdapterTest method testEndpointHandlerRejectsDeviceOfDisabledTenant.

/**
 * Verifies that an adapter rejects a connection attempt from a device that
 * belongs to a tenant for which the adapter is disabled.
 */
@Test
public void testEndpointHandlerRejectsDeviceOfDisabledTenant() {
    // 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();
    // WHEN a device of "my-tenant" tries to connect
    final MqttAuth deviceCredentials = new MqttAuth("device@my-tenant", "irrelevant");
    final MqttEndpoint endpoint = mock(MqttEndpoint.class);
    when(endpoint.auth()).thenReturn(deviceCredentials);
    adapter.handleEndpointConnection(endpoint);
    // THEN the connection is not established
    verify(endpoint).reject(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED);
}
Also used : ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) TenantObject(org.eclipse.hono.util.TenantObject) MqttAuth(io.vertx.mqtt.MqttAuth) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttServer(io.vertx.mqtt.MqttServer) JsonObject(io.vertx.core.json.JsonObject) Test(org.junit.Test)

Example 9 with TenantObject

use of org.eclipse.hono.util.TenantObject 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)

Example 10 with TenantObject

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

the class AbstractVertxBasedHttpProtocolAdapterTest method testUploadTelemetryFailsForDisabledTenant.

/**
 * Verifies that the adapter fails the upload of an event with a 403
 * result if the device belongs to a tenant for which the adapter is
 * disabled.
 */
@Test
public void testUploadTelemetryFailsForDisabledTenant() {
    // GIVEN an adapter
    final HttpServer server = getHttpServer(false);
    final MessageSender sender = mock(MessageSender.class);
    when(messagingClient.getOrCreateTelemetrySender(anyString())).thenReturn(Future.succeededFuture(sender));
    // 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 AbstractVertxBasedHttpProtocolAdapter<HttpProtocolAdapterProperties> adapter = getAdapter(server, null);
    // WHEN a device that belongs to "my-tenant" publishes a telemetry message
    final Buffer payload = Buffer.buffer("some payload");
    final RoutingContext ctx = newRoutingContext(payload);
    adapter.uploadTelemetryMessage(ctx, "my-tenant", "the-device", payload, "application/text");
    // THEN the device gets a 403
    verify(ctx).fail(HttpURLConnection.HTTP_FORBIDDEN);
    // and the message has not been forwarded downstream
    verify(sender, never()).send(any(Message.class));
}
Also used : Buffer(io.vertx.core.buffer.Buffer) TenantObject(org.eclipse.hono.util.TenantObject) RoutingContext(io.vertx.ext.web.RoutingContext) Message(org.apache.qpid.proton.message.Message) MessageSender(org.eclipse.hono.client.MessageSender) HttpServer(io.vertx.core.http.HttpServer) JsonObject(io.vertx.core.json.JsonObject) Test(org.junit.Test)

Aggregations

TenantObject (org.eclipse.hono.util.TenantObject)13 JsonObject (io.vertx.core.json.JsonObject)9 Message (org.apache.qpid.proton.message.Message)8 Test (org.junit.Test)8 Buffer (io.vertx.core.buffer.Buffer)7 Future (io.vertx.core.Future)6 TestContext (io.vertx.ext.unit.TestContext)6 Vertx (io.vertx.core.Vertx)5 Async (io.vertx.ext.unit.Async)5 HttpURLConnection (java.net.HttpURLConnection)5 TenantConstants (org.eclipse.hono.util.TenantConstants)5 Rule (org.junit.Rule)5 Timeout (org.junit.rules.Timeout)5 Handler (io.vertx.core.Handler)4 TimeUnit (java.util.concurrent.TimeUnit)4 Consumer (java.util.function.Consumer)4 MessageConsumer (org.eclipse.hono.client.MessageConsumer)4 IntegrationTestSupport (org.eclipse.hono.tests.IntegrationTestSupport)4 AfterClass (org.junit.AfterClass)4 Logger (org.slf4j.Logger)4