use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class TracingPropagationTest method testFromKafkaToAppToKafka.
@Test
public void testFromKafkaToAppToKafka() {
List<Context> receivedContexts = new CopyOnWriteArrayList<>();
String resultTopic = topic + "-result";
String parentTopic = topic + "-parent";
ConsumerTask<String, Integer> consumed = companion.consumeIntegers().fromTopics(resultTopic, m -> m.plug(until(10L, Duration.ofMinutes(1), null)).onItem().invoke(record -> {
receivedContexts.add(GlobalOpenTelemetry.getPropagators().getTextMapPropagator().extract(Context.current(), record.headers(), new HeaderExtractAdapter()));
}));
MyAppProcessingData bean = runApplication(getKafkaSinkConfigForMyAppProcessingData(resultTopic, parentTopic), MyAppProcessingData.class);
List<SpanContext> producedSpanContexts = new CopyOnWriteArrayList<>();
companion.produceIntegers().usingGenerator(i -> new ProducerRecord<>(parentTopic, null, null, "a-key", i, createTracingSpan(producedSpanContexts, parentTopic)), 10);
await().until(() -> consumed.getRecords().size() >= 10);
List<Integer> values = new ArrayList<>();
assertThat(consumed.getRecords()).allSatisfy(record -> {
assertThat(record.value()).isNotNull();
values.add(record.value());
});
assertThat(values).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<String> producedTraceIds = producedSpanContexts.stream().map(SpanContext::getTraceId).collect(Collectors.toList());
assertThat(producedTraceIds).hasSize(10);
assertThat(receivedContexts).hasSize(10);
assertThat(receivedContexts).doesNotContainNull().doesNotHaveDuplicates();
List<String> receivedSpanIds = receivedContexts.stream().map(context -> Span.fromContextOrNull(context).getSpanContext().getSpanId()).collect(Collectors.toList());
assertThat(receivedSpanIds).doesNotContainNull().doesNotHaveDuplicates().hasSize(10);
List<String> receivedTraceIds = receivedContexts.stream().map(context -> Span.fromContextOrNull(context).getSpanContext().getTraceId()).collect(Collectors.toList());
assertThat(receivedTraceIds).doesNotContainNull().doesNotHaveDuplicates().hasSize(10);
assertThat(receivedTraceIds).containsExactlyInAnyOrderElementsOf(producedTraceIds);
assertThat(bean.tracing()).hasSizeGreaterThanOrEqualTo(10);
assertThat(bean.tracing()).doesNotContainNull().doesNotHaveDuplicates();
List<String> spanIds = new ArrayList<>();
for (TracingMetadata tracing : bean.tracing()) {
Span span = Span.fromContext(tracing.getCurrentContext());
spanIds.add(span.getSpanContext().getSpanId());
assertThat(Span.fromContextOrNull(tracing.getPreviousContext())).isNotNull();
}
await().atMost(Duration.ofMinutes(2)).until(() -> testExporter.getFinishedSpanItems().size() >= 10);
List<String> outgoingParentIds = new ArrayList<>();
List<String> incomingParentIds = new ArrayList<>();
for (SpanData data : testExporter.getFinishedSpanItems()) {
if (data.getKind().equals(SpanKind.CONSUMER)) {
incomingParentIds.add(data.getParentSpanId());
assertThat(data.getAttributes().get(SemanticAttributes.MESSAGING_KAFKA_CONSUMER_GROUP)).isNotNull();
assertThat(data.getAttributes().get(AttributeKey.stringKey("messaging.consumer_id"))).isNotNull();
// Need to skip the spans created during @Incoming processing
continue;
}
assertThat(data.getSpanId()).isIn(receivedSpanIds);
assertThat(data.getSpanId()).isNotEqualTo(data.getParentSpanId());
assertThat(data.getTraceId()).isIn(producedTraceIds);
assertThat(data.getKind()).isEqualByComparingTo(SpanKind.PRODUCER);
outgoingParentIds.add(data.getParentSpanId());
}
// Assert span created on Kafka record is the parent of consumer span we create
assertThat(producedSpanContexts.stream().map(SpanContext::getSpanId)).containsExactlyElementsOf(incomingParentIds);
// Assert consumer span is the parent of the producer span we received in Kafka
assertThat(spanIds.stream()).containsExactlyElementsOf(outgoingParentIds);
}
use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class TracingPropagationTest method testFromKafkaToAppWithNoParent.
@Test
public void testFromKafkaToAppWithNoParent() {
MyAppReceivingData bean = runApplication(getKafkaSinkConfigForMyAppReceivingData(topic), MyAppReceivingData.class);
companion.produceIntegers().usingGenerator(i -> new ProducerRecord<>(topic, null, null, "a-key", i), 10);
await().until(() -> bean.list().size() >= 10);
assertThat(bean.list()).containsExactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
assertThat(bean.tracing()).hasSizeGreaterThanOrEqualTo(10);
assertThat(bean.tracing()).doesNotContainNull().doesNotHaveDuplicates();
List<String> spanIds = new ArrayList<>();
for (TracingMetadata tracing : bean.tracing()) {
spanIds.add(Span.fromContext(tracing.getCurrentContext()).getSpanContext().getSpanId());
assertThat(Span.fromContextOrNull(tracing.getPreviousContext())).isNull();
}
assertThat(spanIds).doesNotContainNull().doesNotHaveDuplicates().hasSizeGreaterThanOrEqualTo(10);
for (SpanData data : testExporter.getFinishedSpanItems()) {
assertThat(data.getSpanId()).isIn(spanIds);
assertThat(data.getSpanId()).isNotEqualTo(data.getParentSpanId());
assertThat(data.getKind()).isEqualByComparingTo(SpanKind.CONSUMER);
}
}
use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class TracingPropagationTest method testFromKafkaToAppWithParentSpan.
@Test
public void testFromKafkaToAppWithParentSpan() {
String parentTopic = topic + "-parent";
String stuffTopic = topic + "-stuff";
MyAppReceivingData bean = runApplication(getKafkaSinkConfigForMyAppReceivingData(parentTopic), MyAppReceivingData.class);
List<SpanContext> producedSpanContexts = new CopyOnWriteArrayList<>();
companion.produceIntegers().usingGenerator(i -> new ProducerRecord<>(parentTopic, null, null, "a-key", i, createTracingSpan(producedSpanContexts, stuffTopic)), 10);
await().until(() -> bean.list().size() >= 10);
assertThat(bean.list()).containsExactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
List<String> producedTraceIds = producedSpanContexts.stream().map(SpanContext::getTraceId).collect(Collectors.toList());
assertThat(producedTraceIds).hasSize(10);
assertThat(bean.tracing()).hasSizeGreaterThanOrEqualTo(10);
assertThat(bean.tracing()).doesNotContainNull().doesNotHaveDuplicates();
List<String> receivedTraceIds = bean.tracing().stream().map(tracingMetadata -> Span.fromContext(tracingMetadata.getCurrentContext()).getSpanContext().getTraceId()).collect(Collectors.toList());
assertThat(receivedTraceIds).doesNotContainNull().doesNotHaveDuplicates().hasSize(10);
assertThat(receivedTraceIds).containsExactlyInAnyOrderElementsOf(producedTraceIds);
List<String> spanIds = new ArrayList<>();
for (TracingMetadata tracing : bean.tracing()) {
spanIds.add(Span.fromContext(tracing.getCurrentContext()).getSpanContext().getSpanId());
assertThat(tracing.getPreviousContext()).isNotNull();
Span previousSpan = Span.fromContextOrNull(tracing.getPreviousContext());
assertThat(previousSpan).isNotNull();
assertThat(previousSpan.getSpanContext().getTraceId()).isEqualTo(Span.fromContext(tracing.getCurrentContext()).getSpanContext().getTraceId());
assertThat(previousSpan.getSpanContext().getSpanId()).isNotEqualTo(Span.fromContext(tracing.getCurrentContext()).getSpanContext().getSpanId());
}
assertThat(spanIds).doesNotContainNull().doesNotHaveDuplicates().hasSizeGreaterThanOrEqualTo(10);
List<String> parentIds = bean.tracing().stream().map(tracingMetadata -> Span.fromContextOrNull(tracingMetadata.getPreviousContext()).getSpanContext().getSpanId()).collect(Collectors.toList());
assertThat(producedSpanContexts.stream().map(SpanContext::getSpanId)).containsExactlyElementsOf(parentIds);
for (SpanData data : testExporter.getFinishedSpanItems()) {
assertThat(data.getSpanId()).isIn(spanIds);
assertThat(data.getSpanId()).isNotEqualTo(data.getParentSpanId());
assertThat(data.getKind()).isEqualByComparingTo(SpanKind.CONSUMER);
assertThat(data.getParentSpanId()).isNotNull();
assertThat(data.getParentSpanId()).isIn(parentIds);
}
}
use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class TracingAmqpToAppToAmqpTest method testFromAmqpToAppToAmqp.
@Test
public void testFromAmqpToAppToAmqp() {
List<Integer> payloads = new CopyOnWriteArrayList<>();
List<Context> receivedContexts = new CopyOnWriteArrayList<>();
usage.consumeIntegersWithTracing("result-topic", payloads::add, receivedContexts::add);
weld.addBeanClass(MyAppProcessingData.class);
new MapBasedConfig().put("mp.messaging.outgoing.result-topic.connector", AmqpConnector.CONNECTOR_NAME).put("mp.messaging.outgoing.result-topic.durable", false).put("mp.messaging.outgoing.result-topic.host", host).put("mp.messaging.outgoing.result-topic.port", port).put("mp.messaging.incoming.parent-topic.connector", AmqpConnector.CONNECTOR_NAME).put("mp.messaging.incoming.parent-topic.host", host).put("mp.messaging.incoming.parent-topic.port", port).put("amqp-username", username).put("amqp-password", password).write();
container = weld.initialize();
MyAppProcessingData bean = container.getBeanManager().createInstance().select(MyAppProcessingData.class).get();
await().until(() -> isAmqpConnectorReady(container));
AtomicInteger count = new AtomicInteger();
List<SpanContext> producedSpanContexts = new CopyOnWriteArrayList<>();
usage.produce("parent-topic", 10, () -> AmqpMessage.create().durable(false).ttl(10000).withIntegerAsBody(count.getAndIncrement()).applicationProperties(createTracingSpan(producedSpanContexts, "parent-topic")).build());
await().atMost(Duration.ofMinutes(5)).until(() -> payloads.size() >= 10);
assertThat(payloads).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<String> producedTraceIds = producedSpanContexts.stream().map(SpanContext::getTraceId).collect(Collectors.toList());
assertThat(producedTraceIds).hasSize(10);
assertThat(receivedContexts).hasSize(10);
assertThat(receivedContexts).doesNotContainNull().doesNotHaveDuplicates();
List<String> receivedSpanIds = receivedContexts.stream().map(context -> Span.fromContextOrNull(context).getSpanContext().getSpanId()).collect(Collectors.toList());
assertThat(receivedSpanIds).doesNotContainNull().doesNotHaveDuplicates().hasSize(10);
List<String> receivedTraceIds = receivedContexts.stream().map(context -> Span.fromContextOrNull(context).getSpanContext().getTraceId()).collect(Collectors.toList());
assertThat(receivedTraceIds).doesNotContainNull().doesNotHaveDuplicates().hasSize(10);
assertThat(receivedTraceIds).containsExactlyInAnyOrderElementsOf(producedTraceIds);
List<String> receivedParentSpanIds = new ArrayList<>();
assertThat(bean.tracing()).hasSizeGreaterThanOrEqualTo(10);
assertThat(bean.tracing()).doesNotContainNull().doesNotHaveDuplicates();
List<String> spanIds = new ArrayList<>();
for (TracingMetadata tracing : bean.tracing()) {
Span span = Span.fromContext(tracing.getCurrentContext());
spanIds.add(span.getSpanContext().getSpanId());
assertThat(Span.fromContextOrNull(tracing.getPreviousContext())).isNotNull();
}
await().atMost(Duration.ofMinutes(2)).until(() -> testExporter.getFinishedSpanItems().size() >= 10);
List<String> outgoingParentIds = new ArrayList<>();
List<String> incomingParentIds = new ArrayList<>();
for (SpanData data : testExporter.getFinishedSpanItems()) {
if (data.getKind().equals(SpanKind.CONSUMER)) {
incomingParentIds.add(data.getParentSpanId());
// Need to skip the spans created during @Incoming processing
continue;
}
assertThat(data.getSpanId()).isIn(receivedSpanIds);
assertThat(data.getSpanId()).isNotEqualTo(data.getParentSpanId());
assertThat(data.getTraceId()).isIn(producedTraceIds);
assertThat(data.getKind()).isEqualByComparingTo(SpanKind.PRODUCER);
outgoingParentIds.add(data.getParentSpanId());
}
// Assert span created on AMQP record is the parent of consumer span we create
assertThat(producedSpanContexts.stream().map(SpanContext::getSpanId)).containsExactlyElementsOf(incomingParentIds);
// Assert consumer span is the parent of the producer span we received in AMQP
assertThat(spanIds.stream()).containsExactlyElementsOf(outgoingParentIds);
}
use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class AmqpCreditBasedSender method createOutgoingTrace.
private void createOutgoingTrace(Message<?> msg, io.vertx.mutiny.amqp.AmqpMessage amqp) {
if (tracingEnabled) {
Optional<TracingMetadata> tracingMetadata = TracingMetadata.fromMessage(msg);
final SpanBuilder spanBuilder = AmqpConnector.TRACER.spanBuilder(amqp.address() + " send").setSpanKind(SpanKind.PRODUCER);
if (tracingMetadata.isPresent()) {
// Handle possible parent span
final Context parentSpanContext = tracingMetadata.get().getCurrentContext();
if (parentSpanContext != null) {
spanBuilder.setParent(parentSpanContext);
} else {
spanBuilder.setNoParent();
}
} else {
spanBuilder.setNoParent();
}
final Span span = spanBuilder.startSpan();
Scope scope = span.makeCurrent();
// Set Span attributes
span.setAttribute(SemanticAttributes.MESSAGING_SYSTEM, "AMQP 1.0");
span.setAttribute(SemanticAttributes.MESSAGING_DESTINATION, amqp.address());
span.setAttribute(SemanticAttributes.MESSAGING_DESTINATION_KIND, "queue");
span.setAttribute(SemanticAttributes.MESSAGING_PROTOCOL, "AMQP");
span.setAttribute(SemanticAttributes.MESSAGING_PROTOCOL_VERSION, "1.0");
// Set span onto headers
GlobalOpenTelemetry.getPropagators().getTextMapPropagator().inject(Context.current(), amqp, HeaderInjectAdapter.SETTER);
span.end();
scope.close();
}
}
Aggregations