2323import java .util .List ;
2424import java .util .Map ;
2525import java .util .Set ;
26+
2627import org .assertj .core .api .ThrowingConsumer ;
2728import org .junit .jupiter .api .AfterAll ;
2829import org .junit .jupiter .api .BeforeAll ;
@@ -42,7 +43,8 @@ public abstract class AwsSdkBaseTest extends ContractTestBase {
4243 LocalStackContainer .Service .S3 ,
4344 LocalStackContainer .Service .DYNAMODB ,
4445 LocalStackContainer .Service .SQS ,
45- LocalStackContainer .Service .KINESIS )
46+ LocalStackContainer .Service .KINESIS ,
47+ LocalStackContainer .Service .SECRETSMANAGER )
4648 .withEnv ("DEFAULT_REGION" , "us-west-2" )
4749 .withNetwork (network )
4850 .withEnv ("LOCALSTACK_HOST" , "127.0.0.1" )
@@ -102,6 +104,8 @@ protected String getApplicationWaitPattern() {
102104
103105 protected abstract String getBedrockAgentRuntimeSpanNamePrefix ();
104106
107+ protected abstract String getSecretsManagerSpanNamePrefix ();
108+
105109 protected abstract String getS3RpcServiceName ();
106110
107111 protected abstract String getDynamoDbRpcServiceName ();
@@ -118,6 +122,8 @@ protected String getApplicationWaitPattern() {
118122
119123 protected abstract String getBedrockAgentRuntimeRpcServiceName ();
120124
125+ protected abstract String getSecretsManagerRpcServiceName ();
126+
121127 private String getS3ServiceName () {
122128 return "AWS::S3" ;
123129 }
@@ -150,6 +156,10 @@ private String getBedrockRuntimeServiceName() {
150156 return "AWS::BedrockRuntime" ;
151157 }
152158
159+ private String getSecretsManagerServiceName () {
160+ return "AWS::SecretsManager" ;
161+ }
162+
153163 private String s3SpanName (String operation ) {
154164 return String .format ("%s.%s" , getS3SpanNamePrefix (), operation );
155165 }
@@ -182,10 +192,23 @@ 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+
185199 protected ThrowingConsumer <KeyValue > assertAttribute (String key , String value ) {
186200 return (attribute ) -> {
187- assertThat (attribute .getKey ()).isEqualTo (key );
188- assertThat (attribute .getValue ().getStringValue ()).isEqualTo (value );
201+ var actualKey = attribute .getKey ();
202+ var actualValue = attribute .getValue ().getStringValue ();
203+
204+ assertThat (actualKey ).isEqualTo (key );
205+
206+ // We only want to Regex Pattern Match on the Secret Id and Secret Arn
207+ if (actualValue .contains ("secret-id" )) {
208+ assertThat (actualValue ).matches (value );
209+ } else {
210+ assertThat (actualValue ).isEqualTo (value );
211+ }
189212 };
190213 }
191214
@@ -413,7 +436,7 @@ private void assertAwsAttributes(
413436 .satisfiesOnlyOnce (assertAttribute (AppSignalsConstants .AWS_REMOTE_OPERATION , operation ))
414437 .satisfiesOnlyOnce (assertAttribute (AppSignalsConstants .AWS_REMOTE_SERVICE , service ))
415438 .satisfiesOnlyOnce (assertAttribute (AppSignalsConstants .AWS_SPAN_KIND , spanKind ));
416- if (type != null && identifier != null ) {
439+ if (type != null && identifier != null && clouformationIdentifier != null ) {
417440 assertions .satisfiesOnlyOnce (
418441 assertAttribute (AppSignalsConstants .AWS_REMOTE_RESOURCE_TYPE , type ));
419442 assertions .satisfiesOnlyOnce (
@@ -2577,4 +2600,198 @@ protected void doTestBedrockAgentRuntimeKnowledgeBaseId() {
25772600 cloudformationIdentifier ,
25782601 0.0 );
25792602 }
2603+
2604+ protected void doTestSecretsManagerDescribeSecret () throws Exception {
2605+ appClient .get ("/secretsmanager/describesecret/test-secret-id" ).aggregate ().join ();
2606+ var traces = mockCollectorClient .getTraces ();
2607+ var metrics =
2608+ mockCollectorClient .getMetrics (
2609+ Set .of (
2610+ AppSignalsConstants .ERROR_METRIC ,
2611+ AppSignalsConstants .FAULT_METRIC ,
2612+ AppSignalsConstants .LATENCY_METRIC ));
2613+ var localService = getApplicationOtelServiceName ();
2614+ var localOperation = "GET /secretsmanager/describesecret/:secretId" ;
2615+ var type = "AWS::SecretsManager::Secret" ;
2616+ var identifier = "test-secret-id-[A-Za-z0-9]{6}" ;
2617+ var cloudformationIdentifier =
2618+ "arn:aws:secretsmanager:us-west-2:000000000000:secret:test-secret-id-[A-Za-z0-9]{6}" ;
2619+ assertSpanClientAttributes (
2620+ traces ,
2621+ secretsManagerSpanName ("DescribeSecret" ),
2622+ getSecretsManagerRpcServiceName (),
2623+ localService ,
2624+ localOperation ,
2625+ getSecretsManagerServiceName (),
2626+ "DescribeSecret" ,
2627+ type ,
2628+ identifier ,
2629+ cloudformationIdentifier ,
2630+ "localstack" ,
2631+ 4566 ,
2632+ "http://localstack:4566" ,
2633+ 200 ,
2634+ List .of (
2635+ assertAttribute (
2636+ SemanticConventionsConstants .AWS_SECRET_ARN ,
2637+ "arn:aws:secretsmanager:us-west-2:000000000000:secret:test-secret-id-[A-Za-z0-9]{6}" )));
2638+ assertMetricClientAttributes (
2639+ metrics ,
2640+ AppSignalsConstants .LATENCY_METRIC ,
2641+ localService ,
2642+ localOperation ,
2643+ getSecretsManagerServiceName (),
2644+ "DescribeSecret" ,
2645+ type ,
2646+ identifier ,
2647+ cloudformationIdentifier ,
2648+ 5000.0 );
2649+ assertMetricClientAttributes (
2650+ metrics ,
2651+ AppSignalsConstants .FAULT_METRIC ,
2652+ localService ,
2653+ localOperation ,
2654+ getSecretsManagerServiceName (),
2655+ "DescribeSecret" ,
2656+ type ,
2657+ identifier ,
2658+ cloudformationIdentifier ,
2659+ 0.0 );
2660+ assertMetricClientAttributes (
2661+ metrics ,
2662+ AppSignalsConstants .ERROR_METRIC ,
2663+ localService ,
2664+ localOperation ,
2665+ getSecretsManagerServiceName (),
2666+ "DescribeSecret" ,
2667+ type ,
2668+ identifier ,
2669+ cloudformationIdentifier ,
2670+ 0.0 );
2671+ }
2672+
2673+ protected void doTestSecretsManagerError () throws Exception {
2674+ appClient .get ("/secretsmanager/error" ).aggregate ().join ();
2675+ var traces = mockCollectorClient .getTraces ();
2676+ var metrics =
2677+ mockCollectorClient .getMetrics (
2678+ Set .of (
2679+ AppSignalsConstants .ERROR_METRIC ,
2680+ AppSignalsConstants .FAULT_METRIC ,
2681+ AppSignalsConstants .LATENCY_METRIC ));
2682+ var localService = getApplicationOtelServiceName ();
2683+ var localOperation = "GET /secretsmanager/error" ;
2684+ assertSpanClientAttributes (
2685+ traces ,
2686+ secretsManagerSpanName ("DescribeSecret" ),
2687+ getSecretsManagerRpcServiceName (),
2688+ localService ,
2689+ localOperation ,
2690+ getSecretsManagerServiceName (),
2691+ "DescribeSecret" ,
2692+ null ,
2693+ null ,
2694+ null ,
2695+ "error.test" ,
2696+ 8080 ,
2697+ "http://error.test:8080" ,
2698+ 400 ,
2699+ List .of ());
2700+ assertMetricClientAttributes (
2701+ metrics ,
2702+ AppSignalsConstants .LATENCY_METRIC ,
2703+ localService ,
2704+ localOperation ,
2705+ getSecretsManagerServiceName (),
2706+ "DescribeSecret" ,
2707+ null ,
2708+ null ,
2709+ null ,
2710+ 5000.0 );
2711+ assertMetricClientAttributes (
2712+ metrics ,
2713+ AppSignalsConstants .FAULT_METRIC ,
2714+ localService ,
2715+ localOperation ,
2716+ getSecretsManagerServiceName (),
2717+ "DescribeSecret" ,
2718+ null ,
2719+ null ,
2720+ null ,
2721+ 0.0 );
2722+ assertMetricClientAttributes (
2723+ metrics ,
2724+ AppSignalsConstants .ERROR_METRIC ,
2725+ localService ,
2726+ localOperation ,
2727+ getSecretsManagerServiceName (),
2728+ "DescribeSecret" ,
2729+ null ,
2730+ null ,
2731+ null ,
2732+ 1.0 );
2733+ }
2734+
2735+ protected void doTestSecretsManagerFault () throws Exception {
2736+ appClient .get ("/secretsmanager/fault" ).aggregate ().join ();
2737+ var traces = mockCollectorClient .getTraces ();
2738+ var metrics =
2739+ mockCollectorClient .getMetrics (
2740+ Set .of (
2741+ AppSignalsConstants .ERROR_METRIC ,
2742+ AppSignalsConstants .FAULT_METRIC ,
2743+ AppSignalsConstants .LATENCY_METRIC ));
2744+
2745+ var localService = getApplicationOtelServiceName ();
2746+ var localOperation = "GET /secretsmanager/fault" ;
2747+ assertSpanClientAttributes (
2748+ traces ,
2749+ secretsManagerSpanName ("DescribeSecret" ),
2750+ getSecretsManagerRpcServiceName (),
2751+ localService ,
2752+ localOperation ,
2753+ getSecretsManagerServiceName (),
2754+ "DescribeSecret" ,
2755+ null ,
2756+ null ,
2757+ null ,
2758+ "fault.test" ,
2759+ 8080 ,
2760+ "http://fault.test:8080" ,
2761+ 500 ,
2762+ List .of ());
2763+ assertMetricClientAttributes (
2764+ metrics ,
2765+ AppSignalsConstants .LATENCY_METRIC ,
2766+ localService ,
2767+ localOperation ,
2768+ getSecretsManagerServiceName (),
2769+ "DescribeSecret" ,
2770+ null ,
2771+ null ,
2772+ null ,
2773+ 5000.0 );
2774+ assertMetricClientAttributes (
2775+ metrics ,
2776+ AppSignalsConstants .FAULT_METRIC ,
2777+ localService ,
2778+ localOperation ,
2779+ getSecretsManagerServiceName (),
2780+ "DescribeSecret" ,
2781+ null ,
2782+ null ,
2783+ null ,
2784+ 1.0 );
2785+ assertMetricClientAttributes (
2786+ metrics ,
2787+ AppSignalsConstants .ERROR_METRIC ,
2788+ localService ,
2789+ localOperation ,
2790+ getSecretsManagerServiceName (),
2791+ "DescribeSecret" ,
2792+ null ,
2793+ null ,
2794+ null ,
2795+ 0.0 );
2796+ }
25802797}
0 commit comments