Search in sources :

Example 76 with Tracer

use of io.opentracing.Tracer in project Payara by payara.

the class OpenTracingIiopServerInterceptor method receive_request.

@Override
public void receive_request(ServerRequestInfo serverRequestInfo) throws ForwardRequest {
    // Double check we have a tracer
    if (!tracerAvailable()) {
        return;
    }
    ServiceContext serviceContext = serverRequestInfo.get_request_service_context(OPENTRACING_IIOP_ID);
    if (serviceContext == null) {
        return;
    }
    OpenTracingIiopTextMap openTracingIiopTextMap = null;
    try (ByteArrayInputStream bis = new ByteArrayInputStream(serviceContext.context_data);
        ObjectInput in = new OpenTracingIiopObjectInputStream(bis)) {
        openTracingIiopTextMap = (OpenTracingIiopTextMap) in.readObject();
    } catch (IOException | ClassNotFoundException exception) {
        throw new ForwardRequest(exception.getMessage(), serverRequestInfo);
    }
    Tracer.SpanBuilder spanBuilder = tracer.buildSpan("rmi").withTag(Tags.COMPONENT.getKey(), "ejb");
    if (openTracingIiopTextMap != null) {
        SpanContext spanContext = tracer.extract(Format.Builtin.TEXT_MAP, openTracingIiopTextMap);
        // Add the propagated span as a parent
        spanBuilder.asChildOf(spanContext);
    }
    // Start the span and mark it as active
    tracer.activateSpan(spanBuilder.start());
}
Also used : ForwardRequest(org.omg.PortableInterceptor.ForwardRequest) SpanContext(io.opentracing.SpanContext) ByteArrayInputStream(java.io.ByteArrayInputStream) ServiceContext(org.omg.IOP.ServiceContext) Tracer(io.opentracing.Tracer) ObjectInput(java.io.ObjectInput) IOException(java.io.IOException)

Example 77 with Tracer

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

the class KafkaBasedCommandSender method sendCommand.

/**
 * {@inheritDoc}
 *
 * <p>
 * The replyId is not used in the Kafka based implementation. It can be set to {@code null}.
 * If set it will be ignored.
 * <p>
 * If the timeout duration is {@code null} then the default timeout value of
 * {@value DEFAULT_COMMAND_TIMEOUT_IN_MS} ms is used.
 */
