1919 AWS_REMOTE_RESOURCE_TYPE ,
2020 AWS_REMOTE_SERVICE ,
2121 AWS_SPAN_KIND ,
22- AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER
22+ AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER ,
23+ AWS_REMOTE_RESOURCE_ACCESS_KEY ,
24+ AWS_REMOTE_RESOURCE_ACCOUNT_ID ,
25+ AWS_REMOTE_RESOURCE_REGION
2326)
2427from opentelemetry .proto .common .v1 .common_pb2 import AnyValue , KeyValue
2528from opentelemetry .proto .metrics .v1 .metrics_pb2 import ExponentialHistogramDataPoint , Metric
3134
3235_AWS_SQS_QUEUE_URL : str = "aws.sqs.queue.url"
3336_AWS_SQS_QUEUE_NAME : str = "aws.sqs.queue.name"
37+ _AWS_KINESIS_STREAM_ARN : str = "aws.kinesis.stream.arn"
3438_AWS_KINESIS_STREAM_NAME : str = "aws.kinesis.stream.name"
3539_AWS_BEDROCK_AGENT_ID : str = "aws.bedrock.agent.id"
3640_AWS_BEDROCK_GUARDRAIL_ID : str = "aws.bedrock.guardrail.id"
4953_GEN_AI_RESPONSE_FINISH_REASONS : str = "gen_ai.response.finish_reasons"
5054_GEN_AI_USAGE_INPUT_TOKENS : str = 'gen_ai.usage.input_tokens'
5155_GEN_AI_USAGE_OUTPUT_TOKENS : str = 'gen_ai.usage.output_tokens'
56+ _AWS_DYNAMODB_TABLE_ARN : str = "aws.dynamodb.table.arn"
5257
5358# pylint: disable=too-many-public-methods
5459class AWSSDKTest (ContractTestBase ):
@@ -236,6 +241,30 @@ def test_dynamodb_put_item(self):
236241 span_name = "DynamoDB.PutItem" ,
237242 )
238243
244+ def test_dynamodb_describe_table (self ):
245+ self .do_test_requests (
246+ "ddb/describe/some-table" ,
247+ "GET" ,
248+ 200 ,
249+ 0 ,
250+ 0 ,
251+ local_operation = "GET /ddb" ,
252+ remote_service = "AWS::DynamoDB" ,
253+ remote_operation = "DescribeTable" ,
254+ remote_resource_type = "AWS::DynamoDB::Table" ,
255+ remote_resource_identifier = "put_test_table" ,
256+ cloudformation_primary_identifier = "put_test_table" ,
257+ remote_resource_account_id = "000000000000" ,
258+ remote_resource_region = "us-west-2" ,
259+ request_specific_attributes = {
260+ SpanAttributes .AWS_DYNAMODB_TABLE_NAMES : ["put_test_table" ],
261+ },
262+ response_specific_attributes = {
263+ _AWS_DYNAMODB_TABLE_ARN : r"arn:aws:dynamodb:us-west-2:000000000000:table/put_test_table" ,
264+ },
265+ span_name = "DynamoDB.DescribeTable" ,
266+ )
267+
239268 def test_dynamodb_error (self ):
240269 self .do_test_requests (
241270 "ddb/error" ,
@@ -397,6 +426,28 @@ def test_kinesis_put_record(self):
397426 },
398427 span_name = "Kinesis.PutRecord" ,
399428 )
429+
430+ def test_kinesis_describe_stream (self ):
431+ self .do_test_requests (
432+ "kinesis/describe/my-stream" ,
433+ "GET" ,
434+ 200 ,
435+ 0 ,
436+ 0 ,
437+ local_operation = "GET /kinesis" ,
438+ remote_service = "AWS::Kinesis" ,
439+ remote_operation = "DescribeStream" ,
440+ remote_resource_type = "AWS::Kinesis::Stream" ,
441+ remote_resource_identifier = "test_stream" ,
442+ cloudformation_primary_identifier = "test_stream" ,
443+ remote_resource_account_id = "000000000000" ,
444+ remote_resource_region = "us-west-2" ,
445+ request_specific_attributes = {
446+ _AWS_KINESIS_STREAM_NAME : "test_stream" ,
447+ _AWS_KINESIS_STREAM_ARN : "arn:aws:kinesis:us-west-2:000000000000:stream/test_stream"
448+ },
449+ span_name = "Kinesis.DescribeStream" ,
450+ )
400451
401452 def test_kinesis_error (self ):
402453 self .do_test_requests (
@@ -1034,6 +1085,27 @@ def test_lambda_error(self):
10341085 span_name = "Lambda.GetEventSourceMapping" ,
10351086 )
10361087
1088+ def test_cross_account (self ):
1089+ self .do_test_requests (
1090+ "cross-account/createbucket/account_b" ,
1091+ "GET" ,
1092+ 200 ,
1093+ 0 ,
1094+ 0 ,
1095+ local_operation = "GET /cross-account" ,
1096+ remote_service = "AWS::S3" ,
1097+ remote_operation = "CreateBucket" ,
1098+ remote_resource_type = "AWS::S3::Bucket" ,
1099+ remote_resource_identifier = "cross-account-bucket" ,
1100+ cloudformation_primary_identifier = "cross-account-bucket" ,
1101+ request_specific_attributes = {
1102+ SpanAttributes .AWS_S3_BUCKET : "cross-account-bucket" ,
1103+ },
1104+ remote_resource_access_key = "account_b_access_key_id" ,
1105+ remote_resource_region = "eu-central-1" ,
1106+ span_name = "S3.CreateBucket" ,
1107+ )
1108+
10371109 #TODO: Need to add test_lambda_get_event_source_mapping once workaround is figured out for storing UUID between tests
10381110
10391111 @override
@@ -1062,6 +1134,9 @@ def _assert_aws_span_attributes(self, resource_scope_spans: List[ResourceScopeSp
10621134 kwargs .get ("remote_resource_type" , "None" ),
10631135 kwargs .get ("remote_resource_identifier" , "None" ),
10641136 kwargs .get ("cloudformation_primary_identifier" , "None" ),
1137+ kwargs .get ("remote_resource_account_id" , "None" ),
1138+ kwargs .get ("remote_resource_region" , "None" ),
1139+ kwargs .get ("remote_resource_account_access_key" , "None" ),
10651140 )
10661141
10671142 def _assert_aws_attributes (
@@ -1073,7 +1148,10 @@ def _assert_aws_attributes(
10731148 span_kind : str ,
10741149 remote_resource_type : str ,
10751150 remote_resource_identifier : str ,
1076- cloudformation_primary_identifier : str
1151+ cloudformation_primary_identifier : str ,
1152+ remote_resource_account_id : str ,
1153+ remote_resource_region : str ,
1154+ remote_resource_account_access_key : str
10771155 ) -> None :
10781156 attributes_dict : Dict [str , AnyValue ] = self ._get_attributes_dict (attributes_list )
10791157 self ._assert_str_attribute (attributes_dict , AWS_LOCAL_SERVICE , self .get_application_otel_service_name ())
@@ -1086,7 +1164,16 @@ def _assert_aws_attributes(
10861164 self ._assert_attribute (attributes_dict , AWS_REMOTE_RESOURCE_IDENTIFIER , remote_resource_identifier )
10871165 if cloudformation_primary_identifier != "None" :
10881166 self ._assert_attribute (attributes_dict , AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER , cloudformation_primary_identifier )
1089-
1167+ if remote_resource_account_id != "None" :
1168+ assert remote_resource_identifier != "None"
1169+ self ._assert_str_attribute (attributes_dict , AWS_REMOTE_RESOURCE_ACCOUNT_ID , remote_resource_account_id )
1170+ self .assertIsNone (attributes_dict .get (AWS_REMOTE_RESOURCE_ACCESS_KEY ))
1171+ if remote_resource_account_access_key != "None" :
1172+ assert remote_resource_identifier != "None"
1173+ self ._assert_str_attribute (attributes_dict , AWS_REMOTE_RESOURCE_ACCESS_KEY , remote_resource_account_access_key )
1174+ self .assertIsNone (attributes_dict .get (AWS_REMOTE_RESOURCE_ACCOUNT_ID ))
1175+ if remote_resource_region != "None" :
1176+ self ._assert_str_attribute (attributes_dict , AWS_REMOTE_RESOURCE_REGION , remote_resource_region )
10901177 self ._assert_str_attribute (attributes_dict , AWS_SPAN_KIND , span_kind )
10911178
10921179 @override
@@ -1187,10 +1274,23 @@ def _assert_metric_attributes(
11871274 self ._assert_attribute (attribute_dict , AWS_SPAN_KIND , kwargs .get ("dependency_metric_span_kind" ) or "CLIENT" )
11881275 remote_resource_type = kwargs .get ("remote_resource_type" , "None" )
11891276 remote_resource_identifier = kwargs .get ("remote_resource_identifier" , "None" )
1277+ remote_resource_account_id = kwargs .get ("remote_resource_account_id" , "None" )
1278+ remote_resource_account_access_key = kwargs .get ("remote_resource_account_access_key" , "None" )
1279+ remote_resource_region = kwargs .get ("remote_resource_region" , "None" )
11901280 if remote_resource_type != "None" :
11911281 self ._assert_attribute (attribute_dict , AWS_REMOTE_RESOURCE_TYPE , remote_resource_type )
11921282 if remote_resource_identifier != "None" :
11931283 self ._assert_attribute (attribute_dict , AWS_REMOTE_RESOURCE_IDENTIFIER , remote_resource_identifier )
1284+ if remote_resource_account_id != "None" :
1285+ assert remote_resource_identifier != "None"
1286+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_ACCOUNT_ID , remote_resource_account_id )
1287+ self .assertIsNone (attribute_dict .get (AWS_REMOTE_RESOURCE_ACCESS_KEY ))
1288+ if remote_resource_account_access_key != "None" :
1289+ assert remote_resource_identifier != "None"
1290+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_ACCESS_KEY , remote_resource_account_access_key )
1291+ self .assertIsNone (attribute_dict .get (AWS_REMOTE_RESOURCE_ACCOUNT_ID ))
1292+ if remote_resource_region != "None" :
1293+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_REGION , remote_resource_region )
11941294 self .check_sum (metric_name , dependency_dp .sum , expected_sum )
11951295
11961296 attribute_dict : Dict [str , AnyValue ] = self ._get_attributes_dict (service_dp .attributes )
@@ -1212,10 +1312,23 @@ def _assert_metric_attributes(
12121312 self ._assert_str_attribute (attribute_dict , AWS_SPAN_KIND , kwargs .get ("dependency_metric_span_kind" ) or "CLIENT" )
12131313 remote_resource_type = kwargs .get ("remote_resource_type" , "None" )
12141314 remote_resource_identifier = kwargs .get ("remote_resource_identifier" , "None" )
1315+ remote_resource_account_id = kwargs .get ("remote_resource_account_id" , "None" )
1316+ remote_resource_account_access_key = kwargs .get ("remote_resource_account_access_key" , "None" )
1317+ remote_resource_region = kwargs .get ("remote_resource_region" , "None" )
12151318 if remote_resource_type != "None" :
12161319 self ._assert_attribute (attribute_dict , AWS_REMOTE_RESOURCE_TYPE , remote_resource_type )
12171320 if remote_resource_identifier != "None" :
12181321 self ._assert_attribute (attribute_dict , AWS_REMOTE_RESOURCE_IDENTIFIER , remote_resource_identifier )
1322+ if remote_resource_account_id != "None" :
1323+ assert remote_resource_identifier != "None"
1324+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_ACCOUNT_ID , remote_resource_account_id )
1325+ self .assertIsNone (attribute_dict .get (AWS_REMOTE_RESOURCE_ACCESS_KEY ))
1326+ if remote_resource_account_access_key != "None" :
1327+ assert remote_resource_identifier != "None"
1328+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_ACCESS_KEY , remote_resource_account_access_key )
1329+ self .assertIsNone (attribute_dict .get (AWS_REMOTE_RESOURCE_ACCOUNT_ID ))
1330+ if remote_resource_region != "None" :
1331+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_REGION , remote_resource_region )
12191332 self .check_sum (metric_name , dependency_dp .sum , expected_sum )
12201333
12211334 attribute_dict_service : Dict [str , AnyValue ] = self ._get_attributes_dict (service_dp .attributes )
0 commit comments