1 // <copyright>
2 //   Copyright (c) Microsoft Corporation.  All rights reserved.
3 // </copyright>
4 
5 namespace System.ServiceModel.Diagnostics
6 {
7     using System;
8     using System.Diagnostics;
9     using System.Runtime;
10     using System.Runtime.Diagnostics;
11     using System.Security;
12     using System.Security.Permissions;
13     using System.ServiceModel.Channels;
14     using System.Xml;
15 
16     internal static class EventTraceActivityHelper
17     {
TryAttachActivity(Message message, EventTraceActivity activity)18         public static bool TryAttachActivity(Message message, EventTraceActivity activity)
19         {
20             if (FxTrace.Trace.IsEnd2EndActivityTracingEnabled && (message != null) && (activity != null))
21             {
22                 if (!message.Properties.ContainsKey(EventTraceActivity.Name))
23                 {
24                     message.Properties.Add(EventTraceActivity.Name, activity);
25                     return true;
26                 }
27             }
28 
29             return false;
30         }
31 
TryExtractActivity(Message message)32         public static EventTraceActivity TryExtractActivity(Message message)
33         {
34             return TryExtractActivity(message, false);
35         }
36 
TryExtractActivity(Message message, bool createIfNotExist)37         public static EventTraceActivity TryExtractActivity(Message message, bool createIfNotExist)
38         {
39             EventTraceActivity eventTraceActivity = null;
40 
41             if (message != null && message.State != MessageState.Closed)
42             {
43                 object property;
44                 if (message.Properties.TryGetValue(EventTraceActivity.Name, out property))
45                 {
46                     eventTraceActivity = property as EventTraceActivity;
47                 }
48 
49                 if (eventTraceActivity == null)
50                 {
51                     Guid activityId;
52                     if (GetMessageId(message, out activityId))
53                     {
54                         eventTraceActivity = new EventTraceActivity(activityId);
55                     }
56                     else
57                     {
58                         UniqueId uid = message.Headers.RelatesTo;
59                         if (uid != null)
60                         {
61                             if (uid.TryGetGuid(out activityId))
62                             {
63                                 eventTraceActivity = new EventTraceActivity(activityId);
64                             }
65                         }
66                     }
67 
68                     if (eventTraceActivity == null && createIfNotExist)
69                     {
70                         eventTraceActivity = new EventTraceActivity();
71                     }
72 
73                     if (eventTraceActivity != null)
74                     {
75                         // Attach the trace activity to the message
76                         message.Properties[EventTraceActivity.Name] = eventTraceActivity;
77                     }
78                 }
79             }
80 
81             return eventTraceActivity;
82         }
83 
84         [Fx.Tag.SecurityNote(Critical = "This sets the ActivityId on the thread. Must not be settable from PT code unless from safe context.")]
85         [SecurityCritical]
86         [SecurityPermission(SecurityAction.Assert, Unrestricted = true)]
SetOnThread(EventTraceActivity eventTraceActivity)87         internal static void SetOnThread(EventTraceActivity eventTraceActivity)
88         {
89             if (eventTraceActivity != null)
90             {
91                 Trace.CorrelationManager.ActivityId = eventTraceActivity.ActivityId;
92             }
93         }
94 
GetMessageId(Message message, out Guid guid)95         private static bool GetMessageId(Message message, out Guid guid)
96         {
97             UniqueId uniqueId = message.Headers.MessageId;
98             if (uniqueId == null)
99             {
100                 guid = Guid.Empty;
101                 return false;
102             }
103 
104             return uniqueId.TryGetGuid(out guid);
105         }
106     }
107 }
108