diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/build.gradle.kts b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/build.gradle.kts index 676b88988d9b..7d6c76c5c8cb 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/build.gradle.kts +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/build.gradle.kts @@ -123,6 +123,7 @@ dependencies { testLibrary("software.amazon.awssdk:s3:2.2.0") testLibrary("software.amazon.awssdk:ses:2.2.0") testLibrary("software.amazon.awssdk:secretsmanager:2.2.0") + testLibrary("software.amazon.awssdk:sfn:2.2.0") testLibrary("software.amazon.awssdk:sns:2.2.0") testLibrary("software.amazon.awssdk:sqs:2.2.0") } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/build.gradle.kts b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/build.gradle.kts index 50f3acfa0a73..3cdb0f82abfb 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/build.gradle.kts +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { testLibrary("software.amazon.awssdk:rds:2.2.0") testLibrary("software.amazon.awssdk:s3:2.2.0") testLibrary("software.amazon.awssdk:secretsmanager:2.2.0") + testLibrary("software.amazon.awssdk:sfn:2.2.0") testLibrary("software.amazon.awssdk:sns:2.2.0") testLibrary("software.amazon.awssdk:sqs:2.2.0") } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts b/instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts index 68de20527a90..2fe8f5ded759 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { testLibrary("software.amazon.awssdk:s3:2.2.0") testLibrary("software.amazon.awssdk:secretsmanager:2.2.0") testLibrary("software.amazon.awssdk:ses:2.2.0") + testLibrary("software.amazon.awssdk:sfn:2.2.0") } val testLatestDeps = findProperty("testLatestDeps") as Boolean diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequest.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequest.java index 7a520861abe6..3f7fd57bb994 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequest.java @@ -12,6 +12,7 @@ import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SECRETSMANAGER; import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SNS; import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SQS; +import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.STEPFUNCTIONS; import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.request; import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.response; @@ -37,6 +38,7 @@ enum AwsSdkRequest { SqsRequest(SQS, "SqsRequest"), KinesisRequest(KINESIS, "KinesisRequest"), SecretsManagerRequest(SECRETSMANAGER, "SecretsManagerRequest"), + StepFunctionsRequest(STEPFUNCTIONS, "SfnRequest"), // specific requests BatchGetItem( DYNAMODB, diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequestType.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequestType.java index 50a2c969e960..f35b75f1bb82 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequestType.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequestType.java @@ -26,7 +26,10 @@ enum AwsSdkRequestType { * Only one of TopicArn and TargetArn are permitted on an SNS request. */ request(AttributeKeys.MESSAGING_DESTINATION_NAME.getKey(), "TargetArn"), - request(AttributeKeys.MESSAGING_DESTINATION_NAME.getKey(), "TopicArn")); + request(AttributeKeys.MESSAGING_DESTINATION_NAME.getKey(), "TopicArn")), + STEPFUNCTIONS( + request(AttributeKeys.AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN.getKey(), "stateMachineArn"), + request(AttributeKeys.AWS_STEP_FUNCTIONS_ACTIVITY_ARN.getKey(), "activityArn")); // Wrapping in unmodifiableMap @SuppressWarnings("ImmutableEnumChecker") @@ -44,6 +47,10 @@ private static class AttributeKeys { // Copied from AwsIncubatingAttributes static final AttributeKey AWS_SECRETSMANAGER_SECRET_ARN = stringKey("aws.secretsmanager.secret.arn"); + static final AttributeKey AWS_STEP_FUNCTIONS_ACTIVITY_ARN = + stringKey("aws.step_functions.activity.arn"); + static final AttributeKey AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN = + stringKey("aws.step_functions.state_machine.arn"); // copied from MessagingIncubatingAttributes static final AttributeKey MESSAGING_DESTINATION_NAME = diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/build.gradle.kts b/instrumentation/aws-sdk/aws-sdk-2.2/testing/build.gradle.kts index 43dcc2a18940..2978ece1158f 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/build.gradle.kts +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/build.gradle.kts @@ -20,6 +20,7 @@ dependencies { compileOnly("software.amazon.awssdk:s3:2.2.0") compileOnly("software.amazon.awssdk:secretsmanager:2.2.0") compileOnly("software.amazon.awssdk:ses:2.2.0") + compileOnly("software.amazon.awssdk:sfn:2.2.0") compileOnly("software.amazon.awssdk:sns:2.2.0") compileOnly("software.amazon.awssdk:sqs:2.2.0") diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java index 04e523c19d9e..3def65b2b9a2 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java @@ -15,6 +15,8 @@ import static io.opentelemetry.semconv.UrlAttributes.URL_FULL; import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_REQUEST_ID; import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_SECRETSMANAGER_SECRET_ARN; +import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_STEP_FUNCTIONS_ACTIVITY_ARN; +import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN; 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; @@ -86,6 +88,12 @@ import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder; import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest; import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse; +import software.amazon.awssdk.services.sfn.SfnAsyncClient; +import software.amazon.awssdk.services.sfn.SfnAsyncClientBuilder; +import software.amazon.awssdk.services.sfn.SfnClient; +import software.amazon.awssdk.services.sfn.SfnClientBuilder; +import software.amazon.awssdk.services.sfn.model.DescribeActivityRequest; +import software.amazon.awssdk.services.sfn.model.DescribeStateMachineRequest; import software.amazon.awssdk.services.sns.SnsAsyncClient; import software.amazon.awssdk.services.sns.SnsAsyncClientBuilder; import software.amazon.awssdk.services.sns.SnsClient; @@ -233,6 +241,14 @@ private void clientAssertions( equalTo(MESSAGING_SYSTEM, AWS_SQS)))); } + if (service.equals("Sfn")) { + if (operation.equals("DescribeStateMachine")) { + attributes.add(equalTo(AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN, "state:machine:arn:foo")); + } else if (operation.equals("DescribeActivity")) { + attributes.add(equalTo(AWS_STEP_FUNCTIONS_ACTIVITY_ARN, "activity:arn:foo")); + } + } + if (service.equals("SecretsManager")) { attributes.add( equalTo( @@ -749,6 +765,86 @@ void testS3ListNullBucket() { assertThat(Context.current()).isEqualTo(Context.root()); } + private static Stream provideStepFunctionsArguments() { + return Stream.of( + Arguments.of( + (Function) + c -> + c.describeStateMachine( + DescribeStateMachineRequest.builder() + .stateMachineArn("state:machine:arn:foo") + .build()), + "DescribeStateMachine", + "POST", + "UNKNOWN"), + Arguments.of( + (Function) + c -> + c.describeActivity( + DescribeActivityRequest.builder().activityArn("activity:arn:foo").build()), + "DescribeActivity", + "POST", + "UNKNOWN")); + } + + @ParameterizedTest + @MethodSource("provideStepFunctionsArguments") + void testSfnSendOperationRequestWithBuilder( + Function call, String operation, String method, String requestId) { + SfnClientBuilder builder = SfnClient.builder(); + configureSdkClient(builder); + SfnClient client = + builder + .endpointOverride(clientUri) + .region(Region.AP_NORTHEAST_1) + .credentialsProvider(CREDENTIALS_PROVIDER) + .build(); + + server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, "")); + Object response = call.apply(client); + assertThat(response.getClass().getSimpleName()) + .satisfiesAnyOf( + v -> + assertThat(response) + .isInstanceOf( + software.amazon.awssdk.services.sfn.model.DescribeActivityResponse.class), + v -> + assertThat(response) + .isInstanceOf( + software.amazon.awssdk.services.sfn.model.DescribeStateMachineResponse + .class)); + clientAssertions("Sfn", operation, method, response, requestId); + } + + @ParameterizedTest + @MethodSource("provideStepFunctionsArguments") + void testSfnAsyncSendOperationRequestWithBuilder( + Function call, String operation, String method, String requestId) { + SfnAsyncClientBuilder builder = SfnAsyncClient.builder(); + configureSdkClient(builder); + SfnAsyncClient client = + builder + .endpointOverride(clientUri) + .region(Region.AP_NORTHEAST_1) + .credentialsProvider(CREDENTIALS_PROVIDER) + .build(); + + server.enqueue(HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, "")); + Object response = call.apply(wrapClient(SfnClient.class, SfnAsyncClient.class, client)); + assertThat(response.getClass().getSimpleName()) + .satisfiesAnyOf( + v -> + assertThat(response) + .isInstanceOf( + software.amazon.awssdk.services.sfn.model.DescribeActivityResponse.class), + v -> + assertThat(response) + .isInstanceOf( + software.amazon.awssdk.services.sfn.model.DescribeStateMachineResponse + .class)); + clientAssertions("Sfn", operation, method, response, requestId); + } + @Test void testSecretsManagerSendOperationRequestWithBuilder() { SecretsManagerClientBuilder builder = SecretsManagerClient.builder();