@Override
public Future<DownstreamMessage<KafkaMessageContext>> sendCommand(final String tenantId, final String deviceId, final String command, final String contentType, final Buffer data, final String replyId, final Map<String, Object> properties, final Duration timeout, final SpanContext context) {
    Objects.requireNonNull(tenantId);
    Objects.requireNonNull(deviceId);
    Objects.requireNonNull(command);
    final long timeoutInMs = Optional.ofNullable(timeout).map(t -> {
        if (t.isNegative()) {
            throw new IllegalArgumentException("command timeout duration must be >= 0");
        }
        return t.toMillis();
    }).orElse(DEFAULT_COMMAND_TIMEOUT_IN_MS);
    final String correlationId = correlationIdSupplier.get();
    final Span span = TracingHelper.buildChildSpan(tracer, context, "send command and receive response", getClass().getSimpleName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_TENANT_ID, tenantId).withTag(TracingHelper.TAG_DEVICE_ID, deviceId).withTag(TracingHelper.TAG_CORRELATION_ID, correlationId).start();
    final ExpiringCommandPromise expiringCommandPromise = new ExpiringCommandPromise(correlationId, timeoutInMs, // Remove the corresponding pending response entry if times out
    x -> removePendingCommandResponse(tenantId, correlationId), span);
    subscribeForCommandResponse(tenantId, span).compose(ok -> {
        // Store the correlation id and the expiring command promise
        pendingCommandResponses.computeIfAbsent(tenantId, k -> new ConcurrentHashMap<>()).put(correlationId, expiringCommandPromise);
        return sendCommand(tenantId, deviceId, command, contentType, data, correlationId, properties, true, "send command", span.context()).onSuccess(sent -> {
            LOGGER.debug("sent command [correlation-id: {}], waiting for response", correlationId);
            span.log("sent command, waiting for response");
        }).onFailure(error -> {
            LOGGER.debug("error sending command", error);
            // To ensure that the span is not already finished.
            if (!expiringCommandPromise.future().isComplete()) {
                TracingHelper.logError(span, "error sending command", error);
            }
            removePendingCommandResponse(tenantId, correlationId);
            expiringCommandPromise.tryCompleteAndCancelTimer(Future.failedFuture(error));
        });
    });
    return expiringCommandPromise.future().onComplete(o -> span.finish());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) MessagingKafkaConsumerConfigProperties(org.eclipse.hono.client.kafka.consumer.MessagingKafkaConsumerConfigProperties) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) MessagingKafkaProducerConfigProperties(org.eclipse.hono.client.kafka.producer.MessagingKafkaProducerConfigProperties) HonoKafkaConsumer(org.eclipse.hono.client.kafka.consumer.HonoKafkaConsumer) KafkaMessageContext(org.eclipse.hono.application.client.kafka.KafkaMessageContext) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Supplier(java.util.function.Supplier) Tags(io.opentracing.tag.Tags) CompositeFuture(io.vertx.core.CompositeFuture) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) Duration(java.time.Duration) Map(java.util.Map) TracingHelper(org.eclipse.hono.tracing.TracingHelper) AsyncResult(io.vertx.core.AsyncResult) AbstractKafkaBasedMessageSender(org.eclipse.hono.client.kafka.producer.AbstractKafkaBasedMessageSender) Consumer(org.apache.kafka.clients.consumer.Consumer) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Promise(io.vertx.core.Promise) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Vertx(io.vertx.core.Vertx) Set(java.util.Set) ConsumerConfig(org.apache.kafka.clients.consumer.ConsumerConfig) UUID(java.util.UUID) KafkaRecordHelper(org.eclipse.hono.client.kafka.KafkaRecordHelper) MessageHelper(org.eclipse.hono.util.MessageHelper) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) StandardCharsets(java.nio.charset.StandardCharsets) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) HonoTopic(org.eclipse.hono.client.kafka.HonoTopic) List(java.util.List) KafkaProducerFactory(org.eclipse.hono.client.kafka.producer.KafkaProducerFactory) Buffer(io.vertx.core.buffer.Buffer) KafkaConsumerRecord(io.vertx.kafka.client.consumer.KafkaConsumerRecord) CommandSender(org.eclipse.hono.application.client.CommandSender) Optional(java.util.Optional) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) Span(io.opentracing.Span) Handler(io.vertx.core.Handler) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Span(io.opentracing.Span)

Example 78 with Tracer

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

the class ProtonBasedCommandResponseSenderTest method setUp.

/**
 * Sets up the fixture.
 */
@BeforeEach
public void setUp() {
    span = TracingMockSupport.mockSpan();
    final Tracer tracer = TracingMockSupport.mockTracer(span);
    final Vertx vertx = mock(Vertx.class);
    when(vertx.eventBus()).thenReturn(mock(EventBus.class));
    final ClientConfigProperties clientConfigProperties = new ClientConfigProperties();
    protonSender = AmqpClientUnitTestHelper.mockProtonSender();
    connection = AmqpClientUnitTestHelper.mockHonoConnection(vertx, clientConfigProperties, tracer);
    when(connection.isConnected()).thenReturn(Future.succeededFuture());
    when(connection.isConnected(anyLong())).thenReturn(Future.succeededFuture());
    when(connection.createSender(anyString(), any(), any())).thenReturn(Future.succeededFuture(protonSender));
    sender = new ProtonBasedCommandResponseSender(connection, SendMessageSampler.Factory.noop(), false);
}
Also used : Tracer(io.opentracing.Tracer) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) EventBus(io.vertx.core.eventbus.EventBus) Vertx(io.vertx.core.Vertx) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 79 with Tracer

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

the class KafkaBasedInternalCommandConsumer method handleCommandMessage.

