Skip to content

Commit 69754f8

Browse files
committed
feat: AWS SDK v2 Secrets Manager auto-instrumentation support
This PR adds auto-instrumentation support for the following AWS resource: Secrets Manager Tests Run: ./gradlew spotlessCheck ./gradlew clean assemble ./gradlew instrumentation:check ./gradlew :smoke-tests:test No regression issues found. All newly added tests pass. Backward Compatibility: There is no risk of breaking existing functionality. This change only adds instrumentation for additional AWS resources without modifying the existing behavior of the auto-instrumentation library.
1 parent 8af76e8 commit 69754f8

File tree

8 files changed

+109
-9
lines changed

8 files changed

+109
-9
lines changed

instrumentation/aws-sdk/aws-sdk-2.2/javaagent/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,10 @@ dependencies {
121121
testLibrary("software.amazon.awssdk:lambda:2.2.0")
122122
testLibrary("software.amazon.awssdk:rds:2.2.0")
123123
testLibrary("software.amazon.awssdk:s3:2.2.0")
124-
testLibrary("software.amazon.awssdk:sqs:2.2.0")
125-
testLibrary("software.amazon.awssdk:sns:2.2.0")
126124
testLibrary("software.amazon.awssdk:ses:2.2.0")
125+
testLibrary("software.amazon.awssdk:secretsmanager:2.2.0")
126+
testLibrary("software.amazon.awssdk:sns:2.2.0")
127+
testLibrary("software.amazon.awssdk:sqs:2.2.0")
127128
}
128129

129130
val latestDepTest = findProperty("testLatestDeps") as Boolean

instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ dependencies {
1818
testLibrary("software.amazon.awssdk:lambda:2.2.0")
1919
testLibrary("software.amazon.awssdk:rds:2.2.0")
2020
testLibrary("software.amazon.awssdk:s3:2.2.0")
21-
testLibrary("software.amazon.awssdk:sqs:2.2.0")
21+
testLibrary("software.amazon.awssdk:secretsmanager:2.2.0")
2222
testLibrary("software.amazon.awssdk:sns:2.2.0")
23+
testLibrary("software.amazon.awssdk:sqs:2.2.0")
2324
}
2425

