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 9df1916a021a..676b88988d9b 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 @@ -121,9 +121,10 @@ dependencies { testLibrary("software.amazon.awssdk:lambda:2.2.0") testLibrary("software.amazon.awssdk:rds:2.2.0") testLibrary("software.amazon.awssdk:s3:2.2.0") - testLibrary("software.amazon.awssdk:sqs:2.2.0") - testLibrary("software.amazon.awssdk:sns:2.2.0") testLibrary("software.amazon.awssdk:ses:2.2.0") + testLibrary("software.amazon.awssdk:secretsmanager:2.2.0") + testLibrary("software.amazon.awssdk:sns:2.2.0") + testLibrary("software.amazon.awssdk:sqs:2.2.0") } val latestDepTest = findProperty("testLatestDeps") as Boolean 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 f438d3e49383..50f3acfa0a73 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 @@ -18,8 +18,9 @@ dependencies { testLibrary("software.amazon.awssdk:lambda:2.2.0") testLibrary("software.amazon.awssdk:rds:2.2.0") testLibrary("software.amazon.awssdk:s3:2.2.0") - testLibrary("software.amazon.awssdk:sqs:2.2.0") + testLibrary("software.amazon.awssdk:secretsmanager:2.2.0") testLibrary("software.amazon.awssdk:sns:2.2.0") + testLibrary("software.amazon.awssdk:sqs:2.2.0") } tasks { 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 cc196ed11e75..68de20527a90 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 @@ -26,6 +26,7 @@ dependencies { testLibrary("software.amazon.awssdk:kinesis:2.2.0") 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:ses:2.2.0") } 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 2d2745a594e7..7a520861abe6 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 @@ -9,6 +9,7 @@ import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.DYNAMODB; import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.KINESIS; import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.S3; +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.FieldMapping.request; @@ -35,6 +36,7 @@ enum AwsSdkRequest { SnsRequest(SNS, "SnsRequest"), SqsRequest(SQS, "SqsRequest"), KinesisRequest(KINESIS, "KinesisRequest"), + SecretsManagerRequest(SECRETSMANAGER, "SecretsManagerRequest"), // 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 1e1c2c668ec3..50a2c969e960 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 @@ -5,7 +5,9 @@ package io.opentelemetry.instrumentation.awssdk.v2_2.internal; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.request; +import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.response; import io.opentelemetry.api.common.AttributeKey; import java.util.Collections; @@ -18,6 +20,7 @@ enum AwsSdkRequestType { KINESIS(request("aws.stream.name", "StreamName")), DYNAMODB(request("aws.table.name", "TableName")), BEDROCK_RUNTIME(), + SECRETSMANAGER(response(AttributeKeys.AWS_SECRETSMANAGER_SECRET_ARN.getKey(), "ARN")), SNS( /* * Only one of TopicArn and TargetArn are permitted on an SNS request. @@ -38,6 +41,10 @@ List fields(FieldMapping.Type type) { } private static class AttributeKeys { + // Copied from AwsIncubatingAttributes + static final AttributeKey AWS_SECRETSMANAGER_SECRET_ARN = + stringKey("aws.secretsmanager.secret.arn"); + // copied from MessagingIncubatingAttributes static final AttributeKey MESSAGING_DESTINATION_NAME = AttributeKey.stringKey("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 eb52ab1d1c7e..43dcc2a18940 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 @@ -18,9 +18,10 @@ dependencies { compileOnly("software.amazon.awssdk:lambda:2.2.0") compileOnly("software.amazon.awssdk:rds:2.2.0") compileOnly("software.amazon.awssdk:s3:2.2.0") - compileOnly("software.amazon.awssdk:sqs:2.2.0") - compileOnly("software.amazon.awssdk:sns:2.2.0") + compileOnly("software.amazon.awssdk:secretsmanager:2.2.0") compileOnly("software.amazon.awssdk:ses:2.2.0") + compileOnly("software.amazon.awssdk:sns:2.2.0") + compileOnly("software.amazon.awssdk:sqs:2.2.0") // needed for SQS - using emq directly as localstack references emq v0.15.7 ie WITHOUT AWS trace header propagation implementation("org.elasticmq:elasticmq-rest-sqs_2.13") 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 8f5dfe0e665e..04e523c19d9e 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 @@ -14,6 +14,7 @@ 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.AwsIncubatingAttributes.AWS_SECRETSMANAGER_SECRET_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; @@ -79,6 +80,12 @@ import software.amazon.awssdk.services.s3.S3ClientBuilder; import software.amazon.awssdk.services.s3.model.CreateBucketRequest; import software.amazon.awssdk.services.s3.model.GetObjectRequest; +import software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClient; +import software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClientBuilder; +import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; +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.sns.SnsAsyncClient; import software.amazon.awssdk.services.sns.SnsAsyncClientBuilder; import software.amazon.awssdk.services.sns.SnsClient; @@ -112,6 +119,18 @@ public abstract class AbstractAws2ClientTest extends AbstractAws2ClientCoreTest + " 0ac9cda2-bbf4-11d3-f92b-31fa5e8dbc99" + ""; + private static final String secretsManagerBodyContent = + "{" + + " \"ARN\": \"arn:aws:secretsmanager:us-east-1:123456789012:secret:MySecretFromCLI-sNkBwD\"," + + " \"Name\": \"MySecretFromCLI\"," + + " \"VersionId\": \"9959b95b-1234-5678-a19b-a4b0315ca5aa\"," + + " \"SecretString\": \"super-secret-value\"," + + " \"VersionStages\": [" + + " \"AWSCURRENT\"" + + " ]," + + " \"CreatedDate\": \"1.523477145713E9\"" + + "}"; + private static void assumeSupportedConfig(String operation) { Assumptions.assumeFalse( operation.equals("SendMessage") && isSqsAttributeInjectionEnabled(), @@ -214,6 +233,13 @@ private void clientAssertions( equalTo(MESSAGING_SYSTEM, AWS_SQS)))); } + if (service.equals("SecretsManager")) { + attributes.add( + equalTo( + AWS_SECRETSMANAGER_SECRET_ARN, + "arn:aws:secretsmanager:us-east-1:123456789012:secret:MySecretFromCLI-sNkBwD")); + } + String evaluatedOperation; SpanKind operationKind; if (operation.equals("SendMessage")) { @@ -722,4 +748,44 @@ void testS3ListNullBucket() { assertThat(Context.current()).isEqualTo(Context.root()); } + + @Test + void testSecretsManagerSendOperationRequestWithBuilder() { + SecretsManagerClientBuilder builder = SecretsManagerClient.builder(); + configureSdkClient(builder); + SecretsManagerClient client = + builder + .endpointOverride(clientUri) + .region(Region.AP_NORTHEAST_1) + .credentialsProvider(CREDENTIALS_PROVIDER) + .build(); + + server.enqueue( + HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, secretsManagerBodyContent)); + Object response = + client.getSecretValue(GetSecretValueRequest.builder().secretId("MySecretFromCLI").build()); + assertThat(response.getClass().getSimpleName()) + .satisfies( + v -> assertThat(v).isEqualTo("GetSecretValueResponse"), + v -> assertThat(response).isInstanceOf(GetSecretValueResponse.class)); + clientAssertions("SecretsManager", "GetSecretValue", "POST", response, "UNKNOWN"); + } + + @Test + void testSecretsManagerAsyncSendOperationRequestWithBuilder() { + SecretsManagerAsyncClientBuilder builder = SecretsManagerAsyncClient.builder(); + configureSdkClient(builder); + SecretsManagerAsyncClient client = + builder + .endpointOverride(clientUri) + .region(Region.AP_NORTHEAST_1) + .credentialsProvider(CREDENTIALS_PROVIDER) + .build(); + + server.enqueue( + HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, secretsManagerBodyContent)); + Object response = + client.getSecretValue(GetSecretValueRequest.builder().secretId("MySecretFromCLI").build()); + clientAssertions("SecretsManager", "GetSecretValue", "POST", response, "UNKNOWN"); + } }