void handleCommandMessage(final KafkaConsumerRecord<String, Buffer> record) {
    // get partition/offset of the command record - related to the tenant-based topic the command was originally received in
    final Integer commandPartition = KafkaRecordHelper.getOriginalPartitionHeader(record.headers()).orElse(null);
    final Long commandOffset = KafkaRecordHelper.getOriginalOffsetHeader(record.headers()).orElse(null);
    if (commandPartition == null || commandOffset == null) {
        LOG.warn("command record is invalid - missing required original partition/offset headers");
        return;
    }
    final KafkaBasedCommand command;
    try {
        command = KafkaBasedCommand.fromRoutedCommandRecord(record);
    } catch (final IllegalArgumentException e) {
        LOG.warn("command record is invalid [tenant-id: {}, device-id: {}]", KafkaRecordHelper.getTenantId(record.headers()).orElse(null), KafkaRecordHelper.getDeviceId(record.headers()).orElse(null), e);
        return;
    }
    // check whether command has already been received and handled;
    // partition index and offset here are related to the *tenant-based* topic the command was originally received in
    // therefore they are stored in a map with the tenant as key
    final Map<Integer, Long> lastHandledPartitionOffsets = lastHandledPartitionOffsetsPerTenant.computeIfAbsent(command.getTenant(), k -> new HashMap<>());
    final Long lastHandledOffset = lastHandledPartitionOffsets.get(commandPartition);
    if (lastHandledOffset != null && commandOffset <= lastHandledOffset) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("ignoring command - record partition offset {} <= last handled offset {} [{}]", commandOffset, lastHandledOffset, command);
        }
    } else {
        lastHandledPartitionOffsets.put(commandPartition, commandOffset);
        final CommandHandlerWrapper commandHandler = commandHandlers.getCommandHandler(command.getTenant(), command.getGatewayOrDeviceId());
        if (commandHandler != null && commandHandler.getGatewayId() != null) {
            // Gateway information set in command handler means a gateway has subscribed for commands for a specific device.
            // This information isn't getting set in the record (by the Command Router) and therefore has to be adopted manually here.
            command.setGatewayId(commandHandler.getGatewayId());
        }
        final SpanContext spanContext = KafkaTracingHelper.extractSpanContext(tracer, record);
        final SpanContext followsFromSpanContext = commandHandler != null ? commandHandler.getConsumerCreationSpanContext() : null;
        final Span currentSpan = CommandContext.createSpan(tracer, command, spanContext, followsFromSpanContext, getClass().getSimpleName());
        currentSpan.setTag(MessageHelper.APP_PROPERTY_ADAPTER_INSTANCE_ID, adapterInstanceId);
        KafkaTracingHelper.TAG_OFFSET.set(currentSpan, record.offset());
        final var commandContext = new KafkaBasedCommandContext(command, commandResponseSender, currentSpan);
        tenantClient.get(command.getTenant(), spanContext).onFailure(t -> {
            if (ServiceInvocationException.extractStatusCode(t) == HttpURLConnection.HTTP_NOT_FOUND) {
                commandContext.reject(new TenantDisabledOrNotRegisteredException(command.getTenant(), HttpURLConnection.HTTP_NOT_FOUND));
            } else {
                commandContext.release(new ServerErrorException(command.getTenant(), HttpURLConnection.HTTP_UNAVAILABLE, "error retrieving tenant configuration", t));
            }
        }).onSuccess(tenantConfig -> {
            commandContext.put(CommandContext.KEY_TENANT_CONFIG, tenantConfig);
            if (commandHandler != null) {
                LOG.trace("using [{}] for received command [{}]", commandHandler, command);
                // command.isValid() check not done here - it is to be done in the command handler
                commandHandler.handleCommand(commandContext);
            } else {
                LOG.info("no command handler found for command [{}]", command);
                commandContext.release(new NoConsumerException("no command handler found for command"));
            }
        });
    }
}
Also used : HttpURLConnection(java.net.HttpURLConnection) MessagingKafkaConsumerConfigProperties(org.eclipse.hono.client.kafka.consumer.MessagingKafkaConsumerConfigProperties) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CommandHandlerWrapper(org.eclipse.hono.client.command.CommandHandlerWrapper) TenantDisabledOrNotRegisteredException(org.eclipse.hono.client.registry.TenantDisabledOrNotRegisteredException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) Supplier(java.util.function.Supplier) CommandResponseSender(org.eclipse.hono.client.command.CommandResponseSender) KafkaClientFactory(org.eclipse.hono.client.kafka.KafkaClientFactory) Context(io.vertx.core.Context) NoConsumerException(org.eclipse.hono.client.NoConsumerException) CompositeFuture(io.vertx.core.CompositeFuture) Status(io.vertx.ext.healthchecks.Status) HealthCheckHandler(io.vertx.ext.healthchecks.HealthCheckHandler) KafkaClientMetricsSupport(org.eclipse.hono.client.kafka.metrics.KafkaClientMetricsSupport) Map(java.util.Map) KafkaAdminClientConfigProperties(org.eclipse.hono.client.kafka.KafkaAdminClientConfigProperties) Admin(org.apache.kafka.clients.admin.Admin) CommandHandlers(org.eclipse.hono.client.command.CommandHandlers) KafkaTracingHelper(org.eclipse.hono.client.kafka.tracing.KafkaTracingHelper) CommonClientConfigs(org.apache.kafka.clients.CommonClientConfigs) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Promise(io.vertx.core.Promise) NewTopic(org.apache.kafka.clients.admin.NewTopic) CommandContext(org.eclipse.hono.client.command.CommandContext) Vertx(io.vertx.core.Vertx) Set(java.util.Set) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ConsumerConfig(org.apache.kafka.clients.consumer.ConsumerConfig) KafkaRecordHelper(org.eclipse.hono.client.kafka.KafkaRecordHelper) TenantClient(org.eclipse.hono.client.registry.TenantClient) MessageHelper(org.eclipse.hono.util.MessageHelper) Future(io.vertx.core.Future) InternalCommandConsumer(org.eclipse.hono.client.command.InternalCommandConsumer) SpanContext(io.opentracing.SpanContext) TopicPartition(io.vertx.kafka.client.common.TopicPartition) Objects(java.util.Objects) HonoTopic(org.eclipse.hono.client.kafka.HonoTopic) List(java.util.List) TopicExistsException(org.apache.kafka.common.errors.TopicExistsException) Buffer(io.vertx.core.buffer.Buffer) KafkaConsumerRecord(io.vertx.kafka.client.consumer.KafkaConsumerRecord) Optional(java.util.Optional) Span(io.opentracing.Span) KafkaConsumer(io.vertx.kafka.client.consumer.KafkaConsumer) SpanContext(io.opentracing.SpanContext) NoConsumerException(org.eclipse.hono.client.NoConsumerException) TenantDisabledOrNotRegisteredException(org.eclipse.hono.client.registry.TenantDisabledOrNotRegisteredException) Span(io.opentracing.Span) CommandHandlerWrapper(org.eclipse.hono.client.command.CommandHandlerWrapper) ServerErrorException(org.eclipse.hono.client.ServerErrorException)

