Search in sources :

Example 26 with Tracer

use of io.opentracing.Tracer in project hono by eclipse.

the class CommandTargetMapperImpl method getTargetGatewayAndAdapterInstance.

@Override
public final Future<JsonObject> getTargetGatewayAndAdapterInstance(final String tenantId, final String deviceId, final SpanContext context) {
    Objects.requireNonNull(tenantId);
    Objects.requireNonNull(deviceId);
    final Span span = TracingHelper.buildChildSpan(tracer, context, "get target gateway and adapter instance", CommandTargetMapper.class.getSimpleName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CONSUMER).withTag(TracingHelper.TAG_TENANT_ID, tenantId).withTag(TracingHelper.TAG_DEVICE_ID, deviceId).start();
    return registrationClient.assertRegistration(tenantId, deviceId, null, span.context()).map(RegistrationAssertion::getAuthorizedGateways).recover(t -> {
        LOG.debug("Error retrieving gateways authorized to act on behalf of device [tenant-id: {}, device-id: {}]", tenantId, deviceId, t);
        return Future.failedFuture(ServiceInvocationException.extractStatusCode(t) == HttpURLConnection.HTTP_NOT_FOUND ? new DeviceDisabledOrNotRegisteredException(tenantId, HttpURLConnection.HTTP_NOT_FOUND) : t);
    }).compose(viaGateways -> {
        return deviceConnectionInfo.getCommandHandlingAdapterInstances(tenantId, deviceId, new HashSet<>(viaGateways), span).compose(resultJson -> determineTargetInstanceJson(resultJson, deviceId, viaGateways, span));
    }).onFailure(t -> {
        LOG.debug("Error getting target gateway and adapter instance", t);
        TracingHelper.logError(span, t);
        Tags.HTTP_STATUS.set(span, ServiceInvocationException.extractStatusCode(t));
    }).onComplete(ar -> span.finish());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) DeviceConnectionConstants(org.eclipse.hono.util.DeviceConnectionConstants) LoggerFactory(org.slf4j.LoggerFactory) ServerErrorException(org.eclipse.hono.client.ServerErrorException) CommandTargetMapper(org.eclipse.hono.commandrouter.CommandTargetMapper) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) MessageHelper(org.eclipse.hono.util.MessageHelper) Tags(io.opentracing.tag.Tags) Future(io.vertx.core.Future) DeviceConnectionInfo(org.eclipse.hono.deviceconnection.infinispan.client.DeviceConnectionInfo) SpanContext(io.opentracing.SpanContext) HashSet(java.util.HashSet) Objects(java.util.Objects) DeviceDisabledOrNotRegisteredException(org.eclipse.hono.client.registry.DeviceDisabledOrNotRegisteredException) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) DeviceRegistrationClient(org.eclipse.hono.client.registry.DeviceRegistrationClient) Span(io.opentracing.Span) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) CommandTargetMapper(org.eclipse.hono.commandrouter.CommandTargetMapper) DeviceDisabledOrNotRegisteredException(org.eclipse.hono.client.registry.DeviceDisabledOrNotRegisteredException) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) Span(io.opentracing.Span) HashSet(java.util.HashSet)

Example 27 with Tracer

use of io.opentracing.Tracer in project hono by eclipse.

the class EdgeDeviceAutoProvisioner method performAutoProvisioning.

/**
 * Auto-provisions the edge device using the given device id and the given registration data.
 *
 * @param tenantId The id of the tenant for which the edge device should be provisioned.
 * @param tenant The tenant information.
 * @param deviceId The id of the edge device which should be provisioned, may be {@code null}.
 * @param gatewayId The id of the edge device's gateway.
 * @param device The registration data for the device to be auto-provisioned.
 * @param spanContext The tracing context to be used by this operation.
 *
 * @return A future indicating the outcome of the operation.
 *
 * @throws NullPointerException if any argument except deviceId is {@code null}.
 */
