Skip to content

Commit 40b6ad5

Browse files
authored
fix: SQS instrumentation could cause InvalidOperationException (#2645) (#2646)
1 parent 9efd346 commit 40b6ad5

File tree

3 files changed

+40
-31
lines changed

3 files changed

+40
-31
lines changed

src/Agent/NewRelic/Agent/Extensions/Providers/Wrapper/AwsSdk/SQSRequestHandler.cs

+31-30
Original file line numberDiff line numberDiff line change
@@ -48,49 +48,50 @@ public static AfterWrappedMethodDelegate HandleSQSRequest(InstrumentedMethodCall
4848
switch (action)
4949
{
5050
case MessageBrokerAction.Produce when requestType == "SendMessageRequest":
51-
{
52-
if (request.MessageAttributes == null)
5351
{
54-
agent.Logger.Debug("AwsSdkPipelineWrapper: requestContext.OriginalRequest.MessageAttributes is null, unable to insert distributed trace headers.");
55-
}
56-
else
57-
{
58-
SqsHelper.InsertDistributedTraceHeaders(transaction, request, dtHeaders.Count);
59-
}
52+
if (request.MessageAttributes == null)
53+
{
54+
agent.Logger.Debug("AwsSdkPipelineWrapper: requestContext.OriginalRequest.MessageAttributes is null, unable to insert distributed trace headers.");
55+
}
56+
else
57+
{
58+
SqsHelper.InsertDistributedTraceHeaders(transaction, request, dtHeaders.Count);
59+
}
6060

61-
break;
62-
}
61+
break;
62+
}
6363
case MessageBrokerAction.Produce:
64-
{
65-
if (requestType == "SendMessageBatchRequest")
6664
{
67-
// loop through each message in the batch and insert distributed trace headers
68-
foreach (var message in request.Entries)
65+
if (requestType == "SendMessageBatchRequest")
6966
{
70-
if (message.MessageAttributes == null)
67+
// loop through each message in the batch and insert distributed trace headers
68+
foreach (var message in request.Entries)
7169
{
72-
agent.Logger.Debug("AwsSdkPipelineWrapper: requestContext.OriginalRequest.Entries.MessageAttributes is null, unable to insert distributed trace headers.");
73-
}
74-
else
75-
{
76-
SqsHelper.InsertDistributedTraceHeaders(transaction, message, dtHeaders.Count);
70+
if (message.MessageAttributes == null)
71+
{
72+
agent.Logger.Debug("AwsSdkPipelineWrapper: requestContext.OriginalRequest.Entries.MessageAttributes is null, unable to insert distributed trace headers.");
73+
}
74+
else
75+
{
76+
SqsHelper.InsertDistributedTraceHeaders(transaction, message, dtHeaders.Count);
77+
}
7778
}
7879
}
79-
}
8080

81-
break;
82-
}
81+
break;
82+
}
8383

8484
// modify the request to ask for DT headers in the response message attributes.
8585
case MessageBrokerAction.Consume:
86-
{
87-
if (request.MessageAttributeNames == null)
88-
request.MessageAttributeNames = new List<string>();
86+
{
87+
// create a new list or clone the existing one so we don't modify the original list
88+
request.MessageAttributeNames = request.MessageAttributeNames == null ? new List<string>() : new List<string>(request.MessageAttributeNames);
8989

90-
foreach (var header in dtHeaders)
91-
request.MessageAttributeNames.Add(header);
92-
break;
93-
}
90+
foreach (var header in dtHeaders)
91+
request.MessageAttributeNames.Add(header);
92+
93+
break;
94+
}
9495
}
9596

9697
return isAsync ?

tests/Agent/IntegrationTests/ContainerApplications/AwsSdkTestApp/AwsSdkExerciser/AwsSdkExerciser.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,19 @@ public async Task<IEnumerable<Message>> SQS_ReceiveMessageAsync(int maxMessagesT
104104
throw new InvalidOperationException("Queue URL is not set. Call SQS_Initialize or SQS_SetQueueUrl first.");
105105
}
106106

107+
List<string> messageAttributeNames = ["All"];
108+
107109
var response = await _amazonSqsClient.ReceiveMessageAsync(new ReceiveMessageRequest
108110
{
109111
QueueUrl = _sqsQueueUrl,
110112
MaxNumberOfMessages = maxMessagesToReceive,
111-
MessageAttributeNames = ["All"]
113+
MessageAttributeNames = messageAttributeNames
112114
});
113115

116+
117+
if (messageAttributeNames.Count != 1)
118+
throw new Exception("Expected messageAttributeNames to have a single element");
119+
114120
foreach (var message in response.Messages)
115121
{
116122
Console.WriteLine($"Message: {message.Body}");

tests/Agent/IntegrationTests/ContainerIntegrationTests/Fixtures/AwsSdkContainerTestFixtures.cs

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public void ExerciseSQS_SendReceivePurge(string queueName)
4141
{
4242
var address = $"http://localhost:{Port}/awssdk";
4343

44+
// The exerciser will return a 500 error if the `RequestMessage.MessageAttributeNames` collection is modified by our instrumentation.
45+
// See https://github.com/newrelic/newrelic-dotnet-agent/pull/2646
4446
GetAndAssertStatusCode($"{address}/SQS_SendReceivePurge?queueName={queueName}", System.Net.HttpStatusCode.OK);
4547
}
4648

0 commit comments

Comments
 (0)