1
1
// Copyright 2020 New Relic, Inc. All rights reserved.
2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
- using System . Collections . Concurrent ;
5
- using System ;
6
4
using System . Collections . Generic ;
7
- using System . Threading . Tasks ;
8
5
using NewRelic . Agent . Api ;
9
- using NewRelic . Agent . Extensions . AwsSdk ;
10
6
using NewRelic . Agent . Extensions . Providers . Wrapper ;
11
- using NewRelic . Reflection ;
12
- using System . Linq ;
13
7
14
8
namespace NewRelic . Providers . Wrapper . AwsSdk
15
9
{
@@ -18,9 +12,7 @@ public class AwsSdkPipelineWrapper : IWrapper
18
12
public bool IsTransactionRequired => true ;
19
13
20
14
private const string WrapperName = "AwsSdkPipelineWrapper" ;
21
- private static readonly ConcurrentDictionary < Type , Func < object , object > > _getRequestResponseFromGeneric = new ( ) ;
22
15
private static HashSet < string > _unsupportedRequestTypes = new ( ) ;
23
- private static HashSet < string > _unsupportedSQSRequestTypes = new ( ) ;
24
16
25
17
public CanWrapResponse CanWrap ( InstrumentedMethodInfo methodInfo )
26
18
{
@@ -60,121 +52,13 @@ public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall ins
60
52
61
53
if ( requestType . StartsWith ( "Amazon.SQS" ) )
62
54
{
63
- return HandleSQSRequest ( instrumentedMethodCall , agent , transaction , request , isAsync , executionContext ) ;
55
+ return SQSRequestHandler . HandleSQSRequest ( instrumentedMethodCall , agent , transaction , request , isAsync , executionContext ) ;
64
56
}
65
57
66
58
if ( _unsupportedRequestTypes . Add ( requestType ) ) // log once per unsupported request type
67
59
agent . Logger . Debug ( $ "AwsSdkPipelineWrapper: Unsupported request type: { requestType } . Returning NoOp delegate.") ;
68
60
69
61
return Delegates . NoOp ;
70
62
}
71
-
72
- private static AfterWrappedMethodDelegate HandleSQSRequest ( InstrumentedMethodCall instrumentedMethodCall , IAgent agent ,
73
- ITransaction transaction , dynamic request , bool isAsync , dynamic executionContext )
74
- {
75
- var requestType = request . GetType ( ) . Name ;
76
-
77
- MessageBrokerAction action ;
78
- switch ( requestType )
79
- {
80
- case "SendMessageRequest" :
81
- case "SendMessageBatchRequest" :
82
- action = MessageBrokerAction . Produce ;
83
- break ;
84
- case "ReceiveMessageRequest" :
85
- action = MessageBrokerAction . Consume ;
86
- break ;
87
- case "PurgeQueueRequest" :
88
- action = MessageBrokerAction . Purge ;
89
- break ;
90
- default :
91
- if ( _unsupportedSQSRequestTypes . Add ( requestType ) ) // log once per unsupported request type
92
- agent . Logger . Debug ( $ "AwsSdkPipelineWrapper: SQS Request type { requestType } is not supported. Returning NoOp delegate.") ;
93
-
94
- return Delegates . NoOp ;
95
- }
96
-
97
- var dtHeaders = agent . GetConfiguredDTHeaders ( ) ;
98
-
99
- string requestQueueUrl = request . QueueUrl ;
100
- ISegment segment = SqsHelper . GenerateSegment ( transaction , instrumentedMethodCall . MethodCall , requestQueueUrl , action ) ;
101
- if ( action == MessageBrokerAction . Produce )
102
- {
103
- if ( requestType == "SendMessageRequest" )
104
- {
105
- if ( request . MessageAttributes == null )
106
- {
107
- agent . Logger . Debug ( "AwsSdkPipelineWrapper: requestContext.OriginalRequest.MessageAttributes is null, unable to insert distributed trace headers." ) ;
108
- }
109
- else
110
- {
111
- SqsHelper . InsertDistributedTraceHeaders ( transaction , request , dtHeaders . Count ) ;
112
- }
113
- }
114
- else if ( requestType == "SendMessageBatchRequest" )
115
- {
116
- // loop through each message in the batch and insert distributed trace headers
117
- foreach ( var message in request . Entries )
118
- {
119
- if ( message . MessageAttributes == null )
120
- {
121
- agent . Logger . Debug ( "AwsSdkPipelineWrapper: requestContext.OriginalRequest.Entries.MessageAttributes is null, unable to insert distributed trace headers." ) ;
122
- }
123
- else
124
- {
125
- SqsHelper . InsertDistributedTraceHeaders ( transaction , message , dtHeaders . Count ) ;
126
- }
127
- }
128
- }
129
- }
130
-
131
- // modify the request to ask for DT headers in the response message attributes.
132
- if ( action == MessageBrokerAction . Consume )
133
- {
134
- if ( request . MessageAttributeNames == null )
135
- request . MessageAttributeNames = new List < string > ( ) ;
136
-
137
- foreach ( var header in dtHeaders )
138
- request . MessageAttributeNames . Add ( header ) ;
139
- }
140
-
141
- if ( isAsync )
142
- {
143
- return Delegates . GetAsyncDelegateFor < Task > ( agent , segment , true , ProcessResponse , TaskContinuationOptions . ExecuteSynchronously ) ;
144
-
145
- void ProcessResponse ( Task responseTask )
146
- {
147
- if ( ! ValidTaskResponse ( responseTask ) || ( segment == null ) || action != MessageBrokerAction . Consume )
148
- return ;
149
-
150
- // taskResult is a ReceiveMessageResponse
151
- var taskResultGetter = _getRequestResponseFromGeneric . GetOrAdd ( responseTask . GetType ( ) , t => VisibilityBypasser . Instance . GeneratePropertyAccessor < object > ( t , "Result" ) ) ;
152
- dynamic receiveMessageResponse = taskResultGetter ( responseTask ) ;
153
-
154
- // accept distributed trace headers from the first message in the response
155
- SqsHelper . AcceptDistributedTraceHeaders ( transaction , receiveMessageResponse . Messages [ 0 ] . MessageAttributes ) ;
156
- }
157
- }
158
-
159
- return Delegates . GetDelegateFor (
160
- onComplete : segment . End ,
161
- onSuccess : ( ) =>
162
- {
163
- if ( action != MessageBrokerAction . Consume )
164
- return ;
165
-
166
- var ec = executionContext ;
167
- var response = ec . ResponseContext . Response ; // response is a ReceiveMessageResponse
168
-
169
- // accept distributed trace headers from the first message in the response
170
- SqsHelper . AcceptDistributedTraceHeaders ( transaction , response . Messages [ 0 ] . MessageAttributes ) ;
171
- }
172
- ) ;
173
- }
174
-
175
- private static bool ValidTaskResponse ( Task response )
176
- {
177
- return response ? . Status == TaskStatus . RanToCompletion ;
178
- }
179
63
}
180
64
}
0 commit comments