public Future<Device> performAutoProvisioning(final String tenantId, final Tenant tenant, final String deviceId, final String gatewayId, final Device device, final SpanContext spanContext) {
    Objects.requireNonNull(tenantId);
    Objects.requireNonNull(tenant);
    Objects.requireNonNull(gatewayId);
    Objects.requireNonNull(device);
    Objects.requireNonNull(spanContext);
    final Span span = TracingHelper.buildChildSpan(tracer, spanContext, "auto-provision edge device connected via gateway", Constants.PROTOCOL_ADAPTER_TYPE_DEVICE_REGISTRY).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_GATEWAY_ID, gatewayId).start();
    TracingHelper.setDeviceTags(span, tenantId, deviceId);
    return deviceManagementService.createDevice(tenantId, Optional.of(deviceId), device, span).recover(thr -> ServiceInvocationException.extractStatusCode(thr) == HttpURLConnection.HTTP_CONFLICT ? Future.succeededFuture(OperationResult.empty(HttpURLConnection.HTTP_CONFLICT)) : Future.failedFuture(thr)).compose(addEdgeDeviceResult -> {
        if (addEdgeDeviceResult.isError()) {
            if (addEdgeDeviceResult.getStatus() != HttpURLConnection.HTTP_CONFLICT) {
                return Future.failedFuture(StatusCodeMapper.from(addEdgeDeviceResult.getStatus(), String.format("failed to add edge device (status %d)", addEdgeDeviceResult.getStatus())));
            }
            // handle HTTP_CONFLICT, meaning the device already exists
            span.log("device already exists");
            LOG.debug("device [{}] for gateway [{}] already created by concurrent auto-provisioning [tenant-id: {}]", deviceId, gatewayId, tenantId);
            return deviceManagementService.readDevice(tenantId, deviceId, span).compose(readDeviceResult -> {
                if (!readDeviceResult.isOk()) {
                    span.log("reading device after conflict failed");
                    LOG.warn("reading device after conflict failed for device [{}] of gateway [{}] of tenant [{}]: status: {}", deviceId, gatewayId, tenantId, readDeviceResult.getStatus());
                    return Future.failedFuture(StatusCodeMapper.from(readDeviceResult.getStatus(), String.format("reading device after conflict failed (status %d)", readDeviceResult.getStatus())));
                }
                if (!readDeviceResult.getPayload().getVia().contains(gatewayId)) {
                    span.log("attempted to auto-provision same device via two different gateways at the same time");
                    LOG.info("attempted to auto-provision device [{}] via gateway [{}] of tenant [{}] but the registration data's via contains only {}", deviceId, gatewayId, tenantId, readDeviceResult.getPayload().getVia());
                    return Future.failedFuture(StatusCodeMapper.from(HttpURLConnection.HTTP_FORBIDDEN, "device already auto-provisioned for another gateway"));
                }
                final Device readDevice = readDeviceResult.getPayload();
                // ensure that a notification event gets sent (even if we might send duplicate events)
                return sendDelayedAutoProvisioningNotificationIfNeeded(tenantId, tenant, deviceId, gatewayId, readDevice, span).map(readDevice);
            });
        }
        span.log("device created");
        LOG.trace("device [{}] for gateway [{}] successfully created by auto-provisioning [tenant-id: {}]", deviceId, gatewayId, tenantId);
        return sendAutoProvisioningEvent(tenantId, tenant, deviceId, gatewayId, span).compose(sendEmptyEventOk -> deviceManagementService.readDevice(tenantId, deviceId, span).compose(readDeviceResult -> {
            if (!readDeviceResult.isOk()) {
                LOG.warn("notification flag of device [{}] for gateway [{}] of tenant [tenant-id: {}] could not be updated", deviceId, gatewayId, tenantId);
                return Future.failedFuture(StatusCodeMapper.from(readDeviceResult.getStatus(), String.format("update of notification flag failed (status %d)", readDeviceResult.getStatus())));
            }
            final Device deviceData = readDeviceResult.getPayload();
            return updateAutoProvisioningNotificationSent(tenantId, deviceId, deviceData, readDeviceResult.getResourceVersion(), span).recover(error -> Future.succeededFuture()).map(deviceData);
        }));
    }).onFailure(thr -> TracingHelper.logError(span, thr)).onComplete(ar -> span.finish());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) Device(org.eclipse.hono.service.management.device.Device) Tracer(io.opentracing.Tracer) EventSender(org.eclipse.hono.client.telemetry.EventSender) MessagingClientProvider(org.eclipse.hono.client.util.MessagingClientProvider) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) Constants(org.eclipse.hono.util.Constants) Tags(io.opentracing.tag.Tags) Future(io.vertx.core.Future) Tenant(org.eclipse.hono.service.management.tenant.Tenant) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) DeviceManagementService(org.eclipse.hono.service.management.device.DeviceManagementService) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) Optional(java.util.Optional) OperationResult(org.eclipse.hono.service.management.OperationResult) Span(io.opentracing.Span) TracingHelper(org.eclipse.hono.tracing.TracingHelper) Device(org.eclipse.hono.service.management.device.Device) Span(io.opentracing.Span)

Example 28 with Tracer

use of io.opentracing.Tracer in project hono by eclipse.

the class ProtonBasedMappingAndDelegatingCommandHandlerTest method mockHonoConnection.

