Skip to content

Commit a4068e9

Browse files
committed
set up contract tests for secrets manager
1 parent 76f87a3 commit a4068e9

File tree

9 files changed

+175
-7
lines changed

9 files changed

+175
-7
lines changed

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/base/AwsSdkBaseTest.java

Lines changed: 113 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import java.util.List;
2424
import java.util.Map;
2525
import java.util.Set;
26+
import java.util.regex.Pattern;
27+
import java.util.regex.PatternSyntaxException;
28+
2629
import org.assertj.core.api.ThrowingConsumer;
2730
import org.junit.jupiter.api.AfterAll;
2831
import org.junit.jupiter.api.BeforeAll;
@@ -42,7 +45,8 @@ public abstract class AwsSdkBaseTest extends ContractTestBase {
4245
LocalStackContainer.Service.S3,
4346
LocalStackContainer.Service.DYNAMODB,
4447
LocalStackContainer.Service.SQS,
45-
LocalStackContainer.Service.KINESIS)
48+
LocalStackContainer.Service.KINESIS,
49+
LocalStackContainer.Service.SECRETSMANAGER)
4650
.withEnv("DEFAULT_REGION", "us-west-2")
4751
.withNetwork(network)
4852
.withEnv("LOCALSTACK_HOST", "127.0.0.1")
@@ -102,6 +106,8 @@ protected String getApplicationWaitPattern() {
102106

103107
protected abstract String getBedrockAgentRuntimeSpanNamePrefix();
104108

109+
protected abstract String getSecretsManagerSpanNamePrefix();
110+
105111
protected abstract String getS3RpcServiceName();
106112

107113
protected abstract String getDynamoDbRpcServiceName();
@@ -118,6 +124,8 @@ protected String getApplicationWaitPattern() {
118124

119125
protected abstract String getBedrockAgentRuntimeRpcServiceName();
120126

127+
protected abstract String getSecretsManagerRpcServiceName();
128+
121129
private String getS3ServiceName() {
122130
return "AWS::S3";
123131
}
@@ -150,6 +158,8 @@ private String getBedrockRuntimeServiceName() {
150158
return "AWS::BedrockRuntime";
151159
}
152160

161+
private String getSecretsManagerServiceName() { return "AWS::SecretsManager"; }
162+
153163
private String s3SpanName(String operation) {
154164
return String.format("%s.%s", getS3SpanNamePrefix(), operation);
155165
}
@@ -182,10 +192,37 @@ private String bedrockAgentRuntimeSpanName(String operation) {
182192
return String.format("%s.%s", getBedrockAgentRuntimeSpanNamePrefix(), operation);
183193
}
184194

195+
private String secretsManagerSpanName(String operation) {
196+
return String.format("%s.%s", getSecretsManagerSpanNamePrefix(), operation);
197+
}
198+
199+
private boolean isValidRegex(String pattern) {
200+
try {
201+
Pattern.compile(pattern);
202+
return true;
203+
} catch (PatternSyntaxException e) {
204+
return false;
205+
}
206+
}
207+
185208
protected ThrowingConsumer<KeyValue> assertAttribute(String key, String value) {
186209
return (attribute) -> {
187210
assertThat(attribute.getKey()).isEqualTo(key);
188-
assertThat(attribute.getValue().getStringValue()).isEqualTo(value);
211+
var actualValue = attribute.getValue().getStringValue();
212+
213+
if (isValidRegex(value)) {
214+
System.out.println("ASSERTING REGEX: " + actualValue + "equivalent to " + value);
215+
assertThat(actualValue).matches(value);
216+
if (!actualValue.matches(value)) {
217+
System.out.println("ASSERTION FAILED between: " + actualValue + " and " + value);
218+
}
219+
} else {
220+
System.out.println("ASSERTING EXACT: " + actualValue + "equivalent to " + value);
221+
assertThat(actualValue).isEqualTo(value);
222+
if (!actualValue.equals(value)) {
223+
System.out.println("ASSERTION FAILED between: " + actualValue + " and " + value);
224+
}
225+
}
189226
};
190227
}
191228

@@ -413,13 +450,14 @@ private void assertAwsAttributes(
413450
.satisfiesOnlyOnce(assertAttribute(AppSignalsConstants.AWS_REMOTE_OPERATION, operation))
414451
.satisfiesOnlyOnce(assertAttribute(AppSignalsConstants.AWS_REMOTE_SERVICE, service))
415452
.satisfiesOnlyOnce(assertAttribute(AppSignalsConstants.AWS_SPAN_KIND, spanKind));
416-
if (type != null && identifier != null) {
453+
if (type != null && identifier != null && clouformationIdentifier != null) {
417454
assertions.satisfiesOnlyOnce(
418455
assertAttribute(AppSignalsConstants.AWS_REMOTE_RESOURCE_TYPE, type));
419456
assertions.satisfiesOnlyOnce(
420457
assertAttribute(AppSignalsConstants.AWS_REMOTE_RESOURCE_IDENTIFIER, identifier));
421458
assertions.satisfiesOnlyOnce(
422-
assertAttribute(AppSignalsConstants.AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER, clouformationIdentifier));
459+
assertAttribute(
460+
AppSignalsConstants.AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER, clouformationIdentifier));
423461
}
424462
}
425463

@@ -1995,7 +2033,8 @@ protected void doTestBedrockGuardrailId() {
19952033
var localOperation = "GET /bedrock/getguardrail";
19962034
String type = "AWS::Bedrock::Guardrail";
19972035
String identifier = "test-bedrock-guardrail";
1998-
String cloudformationIdentifier = "arn:aws:bedrock:us-east-1:000000000000:guardrail/test-bedrock-guardrail";
2036+
String cloudformationIdentifier =
2037+
"arn:aws:bedrock:us-east-1:000000000000:guardrail/test-bedrock-guardrail";
19992038
assertSpanClientAttributes(
20002039
traces,
20012040
bedrockSpanName("GetGuardrail"),
@@ -2015,7 +2054,8 @@ protected void doTestBedrockGuardrailId() {
20152054
assertAttribute(
20162055
SemanticConventionsConstants.AWS_GUARDRAIL_ID, "test-bedrock-guardrail"),
20172056
assertAttribute(
2018-
SemanticConventionsConstants.AWS_GUARDRAIL_ARN, "arn:aws:bedrock:us-east-1:000000000000:guardrail/test-bedrock-guardrail")));
2057+
SemanticConventionsConstants.AWS_GUARDRAIL_ARN,
2058+
"arn:aws:bedrock:us-east-1:000000000000:guardrail/test-bedrock-guardrail")));
20192059
assertMetricClientAttributes(
20202060
metrics,
20212061
AppSignalsConstants.LATENCY_METRIC,
@@ -2185,4 +2225,71 @@ protected void doTestBedrockAgentRuntimeKnowledgeBaseId() {
21852225
cloudformationIdentifier,
21862226
0.0);
21872227
}
2228+
2229+
protected void doTestSecretsManagerCreateSecret() throws Exception {
2230+
appClient.get("/secretsmanager/createsecret/test-secret-id").aggregate().join();
2231+
var traces = mockCollectorClient.getTraces();
2232+
var metrics = mockCollectorClient.getMetrics(
2233+
Set.of(
2234+
AppSignalsConstants.ERROR_METRIC,
2235+
AppSignalsConstants.FAULT_METRIC,
2236+
AppSignalsConstants.LATENCY_METRIC
2237+
)
2238+
);
2239+
var localService = getApplicationOtelServiceName();
2240+
var localOperation = "GET /secretsmanager/createsecret/:secretId";
2241+
var type = "AWS::SecretsManager::Secret";
2242+
var identifier = "test-secret-id-[A-Za-z0-9]{6}";
2243+
var cloudformationIdentifier = "arn:aws:secretsmanager:us-west-2:000000000000:secret:test-secret-id-[A-Za-z0-9]{6}";
2244+
2245+
assertSpanClientAttributes(
2246+
traces,
2247+
secretsManagerSpanName("CreateSecret"),
2248+
getSecretsManagerRpcServiceName(),
2249+
localService,
2250+
localOperation,
2251+
getSecretsManagerServiceName(),
2252+
"CreateSecret",
2253+
type,
2254+
identifier,
2255+
cloudformationIdentifier,
2256+
"localstack",
2257+
4566,
2258+
"http://localstack:4566",
2259+
200,
2260+
List.of(assertAttribute(SemanticConventionsConstants.AWS_SECRET_ARN, "arn:aws:secretsmanager:us-west-2:000000000000:secret:test-secret-id-[A-Za-z0-9]{6}")));
2261+
assertMetricClientAttributes(
2262+
metrics,
2263+
AppSignalsConstants.LATENCY_METRIC,
2264+
localService,
2265+
localOperation,
2266+
getSecretsManagerServiceName(),
2267+
"CreateSecret",
2268+
type,
2269+
identifier,
2270+
cloudformationIdentifier,
2271+
5000.0);
2272+
assertMetricClientAttributes(
2273+
metrics,
2274+
AppSignalsConstants.FAULT_METRIC,
2275+
localService,
2276+
localOperation,
2277+
getSecretsManagerServiceName(),
2278+
"CreateSecret",
2279+
type,
2280+
identifier,
2281+
cloudformationIdentifier,
2282+
0.0);
2283+
assertMetricClientAttributes(
2284+
metrics,
2285+
AppSignalsConstants.ERROR_METRIC,
2286+
localService,
2287+
localOperation,
2288+
getSecretsManagerServiceName(),
2289+
"CreateSecret",
2290+
type,
2291+
identifier,
2292+
cloudformationIdentifier,
2293+
0.0);
2294+
}
21882295
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v1/AwsSdkV1Test.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ protected String getBedrockAgentRuntimeSpanNamePrefix() {
7676
return "AWSBedrockAgentRuntime";
7777
}
7878