2526
tasks {

instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ dependencies {
2626
testLibrary("software.amazon.awssdk:kinesis:2.2.0")
2727
testLibrary("software.amazon.awssdk:rds:2.2.0")
2828
testLibrary("software.amazon.awssdk:s3:2.2.0")
29+
testLibrary("software.amazon.awssdk:secretsmanager:2.2.0")
2930
testLibrary("software.amazon.awssdk:ses:2.2.0")
3031
}
3132

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.awssdk.v2_2.internal;
7+
8+
import static io.opentelemetry.api.common.AttributeKey.stringKey;
9+
10+
import io.opentelemetry.api.common.AttributeKey;
11+
12+
final class AwsExperimentalAttributes {
13+
static final AttributeKey<String> AWS_BUCKET_NAME = stringKey("aws.bucket.name");
14+
static final AttributeKey<String> AWS_QUEUE_URL = stringKey("aws.queue.url");
15+
static final AttributeKey<String> AWS_QUEUE_NAME = stringKey("aws.queue.name");
16+
static final AttributeKey<String> AWS_SECRET_ARN = stringKey("aws.secretsmanager.secret.arn");
17+
static final AttributeKey<String> AWS_STREAM_NAME = stringKey("aws.stream.name");
18+
static final AttributeKey<String> AWS_TABLE_NAME = stringKey("aws.table.name");
19+
20+
private AwsExperimentalAttributes() {}
21+
}

instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.DYNAMODB;
1010
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.KINESIS;
1111
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.S3;
12+
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SECRETSMANAGER;
1213
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SNS;
1314
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SQS;
1415
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.request;
@@ -35,6 +36,7 @@ enum AwsSdkRequest {
3536
SnsRequest(SNS, "SnsRequest"),
3637
SqsRequest(SQS, "SqsRequest"),
3738
KinesisRequest(KINESIS, "KinesisRequest"),
39+
SecretsManagerRequest(SECRETSMANAGER, "SecretsManagerRequest"),
3840
// specific requests
3941
BatchGetItem(
4042
DYNAMODB,

instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AwsSdkRequestType.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,27 @@
55

66
package io.opentelemetry.instrumentation.awssdk.v2_2.internal;
77

8+
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsExperimentalAttributes.AWS_BUCKET_NAME;
9+
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsExperimentalAttributes.AWS_QUEUE_NAME;
10+
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsExperimentalAttributes.AWS_QUEUE_URL;
11+
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsExperimentalAttributes.AWS_SECRET_ARN;
12+
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsExperimentalAttributes.AWS_STREAM_NAME;
13+
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsExperimentalAttributes.AWS_TABLE_NAME;
814
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.request;
15+
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.response;
916

1017
import io.opentelemetry.api.common.AttributeKey;
1118
import java.util.Collections;
1219
import java.util.List;
1320
import java.util.Map;
1421

1522
enum AwsSdkRequestType {
16-
S3(request("aws.bucket.name", "Bucket")),
17-
SQS(request("aws.queue.url", "QueueUrl"), request("aws.queue.name", "QueueName")),
18-
KINESIS(request("aws.stream.name", "StreamName")),
19-
DYNAMODB(request("aws.table.name", "TableName")),
23+
S3(request(AWS_BUCKET_NAME.getKey(), "Bucket")),
24+
SQS(request(AWS_QUEUE_URL.getKey(), "QueueUrl"), request(AWS_QUEUE_NAME.getKey(), "QueueName")),
25+
KINESIS(request(AWS_STREAM_NAME.getKey(), "StreamName")),
26+
DYNAMODB(request(AWS_TABLE_NAME.getKey(), "TableName")),
2027
BEDROCK_RUNTIME(),
28+
SECRETSMANAGER(response(AWS_SECRET_ARN.getKey(), "ARN")),
2129
SNS(
2230
/*
2331
* Only one of TopicArn and TargetArn are permitted on an SNS request.

instrumentation/aws-sdk/aws-sdk-2.2/testing/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ dependencies {
1818
compileOnly("software.amazon.awssdk:lambda:2.2.0")
1919
compileOnly("software.amazon.awssdk:rds:2.2.0")
2020
compileOnly("software.amazon.awssdk:s3:2.2.0")
21-
compileOnly("software.amazon.awssdk:sqs:2.2.0")
22-
compileOnly("software.amazon.awssdk:sns:2.2.0")
21+
compileOnly("software.amazon.awssdk:secretsmanager:2.2.0")
2322
compileOnly("software.amazon.awssdk:ses:2.2.0")
23+
compileOnly("software.amazon.awssdk:sns:2.2.0")
24+
compileOnly("software.amazon.awssdk:sqs:2.2.0")
2425

2526
// needed for SQS - using emq directly as localstack references emq v0.15.7 ie WITHOUT AWS trace header propagation
2627
implementation("org.elasticmq:elasticmq-rest-sqs_2.13")

instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@
7979
import software.amazon.awssdk.services.s3.S3ClientBuilder;
8080
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
8181
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
82+
import software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClient;
83+
import software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClientBuilder;
84+
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
85+
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder;
86+
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
87+
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
8288
import software.amazon.awssdk.services.sns.SnsAsyncClient;
8389
import software.amazon.awssdk.services.sns.SnsAsyncClientBuilder;
8490
import software.amazon.awssdk.services.sns.SnsClient;
@@ -112,6 +118,18 @@ public abstract class AbstractAws2ClientTest extends AbstractAws2ClientCoreTest
112118
+ " <ResponseMetadata><RequestId>0ac9cda2-bbf4-11d3-f92b-31fa5e8dbc99</RequestId></ResponseMetadata>"
113119
+ "</DeleteOptionGroupResponse>";
114120

121+
private static final String secretsManagerBodyContent =
122+
"{"
123+
+ " \"ARN\": \"arn:aws:secretsmanager:us-east-1:123456789012:secret:MySecretFromCLI-sNkBwD\","
124+
+ " \"Name\": \"MySecretFromCLI\","
125+
+ " \"VersionId\": \"9959b95b-1234-5678-a19b-a4b0315ca5aa\","
126+
+ " \"SecretString\": \"super-secret-value\","
127+
+ " \"VersionStages\": ["
128+
+ " \"AWSCURRENT\""
129+
+ " ],"
130+
+ " \"CreatedDate\": \"1.523477145713E9\""
131+
+ "}";
132+
115133
private static void assumeSupportedConfig(String operation) {
116134
Assumptions.assumeFalse(
117135
operation.equals("SendMessage") && isSqsAttributeInjectionEnabled(),
@@ -214,6 +232,13 @@ private void clientAssertions(
214232
equalTo(MESSAGING_SYSTEM, AWS_SQS))));
215233
}
216234

235+
if (service.equals("SecretsManager")) {
236+
attributes.add(
237+
equalTo(
238+
stringKey("aws.secretsmanager.secret.arn"),
239+
"arn:aws:secretsmanager:us-east-1:123456789012:secret:MySecretFromCLI-sNkBwD"));
240+
}
241+
217242
String evaluatedOperation;
218243
SpanKind operationKind;
219244
if (operation.equals("SendMessage")) {
@@ -722,4 +747,44 @@ void testS3ListNullBucket() {
722747

723748
assertThat(Context.current()).isEqualTo(Context.root());
724749
}
750+
751+
@Test
752+
void testSecretsManagerSendOperationRequestWithBuilder() {
753+
SecretsManagerClientBuilder builder = SecretsManagerClient.builder();
754+
configureSdkClient(builder);
755+
SecretsManagerClient client =
756+
builder
757+
.endpointOverride(clientUri)
758+
.region(Region.AP_NORTHEAST_1)
759+
.credentialsProvider(CREDENTIALS_PROVIDER)
760+
.build();
761+
762+
server.enqueue(
763+
HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, secretsManagerBodyContent));
764+
Object response =
765+
client.getSecretValue(GetSecretValueRequest.builder().secretId("MySecretFromCLI").build());
766+
assertThat(response.getClass().getSimpleName())
767+
.satisfies(
768+
v -> assertThat(v).isEqualTo("GetSecretValueResponse"),
769+
v -> assertThat(response).isInstanceOf(GetSecretValueResponse.class));
770+
clientAssertions("SecretsManager", "GetSecretValue", "POST", response, "UNKNOWN");
771+
}
772+
773+
@Test
774+
void testSecretsManagerAsyncSendOperationRequestWithBuilder() {
775+
SecretsManagerAsyncClientBuilder builder = SecretsManagerAsyncClient.builder();
776+
configureSdkClient(builder);
777+
SecretsManagerAsyncClient client =
778+
builder
779+
.endpointOverride(clientUri)
780+
.region(Region.AP_NORTHEAST_1)
781+
.credentialsProvider(CREDENTIALS_PROVIDER)
782+
.build();
783+
784+
server.enqueue(
785+
HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, secretsManagerBodyContent));
786+
Object response =
787+
client.getSecretValue(GetSecretValueRequest.builder().secretId("MySecretFromCLI").build());
788+
clientAssertions("SecretsManager", "GetSecretValue", "POST", response, "UNKNOWN");
789+
}
725790
}

0 commit comments

Comments
 (0)