private static <T> HonoConnection mockHonoConnection(final Vertx vertx, final ClientConfigProperties props) {
    final Tracer tracer = NoopTracerFactory.create();
    final HonoConnection connection = mock(HonoConnection.class);
    when(connection.getVertx()).thenReturn(vertx);
    when(connection.getConfig()).thenReturn(props);
    when(connection.getTracer()).thenReturn(tracer);
    when(connection.executeOnContext(VertxMockSupport.anyHandler())).then(invocation -> {
        final Promise<T> result = Promise.promise();
        final Handler<Future<T>> handler = invocation.getArgument(0);
        handler.handle(result.future());
        return result.future();
    });
    return connection;
}
Also used : HonoConnection(org.eclipse.hono.client.HonoConnection) Tracer(io.opentracing.Tracer) Future(io.vertx.core.Future)

Example 29 with Tracer

use of io.opentracing.Tracer in project hono by eclipse.

the class CacheBasedDeviceConnectionInfoTest method testGetCommandHandlingAdapterInstancesWithTerminatedAdapterInstanceContainer.

/**
 * Verifies that the <em>getCommandHandlingAdapterInstances</em> operation succeeds with a result containing
 * the mapping of a gateway device if the also existing mapping belonging to the *the given device* is associated
 * with an adapter instance identified as already terminated.
 *
 * @param extraUnusedViaGateways Test values.
 * @param ctx The vert.x context.
 */
@ParameterizedTest(name = PARAMETERIZED_TEST_NAME_PATTERN)
@MethodSource("extraUnusedViaGateways")
public void testGetCommandHandlingAdapterInstancesWithTerminatedAdapterInstanceContainer(final Set<String> extraUnusedViaGateways, final VertxTestContext ctx) {
    final AdapterInstanceStatusProvider statusProvider = mock(AdapterInstanceStatusProvider.class);
    info = new CacheBasedDeviceConnectionInfo(cache, tracer, statusProvider);
    final String deviceId = "testDevice";
    final String adapterInstance = "adapterInstance";
    final String otherAdapterInstance = "otherAdapterInstance";
    final String gatewayId = "gw-1";
    final Set<String> viaGateways = new HashSet<>(Set.of(gatewayId));
    viaGateways.addAll(extraUnusedViaGateways);
    // GIVEN testDevice has no last known gateway registered
    when(cache.get(CacheBasedDeviceConnectionInfo.getGatewayEntryKey(Constants.DEFAULT_TENANT, deviceId))).thenReturn(Future.succeededFuture());
    // and testDevice's and gw-1's command handling adapter instances are set to
    // adapterInstance and otherAdapterInstance respectively
    when(cache.getAll(CacheBasedDeviceConnectionInfo.getAdapterInstanceEntryKeys(Constants.DEFAULT_TENANT, deviceId, viaGateways))).thenReturn(Future.succeededFuture(Map.of(CacheBasedDeviceConnectionInfo.getAdapterInstanceEntryKey(Constants.DEFAULT_TENANT, deviceId), adapterInstance, CacheBasedDeviceConnectionInfo.getAdapterInstanceEntryKey(Constants.DEFAULT_TENANT, gatewayId), otherAdapterInstance)));
    when(cache.remove(anyString(), anyString())).thenReturn(Future.succeededFuture(Boolean.TRUE));
    when(statusProvider.getStatus(adapterInstance)).thenReturn(AdapterInstanceStatus.DEAD);
    when(statusProvider.getStatus(otherAdapterInstance)).thenReturn(AdapterInstanceStatus.ALIVE);
    info.getCommandHandlingAdapterInstances(Constants.DEFAULT_TENANT, deviceId, viaGateways, span).onComplete(ctx.succeeding(result -> {
        ctx.verify(() -> {
            assertNotNull(result);
            assertGetInstancesResultMapping(result, gatewayId, otherAdapterInstance);
            assertGetInstancesResultSize(result, 1);
            // verify mapping entry for terminated adapter instance has been removed
            verify(cache).remove(CacheBasedDeviceConnectionInfo.getAdapterInstanceEntryKey(Constants.DEFAULT_TENANT, deviceId), adapterInstance);
        });
        ctx.completeNow();
    }));
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) BeforeEach(org.junit.jupiter.api.BeforeEach) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ArgumentMatchers.anyMap(org.mockito.ArgumentMatchers.anyMap) AdapterInstanceStatus(org.eclipse.hono.util.AdapterInstanceStatus) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Constants(org.eclipse.hono.util.Constants) Timeout(io.vertx.junit5.Timeout) HashSet(java.util.HashSet) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Duration(java.time.Duration) Map(java.util.Map) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) MethodSource(org.junit.jupiter.params.provider.MethodSource) Tracer(io.opentracing.Tracer) DeviceConnectionConstants(org.eclipse.hono.util.DeviceConnectionConstants) Set(java.util.Set) ServerErrorException(org.eclipse.hono.client.ServerErrorException) IOException(java.io.IOException) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) JsonArray(io.vertx.core.json.JsonArray) Mockito.never(org.mockito.Mockito.never) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Stream(java.util.stream.Stream) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Span(io.opentracing.Span) Collections(java.util.Collections) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) HashSet(java.util.HashSet) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 30 with Tracer