79+
@Override
80+
protected String getSecretsManagerSpanNamePrefix() {
81+
return "AWSSecretsManager";
82+
}
83+
7984
protected String getS3RpcServiceName() {
8085
return "Amazon S3";
8186
}
@@ -90,6 +95,11 @@ protected String getSqsRpcServiceName() {
9095
return "AmazonSQS";
9196
}
9297

98+
@Override
99+
protected String getSecretsManagerRpcServiceName() {
100+
return "AWSSecretsManager";
101+
}
102+
93103
protected String getKinesisRpcServiceName() {
94104
return "AmazonKinesis";
95105
}
@@ -235,4 +245,7 @@ void testBedrockAgentRuntimeAgentId() {
235245
void testBedrockAgentRuntimeKnowledgeBaseId() {
236246
doTestBedrockAgentRuntimeKnowledgeBaseId();
237247
}
248+
249+
@Test
250+
void testSecretsManagerCreateSecret() throws Exception { doTestSecretsManagerCreateSecret(); }
238251
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v2/AwsSdkV2Test.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ protected String getBedrockAgentRuntimeSpanNamePrefix() {
7575
return "BedrockAgentRuntime";
7676
}
7777

78+
@Override
79+
protected String getSecretsManagerSpanNamePrefix() { return "SecretsManager"; }
80+
7881
@Override
7982
protected String getS3RpcServiceName() {
8083
return "S3";
@@ -114,6 +117,9 @@ protected String getBedrockAgentRuntimeRpcServiceName() {
114117
return "BedrockAgentRuntime";
115118
}
116119

120+
@Override
121+
protected String getSecretsManagerRpcServiceName() { return "SecretsManager"; }
122+
117123
@Test
118124
void testS3CreateBucket() throws Exception {
119125
doTestS3CreateBucket();
@@ -240,4 +246,7 @@ void testBedrockAgentRuntimeAgentId() {
240246
// void testBedrockAgentRuntimeKnowledgeBaseId() {
241247
// doTestBedrockAgentRuntimeKnowledgeBaseId();
242248
// }
249+
250+
@Test
251+
void testSecretsManagerCreateSecret() throws Exception { doTestSecretsManagerCreateSecret(); }
243252
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/AppSignalsConstants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public class AppSignalsConstants {
3131
public static final String AWS_REMOTE_OPERATION = "aws.remote.operation";
3232
public static final String AWS_REMOTE_RESOURCE_TYPE = "aws.remote.resource.type";
3333
public static final String AWS_REMOTE_RESOURCE_IDENTIFIER = "aws.remote.resource.identifier";
34-
public static final String AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER = "aws.remote.resource.cfn.primary.identifier";
34+
public static final String AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER =
35+
"aws.remote.resource.cfn.primary.identifier";
3536
public static final String AWS_SPAN_KIND = "aws.span.kind";
3637
public static final String AWS_REMOTE_DB_USER = "aws.remote.db.user";
3738
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/SemanticConventionsConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public class SemanticConventionsConstants {
6464
public static final String AWS_GUARDRAIL_ID = "aws.bedrock.guardrail.id";
6565
public static final String AWS_GUARDRAIL_ARN = "aws.bedrock.guardrail.arn";
6666
public static final String GEN_AI_REQUEST_MODEL = "gen_ai.request.model";
67+
public static final String AWS_SECRET_ARN = "aws.secretsmanager.secret.arn";
6768

6869
// kafka
6970
public static final String MESSAGING_CLIENT_ID = "messaging.client_id";

appsignals-tests/images/aws-sdk/aws-sdk-v1/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dependencies {
3737
implementation("com.amazonaws:aws-java-sdk-bedrockagent")
3838
implementation("com.amazonaws:aws-java-sdk-bedrockruntime")
3939
implementation("com.amazonaws:aws-java-sdk-bedrockagentruntime")
40+
implementation("com.amazonaws:aws-java-sdk-secretsmanager")
4041
implementation("commons-logging:commons-logging")
4142
implementation("com.linecorp.armeria:armeria")
4243
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3")

appsignals-tests/images/aws-sdk/aws-sdk-v1/src/main/java/com/amazon/sampleapp/App.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,13 @@
5252
import com.amazonaws.services.s3.model.GetObjectRequest;
5353
import com.amazonaws.services.s3.model.PutObjectRequest;
5454
import com.amazonaws.services.s3.model.Region;
55+
import com.amazonaws.services.secretsmanager.model.CreateSecretRequest;
56+
import com.amazonaws.services.secretsmanager.model.DescribeSecretRequest;
5557
import com.amazonaws.services.sqs.AmazonSQSClient;
5658
import com.amazonaws.services.sqs.model.CreateQueueRequest;
5759
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
5860
import com.amazonaws.services.sqs.model.SendMessageRequest;
61+
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClient;
5962
import java.io.File;
6063
import java.io.IOException;
6164
import java.net.http.HttpClient;
@@ -122,6 +125,7 @@ public static void main(String[] args) throws IOException, InterruptedException
122125
setupSqs();
123126
setupKinesis();
124127
setupBedrock();
128+
setupSecretsManager();
125129

126130
// Add this log line so that we only start testing after all routes are configured.
127131
awaitInitialization();
@@ -631,4 +635,17 @@ private static void setupBedrock() {
631635
return "";
632636
});
633637
}
638+
639+
private static void setupSecretsManager() {
640+
var secretsManagerClient = AWSSecretsManagerClient.builder().withCredentials(CREDENTIALS_PROVIDER).withEndpointConfiguration(endpointConfiguration).build();
641+
642+
get (
643+
"/secretsmanager/createsecret/:secretId",
644+
(req, res) -> {
645+
var secretId = req.params(":secretId");
646+
var createSecretRequest = new CreateSecretRequest().withName(secretId);
647+
secretsManagerClient.createSecret(createSecretRequest);
648+
return "";
649+
});
650+
}
634651
}

appsignals-tests/images/aws-sdk/aws-sdk-v2/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dependencies {
3737
implementation("software.amazon.awssdk:bedrockagent")
3838
implementation("software.amazon.awssdk:bedrockruntime")
3939
implementation("software.amazon.awssdk:bedrockagentruntime")
40+
implementation("software.amazon.awssdk:secretsmanager")
4041
implementation("commons-logging:commons-logging")
4142
implementation("com.linecorp.armeria:armeria")
4243
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3")

appsignals-tests/images/aws-sdk/aws-sdk-v2/src/main/java/com/amazon/sampleapp/App.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
6666
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
6767
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
68+
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
69+
import software.amazon.awssdk.services.secretsmanager.model.CreateSecretRequest;
70+
import software.amazon.awssdk.services.secretsmanager.model.DescribeSecretRequest;
71+
import software.amazon.awssdk.services.secretsmanager.model.DescribeSecretResponse;
6872
import software.amazon.awssdk.services.sqs.SqsClient;
6973
import software.amazon.awssdk.services.sqs.model.CreateQueueRequest;
7074
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
@@ -119,6 +123,7 @@ public static void main(String[] args) throws IOException, InterruptedException
119123
setupSqs();
120124
setupKinesis();
121125
setupBedrock();
126+
setupSecretsManager();
122127
// Add this log line so that we only start testing after all routes are configured.
123128
awaitInitialization();
124129
logger.info("All routes initialized");
@@ -658,4 +663,17 @@ private static void setupBedrock() {
658663
return "";
659664
});
660665
}
666+
667+
private static void setupSecretsManager() {
668+
var secretsManagerClient = SecretsManagerClient.builder().endpointOverride(endpoint).credentialsProvider(CREDENTIALS_PROVIDER).build();
669+
670+
get(
671+
"/secretsmanager/createsecret/:secretId",
672+
(req, res) -> {
673+
var secretId = req.params(":secretId");
674+
var createSecretRequest = CreateSecretRequest.builder().name(secretId).build();
675+
secretsManagerClient.createSecret(createSecretRequest);
676+
return "";
677+
});
678+
}
661679
}

0 commit comments

Comments
 (0)