Example 80 with Tracer

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

the class RequestResponseClientTest method setUp.

/**
 * Sets up the fixture.
 */
@BeforeEach
public void setUp() {
    span = TracingMockSupport.mockSpan();
    final Tracer tracer = TracingMockSupport.mockTracer(span);
    final EventBus eventBus = mock(EventBus.class);
    vertx = mock(Vertx.class);
    when(vertx.eventBus()).thenReturn(eventBus);
    receiver = AmqpClientUnitTestHelper.mockProtonReceiver();
    sender = AmqpClientUnitTestHelper.mockProtonSender();
    final SendMessageSampler sampler = mock(SendMessageSampler.class);
    sample = mock(SendMessageSampler.Sample.class);
    when(sampler.start(anyString())).thenReturn(sample);
    clientConfig = new RequestResponseClientConfigProperties();
    connection = AmqpClientUnitTestHelper.mockHonoConnection(vertx, clientConfig, tracer);
    when(connection.isConnected(anyLong())).thenReturn(Future.succeededFuture());
    when(connection.createReceiver(anyString(), any(ProtonQoS.class), any(ProtonMessageHandler.class), VertxMockSupport.anyHandler())).thenReturn(Future.succeededFuture(receiver));
    when(connection.createSender(anyString(), any(ProtonQoS.class), VertxMockSupport.anyHandler())).thenReturn(Future.succeededFuture(sender));
    client = RequestResponseClient.forEndpoint(connection, "ep", "tenant", sampler, VertxMockSupport.mockHandler(), VertxMockSupport.mockHandler());
}
Also used : ProtonQoS(io.vertx.proton.ProtonQoS) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) RequestResponseClientConfigProperties(org.eclipse.hono.client.RequestResponseClientConfigProperties) Tracer(io.opentracing.Tracer) EventBus(io.vertx.core.eventbus.EventBus) Vertx(io.vertx.core.Vertx) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler) BeforeEach(org.junit.jupiter.api.BeforeEach)

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