Convert aws sdk 2.2 Sqs Suppress Receive Spans Tests (#12895)
This commit is contained in:
parent
47ada968e8
commit
4f697dc7fe
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import io.opentelemetry.instrumentation.awssdk.v2_2.AbstractAws2SqsSuppressReceiveSpansTest
|
|
||||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
|
||||||
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsAsyncClient
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsClient
|
|
||||||
|
|
||||||
class Aws2SqsSuppressReceiveSpansTest extends AbstractAws2SqsSuppressReceiveSpansTest implements AgentTestTrait {
|
|
||||||
@Override
|
|
||||||
ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder() {
|
|
||||||
return ClientOverrideConfiguration.builder()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
SqsClient configureSqsClient(SqsClient sqsClient) {
|
|
||||||
return sqsClient
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
SqsAsyncClient configureSqsClient(SqsAsyncClient sqsClient) {
|
|
||||||
return sqsClient
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.awssdk.v2_2;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.awssdk.v2_2.AbstractAws2SqsSuppressReceiveSpansTest;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsAsyncClient;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsClient;
|
||||||
|
|
||||||
|
class Aws2SqsSuppressReceiveSpansTest extends AbstractAws2SqsSuppressReceiveSpansTest {
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InstrumentationExtension getTesting() {
|
||||||
|
return testing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SqsClient configureSqsClient(SqsClient sqsClient) {
|
||||||
|
return sqsClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SqsAsyncClient configureSqsClient(SqsAsyncClient sqsClient) {
|
||||||
|
return sqsClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder() {
|
||||||
|
return ClientOverrideConfiguration.builder();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.awssdk.v2_2
|
|
||||||
|
|
||||||
import io.opentelemetry.instrumentation.test.LibraryTestTrait
|
|
||||||
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsAsyncClient
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsClient
|
|
||||||
|
|
||||||
abstract class Aws2SqsSuppressReceiveSpansTest extends AbstractAws2SqsSuppressReceiveSpansTest implements LibraryTestTrait {
|
|
||||||
static AwsSdkTelemetry telemetry
|
|
||||||
|
|
||||||
def setupSpec() {
|
|
||||||
def telemetryBuilder = AwsSdkTelemetry.builder(getOpenTelemetry())
|
|
||||||
.setCaptureExperimentalSpanAttributes(true)
|
|
||||||
configure(telemetryBuilder)
|
|
||||||
telemetry = telemetryBuilder.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract void configure(AwsSdkTelemetryBuilder telemetryBuilder)
|
|
||||||
|
|
||||||
@Override
|
|
||||||
ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder() {
|
|
||||||
return ClientOverrideConfiguration.builder()
|
|
||||||
.addExecutionInterceptor(
|
|
||||||
telemetry.newExecutionInterceptor())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
SqsClient configureSqsClient(SqsClient sqsClient) {
|
|
||||||
return telemetry.wrap(sqsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
SqsAsyncClient configureSqsClient(SqsAsyncClient sqsClient) {
|
|
||||||
return telemetry.wrap(sqsClient)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Aws2SqsSuppressReceiveSpansDefaultPropagatorTest extends Aws2SqsSuppressReceiveSpansTest {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void configure(AwsSdkTelemetryBuilder telemetryBuilder) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean isSqsAttributeInjectionEnabled() {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
def "duplicate tracing interceptor"() {
|
|
||||||
setup:
|
|
||||||
def builder = SqsClient.builder()
|
|
||||||
configureSdkClient(builder)
|
|
||||||
def overrideConfiguration = ClientOverrideConfiguration.builder()
|
|
||||||
.addExecutionInterceptor(telemetry.newExecutionInterceptor())
|
|
||||||
.addExecutionInterceptor(telemetry.newExecutionInterceptor())
|
|
||||||
.build()
|
|
||||||
builder.overrideConfiguration(overrideConfiguration)
|
|
||||||
def client = configureSqsClient(builder.build())
|
|
||||||
|
|
||||||
client.createQueue(createQueueRequest)
|
|
||||||
|
|
||||||
when:
|
|
||||||
client.sendMessage(sendMessageRequest)
|
|
||||||
|
|
||||||
def resp = client.receiveMessage(receiveMessageRequest)
|
|
||||||
|
|
||||||
then:
|
|
||||||
resp.messages().size() == 1
|
|
||||||
resp.messages.each {message -> runWithSpan("process child") {}}
|
|
||||||
assertSqsTraces()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Aws2SqsSuppressReceiveSpansW3CPropagatorTest extends Aws2SqsSuppressReceiveSpansTest {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void configure(AwsSdkTelemetryBuilder telemetryBuilder) {
|
|
||||||
telemetryBuilder.setUseConfiguredPropagatorForMessaging(isSqsAttributeInjectionEnabled()) // Difference to main test
|
|
||||||
.setUseXrayPropagator(isXrayInjectionEnabled()) // Disable to confirm messaging propagator actually works
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean isSqsAttributeInjectionEnabled() {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean isXrayInjectionEnabled() {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** We want to test the combination of W3C + Xray, as that's what you'll get in prod if you enable W3C. */
|
|
||||||
class Aws2SqsSuppressReceiveSpansW3CPropagatorAndXrayPropagatorTest extends Aws2SqsSuppressReceiveSpansTest {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void configure(AwsSdkTelemetryBuilder telemetryBuilder) {
|
|
||||||
telemetryBuilder.setUseConfiguredPropagatorForMessaging(isSqsAttributeInjectionEnabled()) // Difference to main test
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean isSqsAttributeInjectionEnabled() {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,7 +20,7 @@ class Aws2SqsDefaultPropagatorTest extends Aws2SqsTracingTest {
|
||||||
void configure(AwsSdkTelemetryBuilder telemetryBuilder) {}
|
void configure(AwsSdkTelemetryBuilder telemetryBuilder) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isSqsAttributeInjectionEnabled() {
|
protected boolean isSqsAttributeInjectionEnabled() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.awssdk.v2_2;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsClient;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsClientBuilder;
|
||||||
|
import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
|
||||||
|
|
||||||
|
class Aws2SqsSuppressReceiveSpansDefaultPropagatorTest extends Aws2SqsSuppressReceiveSpansTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(AwsSdkTelemetryBuilder telemetryBuilder) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isSqsAttributeInjectionEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDuplicateTracingInterceptor() throws URISyntaxException {
|
||||||
|
SqsClientBuilder builder = SqsClient.builder();
|
||||||
|
configureSdkClient(builder);
|
||||||
|
ClientOverrideConfiguration overrideConfiguration =
|
||||||
|
ClientOverrideConfiguration.builder()
|
||||||
|
.addExecutionInterceptor(telemetry.newExecutionInterceptor())
|
||||||
|
.addExecutionInterceptor(telemetry.newExecutionInterceptor())
|
||||||
|
.build();
|
||||||
|
builder.overrideConfiguration(overrideConfiguration);
|
||||||
|
SqsClient client = configureSqsClient(builder.build());
|
||||||
|
|
||||||
|
client.createQueue(createQueueRequest);
|
||||||
|
client.sendMessage(sendMessageRequest);
|
||||||
|
ReceiveMessageResponse response = client.receiveMessage(receiveMessageRequest);
|
||||||
|
|
||||||
|
assertThat(response.messages().size()).isEqualTo(1);
|
||||||
|
response.messages().forEach(message -> getTesting().runWithSpan("process child", () -> {}));
|
||||||
|
|
||||||
|
assertSqsTraces(false, false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.awssdk.v2_2;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsAsyncClient;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsClient;
|
||||||
|
|
||||||
|
public abstract class Aws2SqsSuppressReceiveSpansTest
|
||||||
|
extends AbstractAws2SqsSuppressReceiveSpansTest {
|
||||||
|
protected AwsSdkTelemetry telemetry;
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InstrumentationExtension getTesting() {
|
||||||
|
return testing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SqsClient configureSqsClient(SqsClient sqsClient) {
|
||||||
|
return telemetry.wrap(sqsClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SqsAsyncClient configureSqsClient(SqsAsyncClient sqsClient) {
|
||||||
|
return telemetry.wrap(sqsClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder() {
|
||||||
|
return ClientOverrideConfiguration.builder()
|
||||||
|
.addExecutionInterceptor(telemetry.newExecutionInterceptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void configure(AwsSdkTelemetryBuilder telemetryBuilder);
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
AwsSdkTelemetryBuilder telemetryBuilder =
|
||||||
|
AwsSdkTelemetry.builder(getTesting().getOpenTelemetry())
|
||||||
|
.setCaptureExperimentalSpanAttributes(true);
|
||||||
|
configure(telemetryBuilder);
|
||||||
|
telemetry = telemetryBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.awssdk.v2_2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We want to test the combination of W3C + Xray, as that's what you'll get in prod if you enable
|
||||||
|
* W3C.
|
||||||
|
*/
|
||||||
|
class Aws2SqsSuppressReceiveSpansW3cPropagatorAndXrayPropagatorTest
|
||||||
|
extends Aws2SqsSuppressReceiveSpansTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(AwsSdkTelemetryBuilder telemetryBuilder) {
|
||||||
|
telemetryBuilder.setUseConfiguredPropagatorForMessaging(
|
||||||
|
isSqsAttributeInjectionEnabled()); // Difference to main test
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isSqsAttributeInjectionEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.awssdk.v2_2;
|
||||||
|
|
||||||
|
class Aws2SqsSuppressReceiveSpansW3cPropagatorTest extends Aws2SqsSuppressReceiveSpansTest {
|
||||||
|
@Override
|
||||||
|
protected void configure(AwsSdkTelemetryBuilder telemetryBuilder) {
|
||||||
|
telemetryBuilder
|
||||||
|
.setUseConfiguredPropagatorForMessaging(
|
||||||
|
isSqsAttributeInjectionEnabled()) // Difference to main test
|
||||||
|
.setUseXrayPropagator(
|
||||||
|
isXrayInjectionEnabled()); // Disable to confirm messaging propagator actually works
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isSqsAttributeInjectionEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isXrayInjectionEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ class Aws2SqsW3cPropagatorAndXrayPropagatorTest extends Aws2SqsTracingTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isSqsAttributeInjectionEnabled() {
|
protected boolean isSqsAttributeInjectionEnabled() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@ class Aws2SqsW3cPropagatorTest extends Aws2SqsTracingTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isSqsAttributeInjectionEnabled() {
|
protected boolean isSqsAttributeInjectionEnabled() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isXrayInjectionEnabled() {
|
protected boolean isXrayInjectionEnabled() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,393 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.awssdk.v2_2
|
|
||||||
|
|
||||||
import io.opentelemetry.instrumentation.test.InstrumentationSpecification
|
|
||||||
import io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes
|
|
||||||
import io.opentelemetry.semconv.incubating.AwsIncubatingAttributes
|
|
||||||
import io.opentelemetry.semconv.ServerAttributes
|
|
||||||
import io.opentelemetry.semconv.HttpAttributes
|
|
||||||
import io.opentelemetry.semconv.UrlAttributes
|
|
||||||
import org.elasticmq.rest.sqs.SQSRestServerBuilder
|
|
||||||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
|
|
||||||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
|
|
||||||
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration
|
|
||||||
import software.amazon.awssdk.regions.Region
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsAsyncClient
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsBaseClientBuilder
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsClient
|
|
||||||
import software.amazon.awssdk.services.sqs.model.CreateQueueRequest
|
|
||||||
import software.amazon.awssdk.services.sqs.model.MessageAttributeValue
|
|
||||||
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest
|
|
||||||
import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequest
|
|
||||||
import software.amazon.awssdk.services.sqs.model.SendMessageRequest
|
|
||||||
import spock.lang.Shared
|
|
||||||
|
|
||||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
|
||||||
import static io.opentelemetry.api.trace.SpanKind.CONSUMER
|
|
||||||
import static io.opentelemetry.api.trace.SpanKind.PRODUCER
|
|
||||||
|
|
||||||
abstract class AbstractAws2SqsSuppressReceiveSpansTest extends InstrumentationSpecification {
|
|
||||||
|
|
||||||
private static final StaticCredentialsProvider CREDENTIALS_PROVIDER = StaticCredentialsProvider
|
|
||||||
.create(AwsBasicCredentials.create("my-access-key", "my-secret-key"))
|
|
||||||
|
|
||||||
@Shared
|
|
||||||
def sqs
|
|
||||||
|
|
||||||
@Shared
|
|
||||||
int sqsPort
|
|
||||||
|
|
||||||
static Map<String, MessageAttributeValue> dummyMessageAttributes(count) {
|
|
||||||
(0..<count).collectEntries {
|
|
||||||
[
|
|
||||||
"a$it".toString(),
|
|
||||||
MessageAttributeValue.builder().stringValue("v$it").dataType("String").build()]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String queueUrl = "http://localhost:$sqsPort/000000000000/testSdkSqs"
|
|
||||||
|
|
||||||
ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder()
|
|
||||||
.queueUrl(queueUrl)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
ReceiveMessageRequest receiveMessageBatchRequest = ReceiveMessageRequest.builder()
|
|
||||||
.queueUrl(queueUrl)
|
|
||||||
.maxNumberOfMessages(3)
|
|
||||||
.messageAttributeNames("All")
|
|
||||||
.waitTimeSeconds(5)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
CreateQueueRequest createQueueRequest = CreateQueueRequest.builder()
|
|
||||||
.queueName("testSdkSqs")
|
|
||||||
.build()
|
|
||||||
|
|
||||||
SendMessageRequest sendMessageRequest = SendMessageRequest.builder()
|
|
||||||
.queueUrl(queueUrl)
|
|
||||||
.messageBody("{\"type\": \"hello\"}")
|
|
||||||
.build()
|
|
||||||
|
|
||||||
SendMessageBatchRequest sendMessageBatchRequest = SendMessageBatchRequest.builder()
|
|
||||||
.queueUrl(queueUrl)
|
|
||||||
.entries(
|
|
||||||
e -> e.messageBody("e1").id("i1"),
|
|
||||||
// 8 attributes, injection always possible
|
|
||||||
e -> e.messageBody("e2").id("i2")
|
|
||||||
.messageAttributes(dummyMessageAttributes(8)),
|
|
||||||
// 10 attributes, injection with custom propagator never possible
|
|
||||||
e -> e.messageBody("e3").id("i3").messageAttributes(dummyMessageAttributes(10)))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
boolean isSqsAttributeInjectionEnabled() {
|
|
||||||
AbstractAws2ClientCoreTest.isSqsAttributeInjectionEnabled()
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isXrayInjectionEnabled() {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
void configureSdkClient(SqsBaseClientBuilder builder) {
|
|
||||||
builder
|
|
||||||
.overrideConfiguration(createOverrideConfigurationBuilder().build())
|
|
||||||
.endpointOverride(new URI("http://localhost:" + sqsPort))
|
|
||||||
builder
|
|
||||||
.region(Region.AP_NORTHEAST_1)
|
|
||||||
.credentialsProvider(CREDENTIALS_PROVIDER)
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract SqsClient configureSqsClient(SqsClient sqsClient)
|
|
||||||
|
|
||||||
abstract SqsAsyncClient configureSqsClient(SqsAsyncClient sqsClient)
|
|
||||||
|
|
||||||
abstract ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder()
|
|
||||||
|
|
||||||
def setupSpec() {
|
|
||||||
sqs = SQSRestServerBuilder.withPort(0).withInterface("localhost").start()
|
|
||||||
def server = sqs.waitUntilStarted()
|
|
||||||
sqsPort = server.localAddress().port
|
|
||||||
println getClass().name + " SQS server started at: localhost:$sqsPort/"
|
|
||||||
}
|
|
||||||
|
|
||||||
def cleanupSpec() {
|
|
||||||
if (sqs != null) {
|
|
||||||
sqs.stopAndWait()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void assertSqsTraces(withParent = false) {
|
|
||||||
assertTraces(2 + (withParent ? 1 : 0)) {
|
|
||||||
trace(0, 1) {
|
|
||||||
|
|
||||||
span(0) {
|
|
||||||
name "Sqs.CreateQueue"
|
|
||||||
kind CLIENT
|
|
||||||
hasNoParent()
|
|
||||||
attributes {
|
|
||||||
"aws.agent" "java-aws-sdk"
|
|
||||||
"aws.queue.name" "testSdkSqs"
|
|
||||||
"$AwsIncubatingAttributes.AWS_REQUEST_ID" { it == "00000000-0000-0000-0000-000000000000" || it == "UNKNOWN" }
|
|
||||||
"rpc.system" "aws-api"
|
|
||||||
"rpc.service" "Sqs"
|
|
||||||
"rpc.method" "CreateQueue"
|
|
||||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "POST"
|
|
||||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
|
||||||
"$UrlAttributes.URL_FULL" { it.startsWith("http://localhost:$sqsPort") }
|
|
||||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
|
||||||
"$ServerAttributes.SERVER_PORT" sqsPort
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trace(1, 3) {
|
|
||||||
span(0) {
|
|
||||||
name "testSdkSqs publish"
|
|
||||||
kind PRODUCER
|
|
||||||
hasNoParent()
|
|
||||||
attributes {
|
|
||||||
"aws.agent" "java-aws-sdk"
|
|
||||||
"aws.queue.url" "http://localhost:$sqsPort/000000000000/testSdkSqs"
|
|
||||||
"$AwsIncubatingAttributes.AWS_REQUEST_ID" { it == "00000000-0000-0000-0000-000000000000" || it == "UNKNOWN" }
|
|
||||||
"rpc.system" "aws-api"
|
|
||||||
"rpc.method" "SendMessage"
|
|
||||||
"rpc.service" "Sqs"
|
|
||||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "POST"
|
|
||||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
|
||||||
"$UrlAttributes.URL_FULL" { it.startsWith("http://localhost:$sqsPort") }
|
|
||||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
|
||||||
"$ServerAttributes.SERVER_PORT" sqsPort
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_SYSTEM" MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME" "testSdkSqs"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_OPERATION" "publish"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID" String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
name "testSdkSqs process"
|
|
||||||
kind CONSUMER
|
|
||||||
childOf span(0)
|
|
||||||
hasNoLinks()
|
|
||||||
attributes {
|
|
||||||
"aws.agent" "java-aws-sdk"
|
|
||||||
"rpc.method" "ReceiveMessage"
|
|
||||||
"rpc.system" "aws-api"
|
|
||||||
"rpc.service" "Sqs"
|
|
||||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "POST"
|
|
||||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
|
||||||
"$UrlAttributes.URL_FULL" { it.startsWith("http://localhost:$sqsPort") }
|
|
||||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
|
||||||
"$ServerAttributes.SERVER_PORT" sqsPort
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_SYSTEM" MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME" "testSdkSqs"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_OPERATION" "process"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID" String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span(2) {
|
|
||||||
name "process child"
|
|
||||||
childOf span(1)
|
|
||||||
attributes {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (withParent) {
|
|
||||||
/**
|
|
||||||
* This span represents HTTP "sending of receive message" operation. It's always single, while there can be multiple CONSUMER spans (one per consumed message).
|
|
||||||
* This one could be suppressed (by IF in TracingRequestHandler#beforeRequest but then HTTP instrumentation span would appear
|
|
||||||
*/
|
|
||||||
trace(2, 2) {
|
|
||||||
span(0) {
|
|
||||||
name "parent"
|
|
||||||
hasNoParent()
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
name "Sqs.ReceiveMessage"
|
|
||||||
kind CLIENT
|
|
||||||
childOf span(0)
|
|
||||||
hasNoLinks()
|
|
||||||
attributes {
|
|
||||||
"aws.agent" "java-aws-sdk"
|
|
||||||
"$AwsIncubatingAttributes.AWS_REQUEST_ID" { it == "00000000-0000-0000-0000-000000000000" || it == "UNKNOWN" }
|
|
||||||
"rpc.method" "ReceiveMessage"
|
|
||||||
"aws.queue.url" "http://localhost:$sqsPort/000000000000/testSdkSqs"
|
|
||||||
"rpc.system" "aws-api"
|
|
||||||
"rpc.service" "Sqs"
|
|
||||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "POST"
|
|
||||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
|
||||||
"$UrlAttributes.URL_FULL" { it.startsWith("http://localhost:$sqsPort") }
|
|
||||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
|
||||||
"$ServerAttributes.SERVER_PORT" sqsPort
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "simple sqs producer-consumer services: sync"() {
|
|
||||||
setup:
|
|
||||||
def builder = SqsClient.builder()
|
|
||||||
configureSdkClient(builder)
|
|
||||||
def client = configureSqsClient(builder.build())
|
|
||||||
|
|
||||||
client.createQueue(createQueueRequest)
|
|
||||||
|
|
||||||
when:
|
|
||||||
client.sendMessage(sendMessageRequest)
|
|
||||||
|
|
||||||
def resp = client.receiveMessage(receiveMessageRequest)
|
|
||||||
|
|
||||||
then:
|
|
||||||
resp.messages.size() == 1
|
|
||||||
resp.messages.each {message -> runWithSpan("process child") {}}
|
|
||||||
assertSqsTraces()
|
|
||||||
}
|
|
||||||
|
|
||||||
def "simple sqs producer-consumer services with parent: sync"() {
|
|
||||||
setup:
|
|
||||||
def builder = SqsClient.builder()
|
|
||||||
configureSdkClient(builder)
|
|
||||||
def client = configureSqsClient(builder.build())
|
|
||||||
|
|
||||||
client.createQueue(createQueueRequest)
|
|
||||||
|
|
||||||
when:
|
|
||||||
client.sendMessage(sendMessageRequest)
|
|
||||||
|
|
||||||
def resp = runWithSpan("parent") {
|
|
||||||
client.receiveMessage(receiveMessageRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
then:
|
|
||||||
resp.messages.size() == 1
|
|
||||||
resp.messages.each {message -> runWithSpan("process child") {}}
|
|
||||||
assertSqsTraces(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def "simple sqs producer-consumer services: async"() {
|
|
||||||
setup:
|
|
||||||
def builder = SqsAsyncClient.builder()
|
|
||||||
configureSdkClient(builder)
|
|
||||||
def client = configureSqsClient(builder.build())
|
|
||||||
|
|
||||||
client.createQueue(createQueueRequest).get()
|
|
||||||
|
|
||||||
when:
|
|
||||||
client.sendMessage(sendMessageRequest).get()
|
|
||||||
|
|
||||||
def resp = client.receiveMessage(receiveMessageRequest).get()
|
|
||||||
|
|
||||||
then:
|
|
||||||
resp.messages.size() == 1
|
|
||||||
resp.messages.each {message -> runWithSpan("process child") {}}
|
|
||||||
assertSqsTraces()
|
|
||||||
}
|
|
||||||
|
|
||||||
def "batch sqs producer-consumer services: sync"() {
|
|
||||||
setup:
|
|
||||||
def builder = SqsClient.builder()
|
|
||||||
configureSdkClient(builder)
|
|
||||||
def client = configureSqsClient(builder.build())
|
|
||||||
|
|
||||||
client.createQueue(createQueueRequest)
|
|
||||||
|
|
||||||
when:
|
|
||||||
client.sendMessageBatch(sendMessageBatchRequest)
|
|
||||||
|
|
||||||
def resp = client.receiveMessage(receiveMessageBatchRequest)
|
|
||||||
def totalAttrs = resp.messages().sum {it.messageAttributes().size() }
|
|
||||||
|
|
||||||
then:
|
|
||||||
resp.messages().size() == 3
|
|
||||||
|
|
||||||
// +2: 3 messages, 2x traceparent, 1x not injected due to too many attrs
|
|
||||||
totalAttrs == 18 + (sqsAttributeInjectionEnabled ? 2 : 0)
|
|
||||||
|
|
||||||
assertTraces(xrayInjectionEnabled ? 2 : 3) {
|
|
||||||
trace(0, 1) {
|
|
||||||
|
|
||||||
span(0) {
|
|
||||||
name "Sqs.CreateQueue"
|
|
||||||
kind CLIENT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trace(1, xrayInjectionEnabled ? 4 : 3) {
|
|
||||||
span(0) {
|
|
||||||
name "testSdkSqs publish"
|
|
||||||
kind PRODUCER
|
|
||||||
hasNoParent()
|
|
||||||
attributes {
|
|
||||||
"aws.agent" "java-aws-sdk"
|
|
||||||
"aws.queue.url" "http://localhost:$sqsPort/000000000000/testSdkSqs"
|
|
||||||
"$AwsIncubatingAttributes.AWS_REQUEST_ID" { it.trim() == "00000000-0000-0000-0000-000000000000" || it == "UNKNOWN" }
|
|
||||||
"rpc.system" "aws-api"
|
|
||||||
"rpc.method" "SendMessageBatch"
|
|
||||||
"rpc.service" "Sqs"
|
|
||||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "POST"
|
|
||||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
|
||||||
"$UrlAttributes.URL_FULL" { it.startsWith("http://localhost:$sqsPort") }
|
|
||||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
|
||||||
"$ServerAttributes.SERVER_PORT" sqsPort
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_SYSTEM" MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME" "testSdkSqs"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_OPERATION" "publish"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i: 1..(xrayInjectionEnabled ? 3 : 2)) {
|
|
||||||
span(i) {
|
|
||||||
name "testSdkSqs process"
|
|
||||||
kind CONSUMER
|
|
||||||
childOf span(0)
|
|
||||||
hasNoLinks()
|
|
||||||
|
|
||||||
attributes {
|
|
||||||
"aws.agent" "java-aws-sdk"
|
|
||||||
"rpc.method" "ReceiveMessage"
|
|
||||||
"rpc.system" "aws-api"
|
|
||||||
"rpc.service" "Sqs"
|
|
||||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "POST"
|
|
||||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
|
||||||
"$UrlAttributes.URL_FULL" { it.startsWith("http://localhost:$sqsPort") }
|
|
||||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
|
||||||
"$ServerAttributes.SERVER_PORT" sqsPort
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_SYSTEM" MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME" "testSdkSqs"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_OPERATION" "process"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID" String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!xrayInjectionEnabled) {
|
|
||||||
trace(2, 1) {
|
|
||||||
span(0) {
|
|
||||||
name "testSdkSqs process"
|
|
||||||
kind CONSUMER
|
|
||||||
|
|
||||||
// TODO This is not nice at all, and can also happen if producer is not instrumented
|
|
||||||
hasNoParent()
|
|
||||||
hasNoLinks()
|
|
||||||
|
|
||||||
attributes {
|
|
||||||
"aws.agent" "java-aws-sdk"
|
|
||||||
"rpc.method" "ReceiveMessage"
|
|
||||||
"rpc.system" "aws-api"
|
|
||||||
"rpc.service" "Sqs"
|
|
||||||
"$HttpAttributes.HTTP_REQUEST_METHOD" "POST"
|
|
||||||
"$HttpAttributes.HTTP_RESPONSE_STATUS_CODE" 200
|
|
||||||
"$UrlAttributes.URL_FULL" { it.startsWith("http://localhost:$sqsPort") }
|
|
||||||
"$ServerAttributes.SERVER_ADDRESS" "localhost"
|
|
||||||
"$ServerAttributes.SERVER_PORT" sqsPort
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_SYSTEM" MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME" "testSdkSqs"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_OPERATION" "process"
|
|
||||||
"$MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID" String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.awssdk.v2_2;
|
||||||
|
|
||||||
|
import static io.opentelemetry.api.common.AttributeKey.stringKey;
|
||||||
|
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||||
|
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||||
|
import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD;
|
||||||
|
import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE;
|
||||||
|
import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS;
|
||||||
|
import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT;
|
||||||
|
import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
|
||||||
|
import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_REQUEST_ID;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_OPERATION;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_SYSTEM;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS;
|
||||||
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD;
|
||||||
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE;
|
||||||
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
|
||||||
|
import io.opentelemetry.sdk.trace.data.SpanData;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.pekko.http.scaladsl.Http;
|
||||||
|
import org.elasticmq.rest.sqs.SQSRestServer;
|
||||||
|
import org.elasticmq.rest.sqs.SQSRestServerBuilder;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
||||||
|
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
||||||
|
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
|
||||||
|
import software.amazon.awssdk.regions.Region;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsAsyncClient;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsAsyncClientBuilder;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsClient;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsClientBuilder;
|
||||||
|
import software.amazon.awssdk.services.sqs.model.CreateQueueRequest;
|
||||||
|
import software.amazon.awssdk.services.sqs.model.MessageAttributeValue;
|
||||||
|
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
|
||||||
|
import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
|
||||||
|
import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequest;
|
||||||
|
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;
|
||||||
|
|
||||||
|
public abstract class AbstractAws2SqsBaseTest {
|
||||||
|
protected static final StaticCredentialsProvider CREDENTIALS_PROVIDER =
|
||||||
|
StaticCredentialsProvider.create(
|
||||||
|
AwsBasicCredentials.create("my-access-key", "my-secret-key"));
|
||||||
|
protected static int sqsPort;
|
||||||
|
protected static SQSRestServer sqs;
|
||||||
|
protected final String queueUrl = "http://localhost:" + sqsPort + "/000000000000/testSdkSqs";
|
||||||
|
|
||||||
|
protected ReceiveMessageRequest receiveMessageRequest =
|
||||||
|
ReceiveMessageRequest.builder().queueUrl(queueUrl).build();
|
||||||
|
|
||||||
|
protected ReceiveMessageRequest receiveMessageBatchRequest =
|
||||||
|
ReceiveMessageRequest.builder()
|
||||||
|
.queueUrl(queueUrl)
|
||||||
|
.maxNumberOfMessages(3)
|
||||||
|
.messageAttributeNames("All")
|
||||||
|
.waitTimeSeconds(5)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
protected CreateQueueRequest createQueueRequest =
|
||||||
|
CreateQueueRequest.builder().queueName("testSdkSqs").build();
|
||||||
|
|
||||||
|
protected SendMessageRequest sendMessageRequest =
|
||||||
|
SendMessageRequest.builder().queueUrl(queueUrl).messageBody("{\"type\": \"hello\"}").build();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected SendMessageBatchRequest sendMessageBatchRequest =
|
||||||
|
SendMessageBatchRequest.builder()
|
||||||
|
.queueUrl(queueUrl)
|
||||||
|
.entries(
|
||||||
|
e -> e.messageBody("e1").id("i1"),
|
||||||
|
// 8 attributes, injection always possible
|
||||||
|
e -> e.messageBody("e2").id("i2").messageAttributes(dummyMessageAttributes(8)),
|
||||||
|
// 10 attributes, injection with custom propagator never possible
|
||||||
|
e -> e.messageBody("e3").id("i3").messageAttributes(dummyMessageAttributes(10)))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
protected abstract InstrumentationExtension getTesting();
|
||||||
|
|
||||||
|
protected abstract SqsClient configureSqsClient(SqsClient sqsClient);
|
||||||
|
|
||||||
|
protected abstract SqsAsyncClient configureSqsClient(SqsAsyncClient sqsClient);
|
||||||
|
|
||||||
|
protected abstract ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder();
|
||||||
|
|
||||||
|
protected abstract void assertSqsTraces(boolean withParent, boolean captureHeaders);
|
||||||
|
|
||||||
|
static Map<String, MessageAttributeValue> dummyMessageAttributes(int count) {
|
||||||
|
Map<String, MessageAttributeValue> map = new HashMap<>();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
map.put(
|
||||||
|
"a" + i, MessageAttributeValue.builder().stringValue("v" + i).dataType("String").build());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isXrayInjectionEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void configureSdkClient(SqsClientBuilder builder) throws URISyntaxException {
|
||||||
|
builder
|
||||||
|
.overrideConfiguration(createOverrideConfigurationBuilder().build())
|
||||||
|
.endpointOverride(new URI("http://localhost:" + sqsPort));
|
||||||
|
builder.region(Region.AP_NORTHEAST_1).credentialsProvider(CREDENTIALS_PROVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void configureSdkClient(SqsAsyncClientBuilder builder) throws URISyntaxException {
|
||||||
|
builder
|
||||||
|
.overrideConfiguration(createOverrideConfigurationBuilder().build())
|
||||||
|
.endpointOverride(new URI("http://localhost:" + sqsPort));
|
||||||
|
builder.region(Region.AP_NORTHEAST_1).credentialsProvider(CREDENTIALS_PROVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isSqsAttributeInjectionEnabled() {
|
||||||
|
// See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor
|
||||||
|
return ConfigPropertiesUtil.getBoolean(
|
||||||
|
"otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void setUp() {
|
||||||
|
sqs = SQSRestServerBuilder.withPort(0).withInterface("localhost").start();
|
||||||
|
Http.ServerBinding server = sqs.waitUntilStarted();
|
||||||
|
sqsPort = server.localAddress().getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void cleanUp() {
|
||||||
|
if (sqs != null) {
|
||||||
|
sqs.stopAndWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSimpleSqsProducerConsumerServicesSync() throws URISyntaxException {
|
||||||
|
SqsClientBuilder builder = SqsClient.builder();
|
||||||
|
configureSdkClient(builder);
|
||||||
|
SqsClient client = configureSqsClient(builder.build());
|
||||||
|
|
||||||
|
client.createQueue(createQueueRequest);
|
||||||
|
client.sendMessage(sendMessageRequest);
|
||||||
|
|
||||||
|
ReceiveMessageResponse response = client.receiveMessage(receiveMessageRequest);
|
||||||
|
|
||||||
|
assertThat(response.messages().size()).isEqualTo(1);
|
||||||
|
|
||||||
|
response.messages().forEach(message -> getTesting().runWithSpan("process child", () -> {}));
|
||||||
|
assertSqsTraces(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSimpleSqsProducerConsumerServicesWithParentSync() throws URISyntaxException {
|
||||||
|
SqsClientBuilder builder = SqsClient.builder();
|
||||||
|
configureSdkClient(builder);
|
||||||
|
SqsClient client = configureSqsClient(builder.build());
|
||||||
|
|
||||||
|
client.createQueue(createQueueRequest);
|
||||||
|
client.sendMessage(sendMessageRequest);
|
||||||
|
|
||||||
|
ReceiveMessageResponse response =
|
||||||
|
getTesting().runWithSpan("parent", () -> client.receiveMessage(receiveMessageRequest));
|
||||||
|
|
||||||
|
assertThat(response.messages().size()).isEqualTo(1);
|
||||||
|
|
||||||
|
response.messages().forEach(message -> getTesting().runWithSpan("process child", () -> {}));
|
||||||
|
assertSqsTraces(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("InterruptedExceptionSwallowed")
|
||||||
|
@Test
|
||||||
|
void testSimpleSqsProducerConsumerServicesAsync() throws Exception {
|
||||||
|
SqsAsyncClientBuilder builder = SqsAsyncClient.builder();
|
||||||
|
configureSdkClient(builder);
|
||||||
|
SqsAsyncClient client = configureSqsClient(builder.build());
|
||||||
|
|
||||||
|
client.createQueue(createQueueRequest).get();
|
||||||
|
client.sendMessage(sendMessageRequest).get();
|
||||||
|
|
||||||
|
ReceiveMessageResponse response = client.receiveMessage(receiveMessageRequest).get();
|
||||||
|
|
||||||
|
assertThat(response.messages().size()).isEqualTo(1);
|
||||||
|
|
||||||
|
response.messages().forEach(message -> getTesting().runWithSpan("process child", () -> {}));
|
||||||
|
assertSqsTraces(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SpanDataAssert createQueueSpan(SpanDataAssert span) {
|
||||||
|
return span.hasName("Sqs.CreateQueue")
|
||||||
|
.hasKind(SpanKind.CLIENT)
|
||||||
|
.hasNoParent()
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
|
||||||
|
equalTo(stringKey("aws.queue.name"), "testSdkSqs"),
|
||||||
|
satisfies(
|
||||||
|
AWS_REQUEST_ID,
|
||||||
|
val -> val.matches("\\s*00000000-0000-0000-0000-000000000000\\s*|UNKNOWN")),
|
||||||
|
equalTo(RPC_SYSTEM, "aws-api"),
|
||||||
|
equalTo(RPC_SERVICE, "Sqs"),
|
||||||
|
equalTo(RPC_METHOD, "CreateQueue"),
|
||||||
|
equalTo(HTTP_REQUEST_METHOD, "POST"),
|
||||||
|
equalTo(HTTP_RESPONSE_STATUS_CODE, 200),
|
||||||
|
satisfies(URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
|
equalTo(SERVER_PORT, sqsPort));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // using deprecated semconv
|
||||||
|
static SpanDataAssert processSpan(SpanDataAssert span, SpanData parent) {
|
||||||
|
return span.hasName("testSdkSqs process")
|
||||||
|
.hasKind(SpanKind.CONSUMER)
|
||||||
|
.hasParent(parent)
|
||||||
|
.hasTotalRecordedLinks(0)
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
|
||||||
|
equalTo(RPC_SYSTEM, "aws-api"),
|
||||||
|
equalTo(RPC_SERVICE, "Sqs"),
|
||||||
|
equalTo(RPC_METHOD, "ReceiveMessage"),
|
||||||
|
equalTo(HTTP_REQUEST_METHOD, "POST"),
|
||||||
|
equalTo(HTTP_RESPONSE_STATUS_CODE, 200),
|
||||||
|
satisfies(URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
|
equalTo(SERVER_PORT, sqsPort),
|
||||||
|
equalTo(MESSAGING_SYSTEM, AWS_SQS),
|
||||||
|
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
||||||
|
equalTo(MESSAGING_OPERATION, "process"),
|
||||||
|
satisfies(MESSAGING_MESSAGE_ID, v -> v.isInstanceOf(String.class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // using deprecated semconv
|
||||||
|
static SpanDataAssert publishSpan(SpanDataAssert span, String queueUrl, String rcpMethod) {
|
||||||
|
return span.hasName("testSdkSqs publish")
|
||||||
|
.hasKind(SpanKind.PRODUCER)
|
||||||
|
.hasNoParent()
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
|
||||||
|
equalTo(stringKey("aws.queue.url"), queueUrl),
|
||||||
|
satisfies(
|
||||||
|
AWS_REQUEST_ID,
|
||||||
|
val -> val.matches("\\s*00000000-0000-0000-0000-000000000000\\s*|UNKNOWN")),
|
||||||
|
equalTo(RPC_SYSTEM, "aws-api"),
|
||||||
|
equalTo(RPC_SERVICE, "Sqs"),
|
||||||
|
equalTo(RPC_METHOD, rcpMethod),
|
||||||
|
equalTo(HTTP_REQUEST_METHOD, "POST"),
|
||||||
|
equalTo(HTTP_RESPONSE_STATUS_CODE, 200),
|
||||||
|
satisfies(URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
|
equalTo(SERVER_PORT, sqsPort),
|
||||||
|
equalTo(MESSAGING_SYSTEM, AWS_SQS),
|
||||||
|
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
||||||
|
equalTo(MESSAGING_OPERATION, "publish"),
|
||||||
|
satisfies(
|
||||||
|
MESSAGING_MESSAGE_ID,
|
||||||
|
val ->
|
||||||
|
val.satisfiesAnyOf(
|
||||||
|
v -> assertThat(v).isInstanceOf(String.class),
|
||||||
|
v -> assertThat(v).isNull())));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.instrumentation.awssdk.v2_2;
|
||||||
|
|
||||||
|
import static io.opentelemetry.api.common.AttributeKey.stringKey;
|
||||||
|
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||||
|
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||||
|
import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD;
|
||||||
|
import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE;
|
||||||
|
import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS;
|
||||||
|
import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT;
|
||||||
|
import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
|
||||||
|
import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_REQUEST_ID;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_OPERATION;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_SYSTEM;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS;
|
||||||
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD;
|
||||||
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE;
|
||||||
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import io.opentelemetry.api.common.Attributes;
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
|
||||||
|
import io.opentelemetry.sdk.testing.assertj.TraceAssert;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsClient;
|
||||||
|
import software.amazon.awssdk.services.sqs.SqsClientBuilder;
|
||||||
|
import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
|
||||||
|
|
||||||
|
public abstract class AbstractAws2SqsSuppressReceiveSpansTest extends AbstractAws2SqsBaseTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assertSqsTraces(boolean withParent, boolean captureHeaders) {
|
||||||
|
List<Consumer<TraceAssert>> traceAsserts =
|
||||||
|
new ArrayList<>(
|
||||||
|
Arrays.asList(
|
||||||
|
trace -> trace.hasSpansSatisfyingExactly(span -> createQueueSpan(span)),
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> publishSpan(span, queueUrl, "SendMessage"),
|
||||||
|
span -> processSpan(span, trace.getSpan(0)),
|
||||||
|
span ->
|
||||||
|
span.hasName("process child")
|
||||||
|
.hasParent(trace.getSpan(1))
|
||||||
|
.hasAttributes(Attributes.empty()))));
|
||||||
|
|
||||||
|
if (withParent) {
|
||||||
|
/*
|
||||||
|
* This span represents HTTP "sending of receive message" operation. It's always single,
|
||||||
|
* while there can be multiple CONSUMER spans (one per consumed message).
|
||||||
|
* This one could be suppressed (by IF in TracingRequestHandler#beforeRequest but then
|
||||||
|
* HTTP instrumentation span would appear)
|
||||||
|
*/
|
||||||
|
traceAsserts.add(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("parent").hasNoParent(),
|
||||||
|
span ->
|
||||||
|
span.hasName("Sqs.ReceiveMessage")
|
||||||
|
.hasKind(SpanKind.CLIENT)
|
||||||
|
.hasTotalRecordedLinks(0)
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
|
||||||
|
equalTo(stringKey("aws.queue.url"), queueUrl),
|
||||||
|
satisfies(
|
||||||
|
AWS_REQUEST_ID,
|
||||||
|
val ->
|
||||||
|
val.matches(
|
||||||
|
"\\s*00000000-0000-0000-0000-000000000000\\s*|UNKNOWN")),
|
||||||
|
equalTo(RPC_SYSTEM, "aws-api"),
|
||||||
|
equalTo(RPC_SERVICE, "Sqs"),
|
||||||
|
equalTo(RPC_METHOD, "ReceiveMessage"),
|
||||||
|
equalTo(HTTP_REQUEST_METHOD, "POST"),
|
||||||
|
equalTo(HTTP_RESPONSE_STATUS_CODE, 200),
|
||||||
|
satisfies(URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
|
equalTo(SERVER_PORT, sqsPort))));
|
||||||
|
}
|
||||||
|
|
||||||
|
getTesting().waitAndAssertTraces(traceAsserts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("deprecation") // using deprecated semconv
|
||||||
|
void testBatchSqsProducerConsumerServicesSync() throws URISyntaxException {
|
||||||
|
SqsClientBuilder builder = SqsClient.builder();
|
||||||
|
configureSdkClient(builder);
|
||||||
|
SqsClient client = configureSqsClient(builder.build());
|
||||||
|
|
||||||
|
client.createQueue(createQueueRequest);
|
||||||
|
client.sendMessageBatch(sendMessageBatchRequest);
|
||||||
|
|
||||||
|
ReceiveMessageResponse response = client.receiveMessage(receiveMessageBatchRequest);
|
||||||
|
|
||||||
|
int totalAttrs =
|
||||||
|
response.messages().stream().mapToInt(message -> message.messageAttributes().size()).sum();
|
||||||
|
|
||||||
|
// generates the process spans
|
||||||
|
response.messages().forEach(message -> {});
|
||||||
|
|
||||||
|
assertThat(response.messages().size()).isEqualTo(3);
|
||||||
|
|
||||||
|
// +2: 3 messages, 2x traceparent, 1x not injected due to too many attrs
|
||||||
|
assertThat(totalAttrs).isEqualTo(18 + (isSqsAttributeInjectionEnabled() ? 2 : 0));
|
||||||
|
|
||||||
|
List<Consumer<TraceAssert>> traceAsserts =
|
||||||
|
new ArrayList<>(
|
||||||
|
Arrays.asList(
|
||||||
|
trace -> trace.hasSpansSatisfyingExactly(span -> createQueueSpan(span)),
|
||||||
|
trace -> {
|
||||||
|
List<Consumer<SpanDataAssert>> spanAsserts =
|
||||||
|
new ArrayList<>(
|
||||||
|
singletonList(span -> publishSpan(span, queueUrl, "SendMessageBatch")));
|
||||||
|
|
||||||
|
for (int i = 0; i <= (isXrayInjectionEnabled() ? 2 : 1); i++) {
|
||||||
|
spanAsserts.add(span -> processSpan(span, trace.getSpan(0)));
|
||||||
|
}
|
||||||
|
trace.hasSpansSatisfyingExactly(spanAsserts);
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!isXrayInjectionEnabled()) {
|
||||||
|
traceAsserts.add(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span ->
|
||||||
|
span.hasName("testSdkSqs process")
|
||||||
|
.hasKind(SpanKind.CONSUMER)
|
||||||
|
// TODO: This is not good, and can also happen if producer is not
|
||||||
|
// instrumented
|
||||||
|
.hasNoParent()
|
||||||
|
.hasTotalRecordedLinks(0)
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
|
||||||
|
equalTo(RPC_SYSTEM, "aws-api"),
|
||||||
|
equalTo(RPC_SERVICE, "Sqs"),
|
||||||
|
equalTo(RPC_METHOD, "ReceiveMessage"),
|
||||||
|
equalTo(HTTP_REQUEST_METHOD, "POST"),
|
||||||
|
equalTo(HTTP_RESPONSE_STATUS_CODE, 200),
|
||||||
|
satisfies(URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
|
equalTo(SERVER_PORT, sqsPort),
|
||||||
|
equalTo(MESSAGING_SYSTEM, AWS_SQS),
|
||||||
|
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
||||||
|
equalTo(MESSAGING_OPERATION, "process"),
|
||||||
|
satisfies(MESSAGING_MESSAGE_ID, v -> v.isInstanceOf(String.class)))));
|
||||||
|
}
|
||||||
|
getTesting().waitAndAssertTraces(traceAsserts);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,186 +14,51 @@ import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE;
|
||||||
import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS;
|
import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS;
|
||||||
import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT;
|
import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT;
|
||||||
import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
|
import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
|
||||||
|
import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_REQUEST_ID;
|
||||||
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_BATCH_MESSAGE_COUNT;
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_BATCH_MESSAGE_COUNT;
|
||||||
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME;
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME;
|
||||||
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID;
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID;
|
||||||
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_OPERATION;
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_OPERATION;
|
||||||
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_SYSTEM;
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_SYSTEM;
|
||||||
|
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS;
|
||||||
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD;
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD;
|
||||||
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE;
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE;
|
||||||
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM;
|
import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import io.opentelemetry.api.common.Attributes;
|
import io.opentelemetry.api.common.Attributes;
|
||||||
import io.opentelemetry.api.trace.SpanKind;
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
|
|
||||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
|
||||||
import io.opentelemetry.sdk.testing.assertj.AttributeAssertion;
|
import io.opentelemetry.sdk.testing.assertj.AttributeAssertion;
|
||||||
import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
|
import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
|
||||||
import io.opentelemetry.sdk.trace.data.SpanData;
|
import io.opentelemetry.sdk.trace.data.SpanData;
|
||||||
import io.opentelemetry.semconv.incubating.AwsIncubatingAttributes;
|
|
||||||
import io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes;
|
|
||||||
import io.opentelemetry.testing.internal.armeria.internal.shaded.guava.collect.ImmutableList;
|
import io.opentelemetry.testing.internal.armeria.internal.shaded.guava.collect.ImmutableList;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import org.apache.pekko.http.scaladsl.Http;
|
|
||||||
import org.elasticmq.rest.sqs.SQSRestServer;
|
|
||||||
import org.elasticmq.rest.sqs.SQSRestServerBuilder;
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
|
||||||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
|
||||||
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
|
|
||||||
import software.amazon.awssdk.regions.Region;
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsAsyncClient;
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsAsyncClientBuilder;
|
|
||||||
import software.amazon.awssdk.services.sqs.SqsClient;
|
import software.amazon.awssdk.services.sqs.SqsClient;
|
||||||
import software.amazon.awssdk.services.sqs.SqsClientBuilder;
|
import software.amazon.awssdk.services.sqs.SqsClientBuilder;
|
||||||
import software.amazon.awssdk.services.sqs.model.CreateQueueRequest;
|
|
||||||
import software.amazon.awssdk.services.sqs.model.MessageAttributeValue;
|
import software.amazon.awssdk.services.sqs.model.MessageAttributeValue;
|
||||||
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
|
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
|
||||||
import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
|
import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse;
|
||||||
import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequest;
|
|
||||||
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;
|
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // using deprecated semconv
|
@SuppressWarnings("deprecation") // using deprecated semconv
|
||||||
public abstract class AbstractAws2SqsTracingTest {
|
public abstract class AbstractAws2SqsTracingTest extends AbstractAws2SqsBaseTest {
|
||||||
|
|
||||||
protected abstract InstrumentationExtension getTesting();
|
@Override
|
||||||
|
protected void assertSqsTraces(boolean withParent, boolean captureHeaders) {
|
||||||
protected abstract SqsClient configureSqsClient(SqsClient sqsClient);
|
|
||||||
|
|
||||||
protected abstract SqsAsyncClient configureSqsClient(SqsAsyncClient sqsClient);
|
|
||||||
|
|
||||||
protected abstract ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder();
|
|
||||||
|
|
||||||
private static final StaticCredentialsProvider CREDENTIALS_PROVIDER =
|
|
||||||
StaticCredentialsProvider.create(
|
|
||||||
AwsBasicCredentials.create("my-access-key", "my-secret-key"));
|
|
||||||
|
|
||||||
private static int sqsPort;
|
|
||||||
private static SQSRestServer sqs;
|
|
||||||
|
|
||||||
static Map<String, MessageAttributeValue> dummyMessageAttributes(int count) {
|
|
||||||
Map<String, MessageAttributeValue> map = new HashMap<>();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
map.put(
|
|
||||||
"a" + i, MessageAttributeValue.builder().stringValue("v" + i).dataType("String").build());
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String queueUrl = "http://localhost:" + sqsPort + "/000000000000/testSdkSqs";
|
|
||||||
|
|
||||||
ReceiveMessageRequest receiveMessageRequest =
|
|
||||||
ReceiveMessageRequest.builder().queueUrl(queueUrl).build();
|
|
||||||
|
|
||||||
ReceiveMessageRequest receiveMessageBatchRequest =
|
|
||||||
ReceiveMessageRequest.builder()
|
|
||||||
.queueUrl(queueUrl)
|
|
||||||
.maxNumberOfMessages(3)
|
|
||||||
.messageAttributeNames("All")
|
|
||||||
.waitTimeSeconds(5)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
CreateQueueRequest createQueueRequest =
|
|
||||||
CreateQueueRequest.builder().queueName("testSdkSqs").build();
|
|
||||||
|
|
||||||
SendMessageRequest sendMessageRequest =
|
|
||||||
SendMessageRequest.builder().queueUrl(queueUrl).messageBody("{\"type\": \"hello\"}").build();
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
SendMessageBatchRequest sendMessageBatchRequest =
|
|
||||||
SendMessageBatchRequest.builder()
|
|
||||||
.queueUrl(queueUrl)
|
|
||||||
.entries(
|
|
||||||
e -> e.messageBody("e1").id("i1"),
|
|
||||||
// 8 attributes, injection always possible
|
|
||||||
e -> e.messageBody("e2").id("i2").messageAttributes(dummyMessageAttributes(8)),
|
|
||||||
// 10 attributes, injection with custom propagator never possible
|
|
||||||
e -> e.messageBody("e3").id("i3").messageAttributes(dummyMessageAttributes(10)))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
boolean isSqsAttributeInjectionEnabled() {
|
|
||||||
// See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor
|
|
||||||
return ConfigPropertiesUtil.getBoolean(
|
|
||||||
"otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isXrayInjectionEnabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void configureSdkClient(SqsClientBuilder builder) throws URISyntaxException {
|
|
||||||
builder
|
|
||||||
.overrideConfiguration(createOverrideConfigurationBuilder().build())
|
|
||||||
.endpointOverride(new URI("http://localhost:" + sqsPort));
|
|
||||||
builder.region(Region.AP_NORTHEAST_1).credentialsProvider(CREDENTIALS_PROVIDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void configureSdkClient(SqsAsyncClientBuilder builder) throws URISyntaxException {
|
|
||||||
builder
|
|
||||||
.overrideConfiguration(createOverrideConfigurationBuilder().build())
|
|
||||||
.endpointOverride(new URI("http://localhost:" + sqsPort));
|
|
||||||
builder.region(Region.AP_NORTHEAST_1).credentialsProvider(CREDENTIALS_PROVIDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
static void setUp() {
|
|
||||||
sqs = SQSRestServerBuilder.withPort(0).withInterface("localhost").start();
|
|
||||||
Http.ServerBinding server = sqs.waitUntilStarted();
|
|
||||||
sqsPort = server.localAddress().getPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
static void cleanUp() {
|
|
||||||
if (sqs != null) {
|
|
||||||
sqs.stopAndWait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void assertSqsTraces(Boolean withParent, Boolean captureHeaders) {
|
|
||||||
int offset = withParent ? 2 : 0;
|
int offset = withParent ? 2 : 0;
|
||||||
AtomicReference<SpanData> publishSpan = new AtomicReference<>();
|
AtomicReference<SpanData> publishSpan = new AtomicReference<>();
|
||||||
|
|
||||||
getTesting()
|
getTesting()
|
||||||
.waitAndAssertTraces(
|
.waitAndAssertTraces(
|
||||||
trace ->
|
trace -> trace.hasSpansSatisfyingExactly(span -> createQueueSpan(span)),
|
||||||
trace.hasSpansSatisfyingExactly(
|
|
||||||
span ->
|
|
||||||
span.hasName("Sqs.CreateQueue")
|
|
||||||
.hasKind(SpanKind.CLIENT)
|
|
||||||
.hasNoParent()
|
|
||||||
.hasAttributesSatisfyingExactly(
|
|
||||||
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
|
|
||||||
equalTo(stringKey("aws.queue.name"), "testSdkSqs"),
|
|
||||||
satisfies(
|
|
||||||
AwsIncubatingAttributes.AWS_REQUEST_ID,
|
|
||||||
val ->
|
|
||||||
val.satisfiesAnyOf(
|
|
||||||
v ->
|
|
||||||
assertThat(v)
|
|
||||||
.isEqualTo(
|
|
||||||
"00000000-0000-0000-0000-000000000000"),
|
|
||||||
v -> assertThat(v).isEqualTo("UNKNOWN"))),
|
|
||||||
equalTo(RPC_SYSTEM, "aws-api"),
|
|
||||||
equalTo(RPC_SERVICE, "Sqs"),
|
|
||||||
equalTo(RPC_METHOD, "CreateQueue"),
|
|
||||||
equalTo(HTTP_REQUEST_METHOD, "POST"),
|
|
||||||
equalTo(HTTP_RESPONSE_STATUS_CODE, 200),
|
|
||||||
satisfies(
|
|
||||||
URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
|
||||||
equalTo(SERVER_ADDRESS, "localhost"),
|
|
||||||
equalTo(SERVER_PORT, sqsPort))),
|
|
||||||
trace ->
|
trace ->
|
||||||
trace.hasSpansSatisfyingExactly(
|
trace.hasSpansSatisfyingExactly(
|
||||||
span -> {
|
span -> {
|
||||||
|
@ -206,14 +71,10 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
stringKey("aws.queue.url"),
|
stringKey("aws.queue.url"),
|
||||||
"http://localhost:" + sqsPort + "/000000000000/testSdkSqs"),
|
"http://localhost:" + sqsPort + "/000000000000/testSdkSqs"),
|
||||||
satisfies(
|
satisfies(
|
||||||
AwsIncubatingAttributes.AWS_REQUEST_ID,
|
AWS_REQUEST_ID,
|
||||||
val ->
|
val ->
|
||||||
val.satisfiesAnyOf(
|
val.matches(
|
||||||
v ->
|
"\\s*00000000-0000-0000-0000-000000000000\\s*|UNKNOWN")),
|
||||||
assertThat(v)
|
|
||||||
.isEqualTo(
|
|
||||||
"00000000-0000-0000-0000-000000000000"),
|
|
||||||
v -> assertThat(v).isEqualTo("UNKNOWN"))),
|
|
||||||
equalTo(RPC_SYSTEM, "aws-api"),
|
equalTo(RPC_SYSTEM, "aws-api"),
|
||||||
equalTo(RPC_SERVICE, "Sqs"),
|
equalTo(RPC_SERVICE, "Sqs"),
|
||||||
equalTo(RPC_METHOD, "SendMessage"),
|
equalTo(RPC_METHOD, "SendMessage"),
|
||||||
|
@ -223,10 +84,7 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
equalTo(SERVER_ADDRESS, "localhost"),
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
equalTo(SERVER_PORT, sqsPort),
|
equalTo(SERVER_PORT, sqsPort),
|
||||||
equalTo(
|
equalTo(MESSAGING_SYSTEM, AWS_SQS),
|
||||||
MESSAGING_SYSTEM,
|
|
||||||
MessagingIncubatingAttributes.MessagingSystemIncubatingValues
|
|
||||||
.AWS_SQS),
|
|
||||||
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
||||||
equalTo(MESSAGING_OPERATION, "publish"),
|
equalTo(MESSAGING_OPERATION, "publish"),
|
||||||
satisfies(
|
satisfies(
|
||||||
|
@ -266,14 +124,10 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
stringKey("aws.queue.url"),
|
stringKey("aws.queue.url"),
|
||||||
"http://localhost:" + sqsPort + "/000000000000/testSdkSqs"),
|
"http://localhost:" + sqsPort + "/000000000000/testSdkSqs"),
|
||||||
satisfies(
|
satisfies(
|
||||||
AwsIncubatingAttributes.AWS_REQUEST_ID,
|
AWS_REQUEST_ID,
|
||||||
val ->
|
val ->
|
||||||
val.satisfiesAnyOf(
|
val.matches(
|
||||||
v ->
|
"\\s*00000000-0000-0000-0000-000000000000\\s*|UNKNOWN")),
|
||||||
assertThat(v)
|
|
||||||
.isEqualTo(
|
|
||||||
"00000000-0000-0000-0000-000000000000"),
|
|
||||||
v -> assertThat(v).isEqualTo("UNKNOWN"))),
|
|
||||||
equalTo(RPC_SYSTEM, "aws-api"),
|
equalTo(RPC_SYSTEM, "aws-api"),
|
||||||
equalTo(RPC_SERVICE, "Sqs"),
|
equalTo(RPC_SERVICE, "Sqs"),
|
||||||
equalTo(RPC_METHOD, "ReceiveMessage"),
|
equalTo(RPC_METHOD, "ReceiveMessage"),
|
||||||
|
@ -301,10 +155,7 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
equalTo(SERVER_ADDRESS, "localhost"),
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
equalTo(SERVER_PORT, sqsPort),
|
equalTo(SERVER_PORT, sqsPort),
|
||||||
equalTo(
|
equalTo(MESSAGING_SYSTEM, AWS_SQS),
|
||||||
MESSAGING_SYSTEM,
|
|
||||||
MessagingIncubatingAttributes
|
|
||||||
.MessagingSystemIncubatingValues.AWS_SQS),
|
|
||||||
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
||||||
equalTo(MESSAGING_OPERATION, "receive"),
|
equalTo(MESSAGING_OPERATION, "receive"),
|
||||||
equalTo(MESSAGING_BATCH_MESSAGE_COUNT, 1)));
|
equalTo(MESSAGING_BATCH_MESSAGE_COUNT, 1)));
|
||||||
|
@ -341,10 +192,7 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
equalTo(SERVER_ADDRESS, "localhost"),
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
equalTo(SERVER_PORT, sqsPort),
|
equalTo(SERVER_PORT, sqsPort),
|
||||||
equalTo(
|
equalTo(MESSAGING_SYSTEM, AWS_SQS),
|
||||||
MESSAGING_SYSTEM,
|
|
||||||
MessagingIncubatingAttributes
|
|
||||||
.MessagingSystemIncubatingValues.AWS_SQS),
|
|
||||||
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
||||||
equalTo(MESSAGING_OPERATION, "process"),
|
equalTo(MESSAGING_OPERATION, "process"),
|
||||||
satisfies(
|
satisfies(
|
||||||
|
@ -354,7 +202,7 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
attributes.add(
|
attributes.add(
|
||||||
satisfies(
|
satisfies(
|
||||||
stringArrayKey("messaging.header.test_message_header"),
|
stringArrayKey("messaging.header.test_message_header"),
|
||||||
v -> v.isEqualTo(ImmutableList.of("test"))));
|
v -> v.isEqualTo(singletonList("test"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
span.hasName("testSdkSqs process")
|
span.hasName("testSdkSqs process")
|
||||||
|
@ -378,24 +226,6 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSimpleSqsProducerConsumerServicesSync() throws URISyntaxException {
|
|
||||||
SqsClientBuilder builder = SqsClient.builder();
|
|
||||||
configureSdkClient(builder);
|
|
||||||
SqsClient client = configureSqsClient(builder.build());
|
|
||||||
|
|
||||||
client.createQueue(createQueueRequest);
|
|
||||||
|
|
||||||
client.sendMessage(sendMessageRequest);
|
|
||||||
|
|
||||||
ReceiveMessageResponse response = client.receiveMessage(receiveMessageRequest);
|
|
||||||
|
|
||||||
assertThat(response.messages().size()).isEqualTo(1);
|
|
||||||
|
|
||||||
response.messages().forEach(message -> getTesting().runWithSpan("process child", () -> {}));
|
|
||||||
assertSqsTraces(false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCaptureMessageHeaderAsAttributeSpan() throws URISyntaxException {
|
void testCaptureMessageHeaderAsAttributeSpan() throws URISyntaxException {
|
||||||
SqsClientBuilder builder = SqsClient.builder();
|
SqsClientBuilder builder = SqsClient.builder();
|
||||||
|
@ -423,42 +253,6 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
assertSqsTraces(false, true);
|
assertSqsTraces(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSimpleSqsProducerConsumerServicesWithParentSync() throws URISyntaxException {
|
|
||||||
SqsClientBuilder builder = SqsClient.builder();
|
|
||||||
configureSdkClient(builder);
|
|
||||||
SqsClient client = configureSqsClient(builder.build());
|
|
||||||
|
|
||||||
client.createQueue(createQueueRequest);
|
|
||||||
client.sendMessage(sendMessageRequest);
|
|
||||||
|
|
||||||
ReceiveMessageResponse response =
|
|
||||||
getTesting().runWithSpan("parent", () -> client.receiveMessage(receiveMessageRequest));
|
|
||||||
|
|
||||||
assertThat(response.messages().size()).isEqualTo(1);
|
|
||||||
|
|
||||||
response.messages().forEach(message -> getTesting().runWithSpan("process child", () -> {}));
|
|
||||||
assertSqsTraces(true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("InterruptedExceptionSwallowed")
|
|
||||||
@Test
|
|
||||||
void testSimpleSqsProducerConsumerServicesAsync() throws Exception {
|
|
||||||
SqsAsyncClientBuilder builder = SqsAsyncClient.builder();
|
|
||||||
configureSdkClient(builder);
|
|
||||||
SqsAsyncClient client = configureSqsClient(builder.build());
|
|
||||||
|
|
||||||
client.createQueue(createQueueRequest).get();
|
|
||||||
client.sendMessage(sendMessageRequest).get();
|
|
||||||
|
|
||||||
ReceiveMessageResponse response = client.receiveMessage(receiveMessageRequest).get();
|
|
||||||
|
|
||||||
assertThat(response.messages().size()).isEqualTo(1);
|
|
||||||
|
|
||||||
response.messages().forEach(message -> getTesting().runWithSpan("process child", () -> {}));
|
|
||||||
assertSqsTraces(false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBatchSqsProducerConsumerServicesSync() throws URISyntaxException {
|
void testBatchSqsProducerConsumerServicesSync() throws URISyntaxException {
|
||||||
SqsClientBuilder builder = SqsClient.builder();
|
SqsClientBuilder builder = SqsClient.builder();
|
||||||
|
@ -489,38 +283,7 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
trace -> {
|
trace -> {
|
||||||
publishSpan.set(trace.getSpan(0));
|
publishSpan.set(trace.getSpan(0));
|
||||||
trace.hasSpansSatisfyingExactly(
|
trace.hasSpansSatisfyingExactly(
|
||||||
span ->
|
span -> publishSpan(span, queueUrl, "SendMessageBatch"));
|
||||||
span.hasName("testSdkSqs publish")
|
|
||||||
.hasKind(SpanKind.PRODUCER)
|
|
||||||
.hasNoParent()
|
|
||||||
.hasAttributesSatisfyingExactly(
|
|
||||||
equalTo(stringKey("aws.agent"), "java-aws-sdk"),
|
|
||||||
equalTo(
|
|
||||||
stringKey("aws.queue.url"),
|
|
||||||
"http://localhost:" + sqsPort + "/000000000000/testSdkSqs"),
|
|
||||||
satisfies(
|
|
||||||
AwsIncubatingAttributes.AWS_REQUEST_ID,
|
|
||||||
val ->
|
|
||||||
val.satisfiesAnyOf(
|
|
||||||
v ->
|
|
||||||
assertThat(v.trim())
|
|
||||||
.isEqualTo(
|
|
||||||
"00000000-0000-0000-0000-000000000000"),
|
|
||||||
v -> assertThat(v.trim()).isEqualTo("UNKNOWN"))),
|
|
||||||
equalTo(RPC_SYSTEM, "aws-api"),
|
|
||||||
equalTo(RPC_SERVICE, "Sqs"),
|
|
||||||
equalTo(RPC_METHOD, "SendMessageBatch"),
|
|
||||||
equalTo(HTTP_REQUEST_METHOD, "POST"),
|
|
||||||
equalTo(HTTP_RESPONSE_STATUS_CODE, 200),
|
|
||||||
satisfies(URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
|
||||||
equalTo(SERVER_ADDRESS, "localhost"),
|
|
||||||
equalTo(SERVER_PORT, sqsPort),
|
|
||||||
equalTo(
|
|
||||||
MESSAGING_SYSTEM,
|
|
||||||
MessagingIncubatingAttributes.MessagingSystemIncubatingValues
|
|
||||||
.AWS_SQS),
|
|
||||||
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
|
||||||
equalTo(MESSAGING_OPERATION, "publish")));
|
|
||||||
},
|
},
|
||||||
trace -> {
|
trace -> {
|
||||||
List<Consumer<SpanDataAssert>> spanAsserts = new ArrayList<>();
|
List<Consumer<SpanDataAssert>> spanAsserts = new ArrayList<>();
|
||||||
|
@ -540,10 +303,7 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
satisfies(URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
satisfies(URL_FULL, v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
equalTo(SERVER_ADDRESS, "localhost"),
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
equalTo(SERVER_PORT, sqsPort),
|
equalTo(SERVER_PORT, sqsPort),
|
||||||
equalTo(
|
equalTo(MESSAGING_SYSTEM, AWS_SQS),
|
||||||
MESSAGING_SYSTEM,
|
|
||||||
MessagingIncubatingAttributes.MessagingSystemIncubatingValues
|
|
||||||
.AWS_SQS),
|
|
||||||
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
||||||
equalTo(MESSAGING_OPERATION, "receive"),
|
equalTo(MESSAGING_OPERATION, "receive"),
|
||||||
equalTo(MESSAGING_BATCH_MESSAGE_COUNT, 3)));
|
equalTo(MESSAGING_BATCH_MESSAGE_COUNT, 3)));
|
||||||
|
@ -585,10 +345,7 @@ public abstract class AbstractAws2SqsTracingTest {
|
||||||
v -> v.startsWith("http://localhost:" + sqsPort)),
|
v -> v.startsWith("http://localhost:" + sqsPort)),
|
||||||
equalTo(SERVER_ADDRESS, "localhost"),
|
equalTo(SERVER_ADDRESS, "localhost"),
|
||||||
equalTo(SERVER_PORT, sqsPort),
|
equalTo(SERVER_PORT, sqsPort),
|
||||||
equalTo(
|
equalTo(MESSAGING_SYSTEM, AWS_SQS),
|
||||||
MESSAGING_SYSTEM,
|
|
||||||
MessagingIncubatingAttributes
|
|
||||||
.MessagingSystemIncubatingValues.AWS_SQS),
|
|
||||||
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
equalTo(MESSAGING_DESTINATION_NAME, "testSdkSqs"),
|
||||||
equalTo(MESSAGING_OPERATION, "process"),
|
equalTo(MESSAGING_OPERATION, "process"),
|
||||||
satisfies(
|
satisfies(
|
||||||
|
|
Loading…
Reference in New Issue