use of io.opentracing.Tracer in project hono by eclipse.

the class CacheBasedDeviceConnectionInfoTest method testGetCommandHandlingAdapterInstancesWithSuspectedAdapterInstance.

/**
 * Verifies that the <em>getCommandHandlingAdapterInstances</em> operation fails
 * if the adapter instance mapping entry is associated with a adapter having the state 'SUSPECTED_DEAD'.
 *
 * @param ctx The vert.x context.
 */
@Test
public void testGetCommandHandlingAdapterInstancesWithSuspectedAdapterInstance(final VertxTestContext ctx) {
    final AdapterInstanceStatusProvider statusProvider = mock(AdapterInstanceStatusProvider.class);
    info = new CacheBasedDeviceConnectionInfo(cache, tracer, statusProvider);
    final String deviceId = "testDevice";
    final String adapterInstance = "adapterInstance";
    when(cache.get(anyString())).thenReturn(Future.succeededFuture(adapterInstance));
    when(statusProvider.getStatus(adapterInstance)).thenReturn(AdapterInstanceStatus.SUSPECTED_DEAD);
    when(cache.remove(anyString(), anyString())).thenReturn(Future.succeededFuture(Boolean.TRUE));
    info.getCommandHandlingAdapterInstances(Constants.DEFAULT_TENANT, deviceId, Set.of(), span).onComplete(ctx.failing(t -> {
        ctx.verify(() -> {
            verify(cache).get(CacheBasedDeviceConnectionInfo.getAdapterInstanceEntryKey(Constants.DEFAULT_TENANT, deviceId));
            assertThat(t).isInstanceOf(ClientErrorException.class);
            assertThat(((ClientErrorException) t).getErrorCode()).isEqualTo(HttpURLConnection.HTTP_NOT_FOUND);
            // verify mapping entry for terminated adapter instance has not been removed
            verify(cache, never()).remove(CacheBasedDeviceConnectionInfo.getAdapterInstanceEntryKey(Constants.DEFAULT_TENANT, deviceId), adapterInstance);
        });
        ctx.completeNow();
    }));
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) BeforeEach(org.junit.jupiter.api.BeforeEach) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ArgumentMatchers.anyMap(org.mockito.ArgumentMatchers.anyMap) AdapterInstanceStatus(org.eclipse.hono.util.AdapterInstanceStatus) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Constants(org.eclipse.hono.util.Constants) Timeout(io.vertx.junit5.Timeout) HashSet(java.util.HashSet) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Duration(java.time.Duration) Map(java.util.Map) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) MethodSource(org.junit.jupiter.params.provider.MethodSource) Tracer(io.opentracing.Tracer) DeviceConnectionConstants(org.eclipse.hono.util.DeviceConnectionConstants) Set(java.util.Set) ServerErrorException(org.eclipse.hono.client.ServerErrorException) IOException(java.io.IOException) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) JsonArray(io.vertx.core.json.JsonArray) Mockito.never(org.mockito.Mockito.never) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Stream(java.util.stream.Stream) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Span(io.opentracing.Span) Collections(java.util.Collections) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Mockito.mock(org.mockito.Mockito.mock) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

Tracer (io.opentracing.Tracer)104 Span (io.opentracing.Span)49 SpanContext (io.opentracing.SpanContext)30 Map (java.util.Map)21 Vertx (io.vertx.core.Vertx)19 HashMap (java.util.HashMap)19 Test (org.junit.Test)19 BeforeEach (org.junit.jupiter.api.BeforeEach)19 Test (org.junit.jupiter.api.Test)19 Future (io.vertx.core.Future)18 Buffer (io.vertx.core.buffer.Buffer)16 HttpURLConnection (java.net.HttpURLConnection)14 EventBus (io.vertx.core.eventbus.EventBus)13 JsonObject (io.vertx.core.json.JsonObject)12 Objects (java.util.Objects)12 Logger (org.slf4j.Logger)11 LoggerFactory (org.slf4j.LoggerFactory)11 Tags (io.opentracing.tag.Tags)9 Scope (io.opentracing.Scope)8 GlobalTracer (io.opentracing.util.GlobalTracer)8