diff --git a/BaseIntermediateOutputPath.props b/BaseIntermediateOutputPath.props
new file mode 100644
index 0000000..48e7654
--- /dev/null
+++ b/BaseIntermediateOutputPath.props
@@ -0,0 +1,12 @@
+
+
+
+
+ $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'EnlistmentRoot.marker'))
+ $(EnlistmentRoot)\..\obj\$(MSBuildProjectName)
+ $([System.IO.Path]::GetFullPath( $(BaseIntermediateOutputPath) ))
+
+
\ No newline at end of file
diff --git a/Global.props b/Global.props
index 8bf307a..be82fc5 100644
--- a/Global.props
+++ b/Global.props
@@ -1,6 +1,8 @@
+
+
@@ -60,16 +62,11 @@
- $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'EnlistmentRoot.marker'))
-
$(EnlistmentRoot)\..\bin
$([System.IO.Path]::GetFullPath( $(BinRoot) ))
$(MSBuildProjectDirectory.Substring($(EnlistmentRoot.Length)))
- $(EnlistmentRoot)\..\obj
- $([System.IO.Path]::GetFullPath( $(BaseIntermediateOutputPath) ))
-
Debug
$(BinRoot)\$(Configuration)\$(RelativeOutputPathBase)
@@ -117,4 +114,4 @@
<_Parameter1>$(SemanticVersionMajor).$(SemanticVersionMinor).$(SemanticVersionPatch).$(PreReleaseVersion)
-
\ No newline at end of file
+
diff --git a/WCF/.editorconfig b/WCF/.editorconfig
new file mode 100644
index 0000000..9284239
--- /dev/null
+++ b/WCF/.editorconfig
@@ -0,0 +1,78 @@
+# EditorConfig is awesome:http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Don't use tabs for indentation.
+[*]
+indent_style = space
+# (Please don't specify an indent_size here; that has too many unintended consequences.)
+
+# Code files
+[*.{cs,csx,vb,vbx}]
+indent_size = 4
+
+# Xml project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# Xml config files
+[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
+indent_size = 2
+
+# JSON files
+[*.json]
+indent_size = 2
+
+# Dotnet code style settings:
+[*.{cs,vb}]
+# Sort using and Import directives with System.* appearing first
+dotnet_sort_system_directives_first = true
+# Avoid "this." and "Me." if not necessary
+dotnet_style_qualification_for_field = true:suggestion
+dotnet_style_qualification_for_property = true:suggestion
+dotnet_style_qualification_for_method = true:suggestion
+dotnet_style_qualification_for_event = true:suggestion
+
+# Use language keywords instead of framework type names for type references
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# Suggest more modern language features when available
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+
+# CSharp code style settings:
+[*.cs]
+# Prefer "var" everywhere
+csharp_style_var_for_built_in_types = true:suggestion
+csharp_style_var_when_type_is_apparent = true:suggestion
+csharp_style_var_elsewhere = true:suggestion
+
+# Prefer method-like constructs to have a block body
+csharp_style_expression_bodied_methods = false:none
+csharp_style_expression_bodied_constructors = false:none
+csharp_style_expression_bodied_operators = false:none
+
+# Prefer property-like constructs to have an expression-body
+csharp_style_expression_bodied_properties = true:none
+csharp_style_expression_bodied_indexers = true:none
+csharp_style_expression_bodied_accessors = true:none
+
+# Suggest more modern language features when available
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+
+# Newline settings
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
\ No newline at end of file
diff --git a/WCF/Settings.StyleCop b/WCF/Settings.StyleCop
new file mode 100644
index 0000000..9d40616
--- /dev/null
+++ b/WCF/Settings.StyleCop
@@ -0,0 +1,128 @@
+
+
+ NoMerge
+
+
+
+
+ False
+
+ \.g\.cs$
+ \.generated\.cs$
+ \.g\.i\.cs$
+ TemporaryGeneratedFile_.*\.cs$
+
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ Microsoft
+ Copyright © Microsoft. All Rights Reserved.
+
+
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+ if
+ is
+ on
+ to
+
+
+
+
+
\ No newline at end of file
diff --git a/WCF/Shared.Tests/ChannelTestBase.cs b/WCF/Shared.Tests/ChannelTestBase.cs
index 008f619..080376d 100644
--- a/WCF/Shared.Tests/ChannelTestBase.cs
+++ b/WCF/Shared.Tests/ChannelTestBase.cs
@@ -1,20 +1,20 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-using System.Reflection;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Linq;
+ using System.Reflection;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
public abstract class ChannelTestBase where TChannel : IChannel
{
- public const String SvcUrl = "http://localhost/MyService.svc";
- public const String HostName = "localhost";
+ public const string SvcUrl = "http://localhost/MyService.svc";
+ public const string HostName = "localhost";
[TestMethod]
[TestCategory("Client")]
@@ -24,11 +24,13 @@ public void WhenChannelManagerIsNull_ConstructorThrowsException()
bool failed = false;
try
{
- var channel = GetChannel(null, innerChannel);
- } catch ( ArgumentNullException )
+ var channel = this.GetChannel(null, innerChannel);
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "Constructor did not throw ArgumentNullException");
}
@@ -36,44 +38,43 @@ public void WhenChannelManagerIsNull_ConstructorThrowsException()
[TestCategory("Client")]
public void WhenInnerChannelIsNull_ConstructorThrowsException()
{
-
var manager = new ClientChannelManager(new TelemetryClient(), typeof(ISimpleService));
bool failed = false;
try
{
- var channel = GetChannel(manager, null);
- } catch ( ArgumentNullException )
+ var channel = this.GetChannel(manager, null);
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "Constructor did not throw ArgumentNullException");
}
-
[TestMethod]
[TestCategory("Client")]
public void WhenChannelIsCreated_InnerChannelRemoteAddressIsReturned()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
- // IChannel does not define RemoteAddress, so cheat
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
+ // IChannel does not define RemoteAddress, so cheat
var prop = channel.GetType().GetProperty("RemoteAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
Assert.AreEqual(innerChannel.RemoteAddress, prop.GetValue(channel, null));
}
- //
+ // -------------------------------
// Event Handling
- //
-
+ // -------------------------------
[TestMethod]
[TestCategory("Client")]
public void WhenChannelIsOpened_InnerChannelEventsAreHooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open();
Assert.IsTrue(innerChannel.OpeningIsHooked(), "Opening event is not hooked");
@@ -89,7 +90,7 @@ public void WhenChannelIsOpenedWithTimeout_InnerChannelEventsAreHooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open(TimeSpan.FromSeconds(10));
Assert.IsTrue(innerChannel.OpeningIsHooked(), "Opening event is not hooked");
@@ -99,14 +100,13 @@ public void WhenChannelIsOpenedWithTimeout_InnerChannelEventsAreHooked()
Assert.IsTrue(innerChannel.FaultedIsHooked(), "Faulted event is not hooked");
}
-
[TestMethod]
[TestCategory("Client")]
public void WhenChannelIsOpenedAsync_InnerChannelEventsAreHooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var result = channel.BeginOpen(null, null);
channel.EndOpen(result);
@@ -123,7 +123,7 @@ public void WhenChannelIsOpenedAsyncWithTimeout_InnerChannelEventsAreHooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var result = channel.BeginOpen(TimeSpan.FromSeconds(10), null, null);
channel.EndOpen(result);
@@ -139,7 +139,7 @@ public void WhenChannelIsClosed_InnerChannelEventsAreUnhooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open();
channel.Close();
@@ -156,7 +156,7 @@ public void WhenChannelIsClosedWithTimeout_InnerChannelEventsAreUnhooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open();
channel.Close(TimeSpan.FromSeconds(1));
@@ -173,7 +173,7 @@ public void WhenChannelIsClosedAsync_InnerChannelEventsAreUnhooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open();
var result = channel.BeginClose(null, null);
channel.EndClose(result);
@@ -191,7 +191,7 @@ public void WhenChannelIsClosedAsyncWithTimeout_InnerChannelEventsAreUnhooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open();
var result = channel.BeginClose(TimeSpan.FromSeconds(10), null, null);
channel.EndClose(result);
@@ -209,7 +209,7 @@ public void WhenChannelIsAborted_InnerChannelEventsAreUnhooked()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open();
channel.Abort();
@@ -220,17 +220,16 @@ public void WhenChannelIsAborted_InnerChannelEventsAreUnhooked()
Assert.IsFalse(innerChannel.FaultedIsHooked(), "Faulted event is hooked");
}
- //
+ // ---------------------------------------
// Channel.Open Telemetry
- //
-
+ // ---------------------------------------
[TestMethod]
[TestCategory("Client")]
public void WhenChannelIsOpened_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open();
CheckOpenDependencyWritten(typeof(ISimpleService), true);
@@ -242,7 +241,7 @@ public void WhenChannelIsOpenedWithTimeout_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
channel.Open(TimeSpan.FromSeconds(10));
CheckOpenDependencyWritten(typeof(ISimpleService), true);
@@ -254,7 +253,7 @@ public void WhenChannelIsOpenedAsync_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var result = channel.BeginOpen(null, null);
channel.EndOpen(result);
@@ -267,7 +266,7 @@ public void WhenChannelIsOpenedAsyncWithTimeout_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var result = channel.BeginOpen(TimeSpan.FromSeconds(10), null, null);
channel.EndOpen(result);
@@ -282,15 +281,17 @@ public void WhenChannelIsOpened_TelemetryIsWritten_Failure()
innerChannel.FailOpen = true;
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
bool failed = false;
try
{
channel.Open();
- } catch ( Exception )
+ }
+ catch (Exception)
{
failed = true;
}
+
Assert.IsTrue(failed, "Open() did not throw exception");
CheckOpenDependencyWritten(typeof(ISimpleService), false);
@@ -304,15 +305,17 @@ public void WhenChannelIsOpenedWithTimeout_TelemetryIsWritten_Failure()
innerChannel.FailOpen = true;
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
bool failed = false;
try
{
channel.Open(TimeSpan.FromSeconds(10));
- } catch ( Exception )
+ }
+ catch (Exception)
{
failed = true;
}
+
Assert.IsTrue(failed, "Open() did not throw exception");
CheckOpenDependencyWritten(typeof(ISimpleService), false);
@@ -326,15 +329,17 @@ public void WhenChannelIsOpenedAsync_TelemetryIsWritten_FailureInBegin()
innerChannel.FailBeginOpen = true;
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
bool failed = false;
try
{
channel.BeginOpen(null, null);
- } catch ( Exception )
+ }
+ catch (Exception)
{
failed = true;
}
+
Assert.IsTrue(failed, "BeginOpen() did not throw exception");
CheckOpenDependencyWritten(typeof(ISimpleService), false);
@@ -348,26 +353,27 @@ public void WhenChannelIsOpenedAsyncWithTimeout_TelemetryIsWritten_FailureInBegi
innerChannel.FailBeginOpen = true;
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
bool failed = false;
try
{
channel.BeginOpen(TimeSpan.FromSeconds(10), null, null);
- } catch ( Exception )
+ }
+ catch (Exception)
{
failed = true;
}
+
Assert.IsTrue(failed, "BeginOpen() did not throw exception");
CheckOpenDependencyWritten(typeof(ISimpleService), false);
}
-
-
internal abstract TChannel GetChannel(IChannel channel, Type contract);
+
internal abstract TChannel GetChannel(IChannelManager manager, IChannel channel);
- private void CheckOpenDependencyWritten(Type contract, bool success)
+ private static void CheckOpenDependencyWritten(Type contract, bool success)
{
var dependency = TestTelemetryChannel.CollectedData().OfType().FirstOrDefault();
Assert.IsNotNull(dependency, "Did not write dependency event");
diff --git a/WCF/Shared.Tests/Channels/TestTelemetryChannel.cs b/WCF/Shared.Tests/Channels/TestTelemetryChannel.cs
index 78aa9b7..e35f0d1 100644
--- a/WCF/Shared.Tests/Channels/TestTelemetryChannel.cs
+++ b/WCF/Shared.Tests/Channels/TestTelemetryChannel.cs
@@ -1,13 +1,9 @@
-using Microsoft.ApplicationInsights.Channel;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Channels
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Channels
{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.ApplicationInsights.Channel;
+
public sealed class TestTelemetryChannel : ITelemetryChannel
{
private static List items = new List();
@@ -17,36 +13,37 @@ public sealed class TestTelemetryChannel : ITelemetryChannel
public string EndpointAddress { get; set; }
- public void Flush()
+ public static void Clear()
{
+ lock (lockobj)
+ {
+ items.Clear();
+ }
}
- public void Send(ITelemetry item)
+ public static IList CollectedData()
{
- lock ( lockobj )
+ lock (lockobj)
{
- items.Add(item);
+ List list = new List(items);
+ return list;
}
}
- public void Dispose()
+ public void Flush()
{
}
- public static void Clear()
+ public void Send(ITelemetry item)
{
- lock ( lockobj )
+ lock (lockobj)
{
- items.Clear();
+ items.Add(item);
}
}
- public static IList CollectedData()
+
+ public void Dispose()
{
- lock ( lockobj )
- {
- List list = new List(items);
- return list;
- }
}
}
}
diff --git a/WCF/Shared.Tests/ClientChannelManager.cs b/WCF/Shared.Tests/ClientChannelManager.cs
index f5e2a9d..04fb654 100644
--- a/WCF/Shared.Tests/ClientChannelManager.cs
+++ b/WCF/Shared.Tests/ClientChannelManager.cs
@@ -1,11 +1,18 @@
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using System;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Description;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+
internal class ClientChannelManager : IChannelManager
{
+ public ClientChannelManager(TelemetryClient client, Type contractType)
+ {
+ this.TelemetryClient = client;
+ this.OperationMap = new ClientContract(ContractDescription.GetContract(contractType));
+ this.CloseTimeout = this.OpenTimeout = this.ReceiveTimeout = this.SendTimeout = TimeSpan.FromSeconds(5);
+ }
+
public TimeSpan CloseTimeout { get; private set; }
public TimeSpan OpenTimeout { get; private set; }
@@ -17,17 +24,15 @@ internal class ClientChannelManager : IChannelManager
public TimeSpan SendTimeout { get; private set; }
public TelemetryClient TelemetryClient { get; private set; }
- public String RootOperationIdHeaderName { get; set; }
- public String ParentOperationIdHeaderName { get; set; }
- public String SoapRootOperationIdHeaderName { get; set; }
- public String SoapParentOperationIdHeaderName { get; set; }
- public String SoapHeaderNamespace { get; set; }
- public ClientChannelManager(TelemetryClient client, Type contractType)
- {
- this.TelemetryClient = client;
- this.OperationMap = new ClientContract(ContractDescription.GetContract(contractType));
- this.CloseTimeout = this.OpenTimeout = this.ReceiveTimeout = this.SendTimeout = TimeSpan.FromSeconds(5);
- }
+ public string RootOperationIdHeaderName { get; set; }
+
+ public string ParentOperationIdHeaderName { get; set; }
+
+ public string SoapRootOperationIdHeaderName { get; set; }
+
+ public string SoapParentOperationIdHeaderName { get; set; }
+
+ public string SoapHeaderNamespace { get; set; }
}
}
diff --git a/WCF/Shared.Tests/ClientContractTests.cs b/WCF/Shared.Tests/ClientContractTests.cs
index ddd81e8..038e597 100644
--- a/WCF/Shared.Tests/ClientContractTests.cs
+++ b/WCF/Shared.Tests/ClientContractTests.cs
@@ -1,11 +1,11 @@
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Description;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ClientContractTests
{
diff --git a/WCF/Shared.Tests/ClientExceptionExtensionsTests.cs b/WCF/Shared.Tests/ClientExceptionExtensionsTests.cs
index 7238423..f3a2ecc 100644
--- a/WCF/Shared.Tests/ClientExceptionExtensionsTests.cs
+++ b/WCF/Shared.Tests/ClientExceptionExtensionsTests.cs
@@ -1,10 +1,10 @@
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ClientExceptionExtensionsTests
{
@@ -15,10 +15,12 @@ public void When_ExceptionIsNull_ExceptionIsThrown()
try
{
ClientExceptionExtensions.ToResultCode(null);
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "ToResultCode() did not throw ArgumentNullException");
}
@@ -52,8 +54,7 @@ public void When_OtherException()
TestException("ChannelTerminatedException");
}
-
- private void TestException(string expected) where TException : Exception, new()
+ private static void TestException(string expected) where TException : Exception, new()
{
var ex = new TException();
Assert.AreEqual(expected, ex.ToResultCode());
diff --git a/WCF/Shared.Tests/ClientIpTelemetryInitializerTests.cs b/WCF/Shared.Tests/ClientIpTelemetryInitializerTests.cs
index 6a6e842..5d5d403 100644
--- a/WCF/Shared.Tests/ClientIpTelemetryInitializerTests.cs
+++ b/WCF/Shared.Tests/ClientIpTelemetryInitializerTests.cs
@@ -1,41 +1,39 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Collections.Generic;
-using System.ServiceModel.Channels;
-using System.Text;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ClientIpTelemetryInitializerTests
{
[TestMethod]
public void SetsClientIpFromWcfContextOnRequest()
{
- const String clientIp = "10.12.32.12";
+ const string ClientIp = "10.12.32.12";
var context = new MockOperationContext();
context.IncomingProperties.Add(
RemoteEndpointMessageProperty.Name,
- new RemoteEndpointMessageProperty(clientIp, 7656));
+ new RemoteEndpointMessageProperty(ClientIp, 7656));
var initializer = new ClientIpTelemetryInitializer();
var telemetry = context.Request;
initializer.Initialize(telemetry, context);
- Assert.AreEqual(clientIp, telemetry.Context.Location.Ip);
+ Assert.AreEqual(ClientIp, telemetry.Context.Location.Ip);
}
[TestMethod]
public void SetsClientIpFromWcfContextOnOtherEvent()
{
- const String originalIp = "10.12.32.12";
- const String newIp = "172.34.12.45";
+ const string OriginalIp = "10.12.32.12";
+ const string NewIp = "172.34.12.45";
var context = new MockOperationContext();
context.IncomingProperties.Add(
RemoteEndpointMessageProperty.Name,
- new RemoteEndpointMessageProperty(originalIp, 7656));
+ new RemoteEndpointMessageProperty(OriginalIp, 7656));
var initializer = new ClientIpTelemetryInitializer();
@@ -48,26 +46,26 @@ public void SetsClientIpFromWcfContextOnOtherEvent()
context.IncomingProperties.Clear();
context.IncomingProperties.Add(
RemoteEndpointMessageProperty.Name,
- new RemoteEndpointMessageProperty(newIp, 7656));
+ new RemoteEndpointMessageProperty(NewIp, 7656));
var telemetry = new EventTelemetry("myevent");
initializer.Initialize(telemetry, context);
- Assert.AreEqual(originalIp, telemetry.Context.Location.Ip);
+ Assert.AreEqual(OriginalIp, telemetry.Context.Location.Ip);
}
[TestMethod]
public void ClientIpIsCopiedFromRequestIfPresent()
{
- const String clientIp = "10.12.32.12";
+ const string ClientIp = "10.12.32.12";
var context = new MockOperationContext();
- context.Request.Context.Location.Ip = clientIp;
+ context.Request.Context.Location.Ip = ClientIp;
var initializer = new ClientIpTelemetryInitializer();
var telemetry = new EventTelemetry();
initializer.Initialize(telemetry, context);
- Assert.AreEqual(clientIp, telemetry.Context.Location.Ip);
+ Assert.AreEqual(ClientIp, telemetry.Context.Location.Ip);
}
}
}
diff --git a/WCF/Shared.Tests/ClientTelemetryBindingElementTests.cs b/WCF/Shared.Tests/ClientTelemetryBindingElementTests.cs
index 43f5368..3b7c461 100644
--- a/WCF/Shared.Tests/ClientTelemetryBindingElementTests.cs
+++ b/WCF/Shared.Tests/ClientTelemetryBindingElementTests.cs
@@ -1,17 +1,17 @@
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ClientTelemetryBindingElementTests
{
- const String TwoWayOp1 = "http://tempuri.org/ISimpleService/GetSimpleData";
- const String TwoWayOp2 = "http://tempuri.org/ISimpleService/CallFailsWithFault";
+ private const string TwoWayOp1 = "http://tempuri.org/ISimpleService/GetSimpleData";
+ private const string TwoWayOp2 = "http://tempuri.org/ISimpleService/CallFailsWithFault";
[TestMethod]
[TestCategory("Client")]
@@ -23,10 +23,12 @@ public void WhenClientIsNull_ConstructorThrowsException()
try
{
var element = new ClientTelemetryBindingElement(client, map);
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "Constructor did not throw ArgumentNullException");
}
@@ -41,10 +43,12 @@ public void WhenOperationMapIsNull_ConstructorThrowsException()
try
{
var element = new ClientTelemetryBindingElement(client, map);
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "Constructor did not throw ArgumentNullException");
}
@@ -59,10 +63,12 @@ public void WhenContextIsNull_CanBuildChannelFactoryThrowsException()
{
var element = new ClientTelemetryBindingElement(client, map);
element.CanBuildChannelFactory(null);
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "CanBuildChannelFactory did not throw ArgumentNullException");
}
@@ -77,10 +83,12 @@ public void WhenContextIsNull_BuildChannelFactoryThrowsException()
{
var element = new ClientTelemetryBindingElement(client, map);
element.BuildChannelFactory(null);
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "BuildChannelFactory did not throw ArgumentNullException");
}
@@ -132,7 +140,6 @@ public void WithIInputChannel_CanBuildChannelFactoryReturnsFalse()
Assert.IsFalse(element.CanBuildChannelFactory(context));
}
-
public void TestChannelShape(Binding binding, bool tryCreate = true)
{
TelemetryClient client = new TelemetryClient();
@@ -143,7 +150,7 @@ public void TestChannelShape(Binding binding, bool tryCreate = true)
BindingContext context = new BindingContext(custom, new BindingParameterCollection());
Assert.IsTrue(element.CanBuildChannelFactory(context));
- if ( tryCreate )
+ if (tryCreate)
{
var factory = element.BuildChannelFactory(context);
Assert.IsNotNull(factory, "BuildChannelFactory() returned null");
diff --git a/WCF/Shared.Tests/ClientTelemetryDuplexChannelTests.cs b/WCF/Shared.Tests/ClientTelemetryDuplexChannelTests.cs
index 19f4ec5..cf044c2 100644
--- a/WCF/Shared.Tests/ClientTelemetryDuplexChannelTests.cs
+++ b/WCF/Shared.Tests/ClientTelemetryDuplexChannelTests.cs
@@ -1,35 +1,23 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-using System.ServiceModel.Channels;
-using System.Threading;
-using System.Xml;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Linq;
+ using System.ServiceModel.Channels;
+ using System.Threading;
+ using System.Xml;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ClientTelemetryDuplexChannelTests : ChannelTestBase
{
- const String TwoWayOp1 = "http://tempuri.org/ISimpleService/GetSimpleData";
- const String TwoWayOp2 = "http://tempuri.org/ISimpleService/CallFailsWithFault";
- const String OneWayOp1 = "http://tempuri.org/IOneWayService/SuccessfullOneWayCall";
-
- internal override IDuplexChannel GetChannel(IChannel innerChannel, Type contract)
- {
- return GetChannel(
- new ClientChannelManager(new TelemetryClient(), contract),
- innerChannel
- );
- }
- internal override IDuplexChannel GetChannel(IChannelManager manager, IChannel innerChannel)
- {
- return new ClientTelemetryDuplexChannel(manager, innerChannel);
- }
+ private const string TwoWayOp1 = "http://tempuri.org/ISimpleService/GetSimpleData";
+ private const string TwoWayOp2 = "http://tempuri.org/ISimpleService/CallFailsWithFault";
+ private const string OneWayOp1 = "http://tempuri.org/IOneWayService/SuccessfullOneWayCall";
[TestMethod]
[TestCategory("Client")]
@@ -37,34 +25,39 @@ public void Send_WhenMessageIsNull_ThrowsException()
{
TestTelemetryChannel.Clear();
var innerChannel = new MockClientChannel(SvcUrl);
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
bool failed = false;
try
{
channel.Send(null);
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "Send did not throw an exception");
}
+
[TestMethod]
[TestCategory("Client")]
public void BeginSend_WhenMessageIsNull_ThrowsException()
{
TestTelemetryChannel.Clear();
var innerChannel = new MockClientChannel(SvcUrl);
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
bool failed = false;
try
{
channel.BeginSend(null, null, null);
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "BeginSend did not throw an exception");
}
@@ -74,7 +67,7 @@ public void Send_OneWay_WritesTelemetry()
{
TestTelemetryChannel.Clear();
var innerChannel = new MockClientChannel(SvcUrl);
- var channel = GetChannel(innerChannel, typeof(IOneWayService));
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService));
var request = BuildMessage(OneWayOp1);
request.Headers.MessageId = new UniqueId();
@@ -92,7 +85,7 @@ public void SendFollowedByMatchingReceive_WritesTelemetry()
{
TestTelemetryChannel.Clear();
var innerChannel = new MockClientChannel(SvcUrl);
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var request = BuildMessage(TwoWayOp1);
request.Headers.MessageId = new UniqueId();
@@ -115,7 +108,7 @@ public void AsyncSendAndReceive_WritesTelemetry()
{
TestTelemetryChannel.Clear();
var innerChannel = new MockClientChannel(SvcUrl);
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var request = BuildMessage(TwoWayOp1);
request.Headers.MessageId = new UniqueId();
@@ -140,7 +133,7 @@ public void AsyncSendAndTryReceive_WritesTelemetry()
{
TestTelemetryChannel.Clear();
var innerChannel = new MockClientChannel(SvcUrl);
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var request = BuildMessage(TwoWayOp1);
request.Headers.MessageId = new UniqueId();
@@ -166,7 +159,7 @@ public void SendFollowedWithReceiveTimeout_WritesTelemetry()
{
TestTelemetryChannel.Clear();
var innerChannel = new MockClientChannel(SvcUrl);
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var request = BuildMessage(TwoWayOp1);
request.Headers.MessageId = new UniqueId();
@@ -177,12 +170,14 @@ public void SendFollowedWithReceiveTimeout_WritesTelemetry()
try
{
channel.Receive();
- } catch ( TimeoutException )
+ }
+ catch (TimeoutException)
{
failed = true;
}
Assert.IsTrue(failed, "Receive did not fail with TimeoutException");
+
// there's potentially some additional delay between our timeout firing internally,
// and the callback firing so that telemetry can be written
Thread.Sleep(200);
@@ -194,7 +189,19 @@ public void SendFollowedWithReceiveTimeout_WritesTelemetry()
Assert.IsFalse(telemetry.Success.Value, "Dependency call succeeded");
}
- private Message BuildMessage(String action)
+ internal override IDuplexChannel GetChannel(IChannel innerChannel, Type contract)
+ {
+ return this.GetChannel(
+ new ClientChannelManager(new TelemetryClient(), contract),
+ innerChannel);
+ }
+
+ internal override IDuplexChannel GetChannel(IChannelManager manager, IChannel innerChannel)
+ {
+ return new ClientTelemetryDuplexChannel(manager, innerChannel);
+ }
+
+ private static Message BuildMessage(string action)
{
return Message.CreateMessage(MessageVersion.Default, action, "");
}
diff --git a/WCF/Shared.Tests/ClientTelemetryEndpointBehaviorTests.cs b/WCF/Shared.Tests/ClientTelemetryEndpointBehaviorTests.cs
index 9df1f60..11ca185 100644
--- a/WCF/Shared.Tests/ClientTelemetryEndpointBehaviorTests.cs
+++ b/WCF/Shared.Tests/ClientTelemetryEndpointBehaviorTests.cs
@@ -1,16 +1,16 @@
-using Microsoft.ApplicationInsights.Extensibility;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Reflection;
-using System.Runtime.Remoting;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Reflection;
+ using System.Runtime.Remoting;
+ using System.ServiceModel;
+ using Microsoft.ApplicationInsights.Extensibility;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ClientTelemetryEndpointBehaviorTests
{
@@ -18,10 +18,9 @@ public class ClientTelemetryEndpointBehaviorTests
[TestCategory("Client")]
public void BehaviorAddsCustomBinding()
{
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
var binding = new NetTcpBinding();
- //binding.TransferMode = TransferMode.Streamed;
var configuration = new TelemetryConfiguration();
var factory = new ChannelFactory(binding, host.GetServiceAddress());
ISimpleService channel = null;
@@ -40,30 +39,30 @@ public void BehaviorAddsCustomBinding()
factory.Close();
Assert.IsInstanceOfType(innerChannel, typeof(ClientTelemetryChannelBase), "Telemetry channel is missing");
- } catch
+ }
+ catch
{
factory.Abort();
- if ( channel != null )
+ if (channel != null)
{
((IClientChannel)channel).Abort();
}
+
throw;
}
}
}
-
[TestMethod]
[TestCategory("Integration"), TestCategory("Client")]
public void RequestReply_TelemetryIsWritten()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
var binding = new NetTcpBinding();
- //binding.TransferMode = TransferMode.Streamed;
var configuration = new TelemetryConfiguration();
var factory = new ChannelFactory(binding, host.GetServiceAddress());
ISimpleService channel = null;
@@ -82,18 +81,21 @@ public void RequestReply_TelemetryIsWritten()
factory.Close();
Assert.IsTrue(TestTelemetryChannel.CollectedData().Count > 0, "No telemetry events written");
- } catch
+ }
+ catch
{
- if ( channel != null )
+ if (channel != null)
{
((IClientChannel)channel).Abort();
}
+
factory.Abort();
throw;
}
}
}
- private System.ServiceModel.Channels.IChannel GetInnerChannel(object proxy)
+
+ private static System.ServiceModel.Channels.IChannel GetInnerChannel(object proxy)
{
// TransparentProxy -> ServiceChannelProxy -> ServiceChannel
var realProxy = RemotingServices.GetRealProxy(proxy);
diff --git a/WCF/Shared.Tests/ClientTelemetryExtensionElementTestscs.cs b/WCF/Shared.Tests/ClientTelemetryExtensionElementTestscs.cs
index 9493656..d62126c 100644
--- a/WCF/Shared.Tests/ClientTelemetryExtensionElementTestscs.cs
+++ b/WCF/Shared.Tests/ClientTelemetryExtensionElementTestscs.cs
@@ -1,11 +1,11 @@
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Configuration;
-using System.Linq;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Configuration;
+ using System.Linq;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ClientTelemetryExtensionElementTestscs
{
diff --git a/WCF/Shared.Tests/ClientTelemetryOutputChannelTests.cs b/WCF/Shared.Tests/ClientTelemetryOutputChannelTests.cs
index b355e12..525d102 100644
--- a/WCF/Shared.Tests/ClientTelemetryOutputChannelTests.cs
+++ b/WCF/Shared.Tests/ClientTelemetryOutputChannelTests.cs
@@ -1,36 +1,19 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Linq;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ClientTelemetryOutputChannelTests : ChannelTestBase
{
- const String OneWayOp1 = "http://tempuri.org/IOneWayService/SuccessfullOneWayCall";
-
- private IOutputChannel GetChannel(IChannel innerChannel, Type contract, TelemetryClient client)
- {
- return GetChannel(
- new ClientChannelManager(client ?? new TelemetryClient(), contract),
- innerChannel
- );
- }
- internal override IOutputChannel GetChannel(IChannel innerChannel, Type contract)
- {
- return GetChannel(innerChannel, contract, null);
- }
- internal override IOutputChannel GetChannel(IChannelManager manager, IChannel innerChannel)
- {
- return new ClientTelemetryOutputChannel(manager, innerChannel);
- }
+ private const string OneWayOp1 = "http://tempuri.org/IOneWayService/SuccessfullOneWayCall";
[TestMethod]
[TestCategory("Client")]
@@ -38,7 +21,7 @@ public void WhenMessageIsSent_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(IOneWayService));
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService));
channel.Send(BuildMessage(OneWayOp1));
@@ -51,7 +34,7 @@ public void WhenMessageIsSentWithTimeout_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(IOneWayService));
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService));
channel.Send(BuildMessage(OneWayOp1), TimeSpan.FromSeconds(10));
@@ -64,7 +47,7 @@ public void WhenMessageIsSent_TelemetryIsWritten_Exception()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(IOneWayService));
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService));
innerChannel.FailRequest = true;
@@ -72,10 +55,12 @@ public void WhenMessageIsSent_TelemetryIsWritten_Exception()
try
{
channel.Send(BuildMessage(OneWayOp1));
- } catch
+ }
+ catch
{
failed = true;
}
+
Assert.IsTrue(failed, "Send did not throw an exception");
CheckOpDependencyWritten(DependencyConstants.WcfClientCall, typeof(IOneWayService), OneWayOp1, "SuccessfullOneWayCall", false);
@@ -87,7 +72,7 @@ public void WhenMessageIsSent_WithTimeoutException_TelemetryHasResultCode()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(IOneWayService));
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService));
innerChannel.FailRequest = true;
innerChannel.ExceptionToThrowOnSend = new TimeoutException();
@@ -96,10 +81,12 @@ public void WhenMessageIsSent_WithTimeoutException_TelemetryHasResultCode()
try
{
channel.Send(BuildMessage(OneWayOp1));
- } catch ( TimeoutException )
+ }
+ catch (TimeoutException)
{
failed = true;
}
+
Assert.IsTrue(failed, "Send did not throw TimeoutException");
var telemetry = TestTelemetryChannel.CollectedData().OfType().First();
@@ -112,7 +99,7 @@ public void WhenMessageIsSent_Async_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(IOneWayService));
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService));
var result = channel.BeginSend(BuildMessage(OneWayOp1), null, null);
channel.EndSend(result);
@@ -126,7 +113,7 @@ public void WhenMessageIsSentWithTimeout_Async_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(IOneWayService));
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService));
var result = channel.BeginSend(BuildMessage(OneWayOp1), TimeSpan.FromSeconds(10), null, null);
channel.EndSend(result);
@@ -140,7 +127,7 @@ public void WhenMessageIsSent_Async_TelemetryIsWritten_ExceptionOnEnd()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(IOneWayService));
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService));
innerChannel.FailEndRequest = true;
@@ -149,19 +136,20 @@ public void WhenMessageIsSent_Async_TelemetryIsWritten_ExceptionOnEnd()
try
{
channel.EndSend(result);
- } catch
+ }
+ catch
{
failed = true;
}
+
Assert.IsTrue(failed, "EndSend did not throw an exception");
CheckOpDependencyWritten(DependencyConstants.WcfClientCall, typeof(IOneWayService), OneWayOp1, "SuccessfullOneWayCall", false);
}
-
- //
+ // -----------------------
// Other tests
- //
+ // -----------------------
[TestMethod]
[TestCategory("Client")]
public void WhenMessageIsSent_CorrelationHeadersAreSet()
@@ -171,7 +159,7 @@ public void WhenMessageIsSent_CorrelationHeadersAreSet()
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(IOneWayService), client);
+ var channel = this.GetChannel(innerChannel, typeof(IOneWayService), client);
channel.Send(BuildMessage(OneWayOp1));
@@ -183,27 +171,37 @@ public void WhenMessageIsSent_CorrelationHeadersAreSet()
Assert.IsNotNull(GetSoapHeader(message, CorrelationHeaders.SoapStandardNamespace, CorrelationHeaders.SoapStandardParentIdHeader));
}
- private String GetSoapHeader(Message message, String ns, String headerName)
+ internal override IOutputChannel GetChannel(IChannel innerChannel, Type contract)
{
- return message.Headers.GetHeader(headerName, ns);
+ return this.GetChannel(innerChannel, contract, null);
+ }
+
+ internal override IOutputChannel GetChannel(IChannelManager manager, IChannel innerChannel)
+ {
+ return new ClientTelemetryOutputChannel(manager, innerChannel);
}
- private String GetHttpHeader(Message message, String headerName)
+ private static string GetSoapHeader(Message message, string ns, string headerName)
+ {
+ return message.Headers.GetHeader(headerName, ns);
+ }
+
+ private static string GetHttpHeader(Message message, string headerName)
{
var httpHeaders = message.GetHttpRequestHeaders();
return httpHeaders.Headers[headerName];
}
- private Message BuildMessage(String action)
+ private static Message BuildMessage(string action)
{
return Message.CreateMessage(MessageVersion.Default, action, "");
}
- private void CheckOpDependencyWritten(String type, Type contract, String action, String method, bool success)
+ private static void CheckOpDependencyWritten(string type, Type contract, string action, string method, bool success)
{
var dependency = TestTelemetryChannel.CollectedData().OfType().FirstOrDefault();
Assert.IsNotNull(dependency, "Did not write dependency event");
- Assert.AreEqual(SvcUrl, dependency.Data);
+ Assert.AreEqual(ClientTelemetryOutputChannelTests.SvcUrl, dependency.Data);
Assert.AreEqual("localhost", dependency.Target);
Assert.AreEqual(type, dependency.Type);
Assert.AreEqual(contract.Name + "." + method, dependency.Name);
@@ -211,5 +209,12 @@ private void CheckOpDependencyWritten(String type, Type contract, String action,
Assert.AreEqual("True", dependency.Properties["isOneWay"]);
Assert.AreEqual(success, dependency.Success.Value);
}
+
+ private IOutputChannel GetChannel(IChannel innerChannel, Type contract, TelemetryClient client)
+ {
+ return this.GetChannel(
+ new ClientChannelManager(client ?? new TelemetryClient(), contract),
+ innerChannel);
+ }
}
}
diff --git a/WCF/Shared.Tests/ClientTelemetryRequestChannelTests.cs b/WCF/Shared.Tests/ClientTelemetryRequestChannelTests.cs
index 088dfc1..ce4f58e 100644
--- a/WCF/Shared.Tests/ClientTelemetryRequestChannelTests.cs
+++ b/WCF/Shared.Tests/ClientTelemetryRequestChannelTests.cs
@@ -1,45 +1,32 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Linq;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Integration;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
- public class ClientTelemetryRequestChannelTests : ChannelTestBase
+ public class ClientTelemetryRequestChannelTests : ChannelTestBase
{
- const String TwoWayOp1 = "http://tempuri.org/ISimpleService/GetSimpleData";
- const String TwoWayOp2 = "http://tempuri.org/ISimpleService/CallFailsWithFault";
- const String OneWayOp1 = "http://tempuri.org/IOneWayService/SuccessfullOneWayCall";
-
-
- internal override IRequestChannel GetChannel(IChannel innerChannel, Type contract)
- {
- return new ClientTelemetryRequestChannel(
- new ClientChannelManager(new TelemetryClient(), contract),
- innerChannel
- );
- }
- internal override IRequestChannel GetChannel(IChannelManager manager, IChannel innerChannel)
- {
- return new ClientTelemetryRequestChannel(manager, innerChannel);
- }
+ private const string TwoWayOp1 = "http://tempuri.org/ISimpleService/GetSimpleData";
+ private const string TwoWayOp2 = "http://tempuri.org/ISimpleService/CallFailsWithFault";
+ private const string OneWayOp1 = "http://tempuri.org/IOneWayService/SuccessfullOneWayCall";
- //
+ // ----------------------------------
// Request Telemetry
- //
+ // ----------------------------------
[TestMethod]
[TestCategory("Client")]
public void WhenRequestIsSent_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var response = channel.Request(BuildMessage(TwoWayOp1));
@@ -52,7 +39,7 @@ public void WhenRequestIsSentWithTimeout_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var response = channel.Request(BuildMessage(TwoWayOp1), TimeSpan.FromSeconds(10));
@@ -65,7 +52,7 @@ public void WhenRequestIsSent_TelemetryIsWritten_SoapFault()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
innerChannel.ReturnSoapFault = true;
@@ -81,7 +68,7 @@ public void WhenRequestIsSent_TelemetryIsWritten_Exception()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
innerChannel.FailRequest = true;
@@ -89,9 +76,12 @@ public void WhenRequestIsSent_TelemetryIsWritten_Exception()
try
{
var response = channel.Request(BuildMessage(TwoWayOp1));
- } catch {
+ }
+ catch
+ {
failed = true;
}
+
Assert.IsTrue(failed, "Request did not throw an exception");
CheckOpDependencyWritten(DependencyConstants.WcfClientCall, typeof(ISimpleService), TwoWayOp1, "GetSimpleData", false);
}
@@ -102,7 +92,7 @@ public void WhenRequestIsSentWithTimeout_TelemetryIsWritten_Exception()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
innerChannel.FailRequest = true;
@@ -110,9 +100,12 @@ public void WhenRequestIsSentWithTimeout_TelemetryIsWritten_Exception()
try
{
var response = channel.Request(BuildMessage(TwoWayOp1), TimeSpan.FromSeconds(10));
- } catch {
+ }
+ catch
+ {
failed = true;
}
+
Assert.IsTrue(failed, "Request did not throw an exception");
CheckOpDependencyWritten(DependencyConstants.WcfClientCall, typeof(ISimpleService), TwoWayOp1, "GetSimpleData", false);
}
@@ -123,7 +116,7 @@ public void WhenRequestIsSent_Async_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var result = channel.BeginRequest(BuildMessage(TwoWayOp1), null, null);
var response = channel.EndRequest(result);
@@ -137,7 +130,7 @@ public void WhenRequestIsSent_AsyncWithTimeout_TelemetryIsWritten()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
var result = channel.BeginRequest(BuildMessage(TwoWayOp1), TimeSpan.FromSeconds(10), null, null);
var response = channel.EndRequest(result);
@@ -151,7 +144,7 @@ public void WhenRequestIsSent_Async_TelemetryIsWritten_Exception()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
innerChannel.FailRequest = true;
@@ -159,11 +152,12 @@ public void WhenRequestIsSent_Async_TelemetryIsWritten_Exception()
try
{
var result = channel.BeginRequest(BuildMessage(TwoWayOp1), null, null);
-
- } catch
+ }
+ catch
{
failed = true;
}
+
Assert.IsTrue(failed, "BeginRequest did not throw an exception");
CheckOpDependencyWritten(DependencyConstants.WcfClientCall, typeof(ISimpleService), TwoWayOp1, "GetSimpleData", false);
@@ -175,7 +169,7 @@ public void WhenRequestIsSent_AsyncWithTimeout_TelemetryIsWritten_Exception()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
innerChannel.FailRequest = true;
@@ -183,11 +177,12 @@ public void WhenRequestIsSent_AsyncWithTimeout_TelemetryIsWritten_Exception()
try
{
var result = channel.BeginRequest(BuildMessage(TwoWayOp1), TimeSpan.FromSeconds(10), null, null);
-
- } catch
+ }
+ catch
{
failed = true;
}
+
Assert.IsTrue(failed, "BeginRequest did not throw an exception");
CheckOpDependencyWritten(DependencyConstants.WcfClientCall, typeof(ISimpleService), TwoWayOp1, "GetSimpleData", false);
@@ -199,7 +194,7 @@ public void WhenRequestIsSent_Async_TelemetryIsWritten_ExceptionOnEnd()
{
var innerChannel = new MockClientChannel(SvcUrl);
TestTelemetryChannel.Clear();
- var channel = GetChannel(innerChannel, typeof(ISimpleService));
+ var channel = this.GetChannel(innerChannel, typeof(ISimpleService));
innerChannel.FailEndRequest = true;
@@ -208,27 +203,39 @@ public void WhenRequestIsSent_Async_TelemetryIsWritten_ExceptionOnEnd()
try
{
var response = channel.EndRequest(result);
- } catch
+ }
+ catch
{
failed = true;
}
+
Assert.IsTrue(failed, "EndRequest did not throw an exception");
CheckOpDependencyWritten(DependencyConstants.WcfClientCall, typeof(ISimpleService), TwoWayOp1, "GetSimpleData", false);
}
+ internal override IRequestChannel GetChannel(IChannel innerChannel, Type contract)
+ {
+ return new ClientTelemetryRequestChannel(
+ new ClientChannelManager(new TelemetryClient(), contract),
+ innerChannel);
+ }
+ internal override IRequestChannel GetChannel(IChannelManager manager, IChannel innerChannel)
+ {
+ return new ClientTelemetryRequestChannel(manager, innerChannel);
+ }
- private Message BuildMessage(String action)
+ private static Message BuildMessage(string action)
{
return Message.CreateMessage(MessageVersion.Default, action, "");
}
- private DependencyTelemetry CheckOpDependencyWritten(String type, Type contract, String action, String method, bool success)
+ private static DependencyTelemetry CheckOpDependencyWritten(string type, Type contract, string action, string method, bool success)
{
var dependency = TestTelemetryChannel.CollectedData().OfType().FirstOrDefault();
Assert.IsNotNull(dependency, "Did not write dependency event");
- Assert.AreEqual(SvcUrl, dependency.Data);
+ Assert.AreEqual(ClientTelemetryRequestChannelTests.SvcUrl, dependency.Data);
Assert.AreEqual("localhost", dependency.Target);
Assert.AreEqual(type, dependency.Type);
Assert.AreEqual(contract.Name + "." + method, dependency.Name);
diff --git a/WCF/Shared.Tests/ContractDescriptionBuilder.cs b/WCF/Shared.Tests/ContractDescriptionBuilder.cs
index 687cef8..46dd788 100644
--- a/WCF/Shared.Tests/ContractDescriptionBuilder.cs
+++ b/WCF/Shared.Tests/ContractDescriptionBuilder.cs
@@ -1,11 +1,11 @@
-using System;
-using System.Globalization;
-using System.Reflection;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
- class ContractBuilder
+ using System;
+ using System.Globalization;
+ using System.Reflection;
+ using System.ServiceModel.Description;
+
+ internal class ContractBuilder
{
public static ContractDescription CreateDescription(Type contractType, Type serviceType)
{
@@ -16,10 +16,10 @@ public static ContractDescription CreateDescription(Type contractType, Type serv
return (ContractDescription)typeLoaderType.InvokeMember(
"LoadContractDescription",
BindingFlags.InvokeMethod,
- null, typeLoader,
+ null,
+ typeLoader,
new object[] { contractType, serviceType },
- CultureInfo.InvariantCulture
- );
+ CultureInfo.InvariantCulture);
}
}
}
diff --git a/WCF/Shared.Tests/ContractFilterTests.cs b/WCF/Shared.Tests/ContractFilterTests.cs
index 9d1cc3d..2851a3f 100644
--- a/WCF/Shared.Tests/ContractFilterTests.cs
+++ b/WCF/Shared.Tests/ContractFilterTests.cs
@@ -1,11 +1,11 @@
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Description;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ContractFilterTests
{
@@ -13,26 +13,25 @@ public class ContractFilterTests
public void WhenNoOpsInAnyContractAreInstrumentedShouldProcessReturnsTrue()
{
ContractDescription contract1 = ContractBuilder.CreateDescription(
- typeof(ISimpleService), typeof(SimpleService)
- );
+ typeof(ISimpleService), typeof(SimpleService));
ContractDescription contract2 = ContractBuilder.CreateDescription(
- typeof(ISimpleService2), typeof(SimpleService)
- );
+ typeof(ISimpleService2), typeof(SimpleService));
ContractFilter filter = new ContractFilter(new[] { contract1, contract2 });
- foreach ( var operation in contract1.Operations )
+ foreach (var operation in contract1.Operations)
{
Assert.IsTrue(
filter.ShouldProcess(contract1.Name, contract1.Namespace, operation.Name),
- "Operation {0} not processed", operation.Name
- );
+ "Operation {0} not processed",
+ operation.Name);
}
- foreach ( var operation in contract2.Operations )
+
+ foreach (var operation in contract2.Operations)
{
Assert.IsTrue(
filter.ShouldProcess(contract2.Name, contract2.Namespace, operation.Name),
- "Operation {0} not processed", operation.Name
- );
+ "Operation {0} not processed",
+ operation.Name);
}
}
@@ -40,44 +39,40 @@ public void WhenNoOpsInAnyContractAreInstrumentedShouldProcessReturnsTrue()
public void WhenOpsInOneContractAreInstrumentedShouldProcessReturnsTrueForAllInstrumented()
{
ContractDescription contract1 = ContractBuilder.CreateDescription(
- typeof(ISimpleService), typeof(SimpleService)
- );
+ typeof(ISimpleService), typeof(SimpleService));
ContractDescription contract2 = ContractBuilder.CreateDescription(
- typeof(ISelectiveTelemetryService), typeof(SelectiveTelemetryService)
- );
+ typeof(ISelectiveTelemetryService), typeof(SelectiveTelemetryService));
// Only check contract 1 operations
ContractFilter filter = new ContractFilter(new[] { contract1, contract2 });
- foreach ( var operation in contract1.Operations )
+ foreach (var operation in contract1.Operations)
{
Assert.IsTrue(
filter.ShouldProcess(contract1.Name, contract1.Namespace, operation.Name),
- "Operation {0} not processed", operation.Name
- );
+ "Operation {0} not processed",
+ operation.Name);
}
// Check instrumented operation in second contract
Assert.IsTrue(
filter.ShouldProcess(contract2.Name, contract2.Namespace, "OperationWithTelemetry"),
- "Operation {0} not processed", "OperationWithTelemetry"
- );
-
+ "Operation {0} not processed",
+ "OperationWithTelemetry");
}
[TestMethod]
public void WhenOpsInOneContractAreInstrumentedShouldProcessReturnsFalseForAllInstrumented()
{
ContractDescription contract1 = ContractBuilder.CreateDescription(
- typeof(ISimpleService), typeof(SimpleService)
- );
+ typeof(ISimpleService), typeof(SimpleService));
ContractDescription contract2 = ContractBuilder.CreateDescription(
typeof(ISelectiveTelemetryService), typeof(SelectiveTelemetryService));
ContractFilter filter = new ContractFilter(new[] { contract1, contract2 });
Assert.IsFalse(
filter.ShouldProcess(contract2.Name, contract2.Namespace, "OperationWithoutTelemetry"),
- "Operation {0} is processed", "OperationWithoutTelemetry"
- );
+ "Operation {0} is processed",
+ "OperationWithoutTelemetry");
}
}
}
diff --git a/WCF/Shared.Tests/Integration/AsyncStackTests.cs b/WCF/Shared.Tests/Integration/AsyncStackTests.cs
index 2095fa1..9da97f4 100644
--- a/WCF/Shared.Tests/Integration/AsyncStackTests.cs
+++ b/WCF/Shared.Tests/Integration/AsyncStackTests.cs
@@ -1,12 +1,12 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
{
+ using System;
+ using System.Linq;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
#if NET45
[TestClass]
public class AsyncStackTests
@@ -16,7 +16,7 @@ public class AsyncStackTests
public void TelemetryEventsAreGeneratedOnAsyncCall()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
IAsyncService client = host.GetChannel();
@@ -32,17 +32,19 @@ public void ErrorTelemetryEventsAreGeneratedOnAsyncFault()
TestTelemetryChannel.Clear();
var host = new HostingContext()
.ShouldWaitForCompletion();
- using ( host )
+ using (host)
{
host.Open();
IAsyncService client = host.GetChannel();
try
{
client.FailWithFaultAsync().Wait();
- } catch
+ }
+ catch
{
}
}
+
var errors = from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item;
@@ -56,17 +58,19 @@ public void ErrorTelemetryEventsContainAllDataOnAsyncCall()
TestTelemetryChannel.Clear();
var host = new HostingContext()
.ShouldWaitForCompletion();
- using ( host )
+ using (host)
{
host.Open();
IAsyncService client = host.GetChannel();
try
{
client.FailWithFaultAsync().Wait();
- } catch
+ }
+ catch
{
}
}
+
var error = (from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item).Cast().First();
@@ -82,17 +86,19 @@ public void ErrorTelemetryEventsAreGeneratedOnAsyncExceptionAndIEDIF_False()
TestTelemetryChannel.Clear();
var host = new HostingContext()
.ShouldWaitForCompletion();
- using ( host )
+ using (host)
{
host.Open();
IAsyncService client = host.GetChannel();
try
{
client.FailWithExceptionAsync().Wait();
- } catch
+ }
+ catch
{
}
}
+
var errors = from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item;
@@ -107,17 +113,19 @@ public void ErrorTelemetryEventsAreGeneratedOnAsyncExceptionAndIEDIF_True()
var host = new HostingContext()
.ShouldWaitForCompletion()
.IncludeDetailsInFaults();
- using ( host )
+ using (host)
{
host.Open();
IAsyncService client = host.GetChannel();
try
{
client.FailWithExceptionAsync().Wait();
- } catch
+ }
+ catch
{
}
}
+
var errors = from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item;
@@ -129,12 +137,13 @@ public void ErrorTelemetryEventsAreGeneratedOnAsyncExceptionAndIEDIF_True()
public void TelemetryContextIsFlowedAccrossAsyncCalls()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
IAsyncService client = host.GetChannel();
client.WriteDependencyEventAsync().Wait();
}
+
var data = TestTelemetryChannel.CollectedData();
var request = data
.OfType()
@@ -144,7 +153,6 @@ public void TelemetryContextIsFlowedAccrossAsyncCalls()
.FirstOrDefault();
Assert.AreEqual(request.Context.Operation.Id, dependency.Context.Operation.Id);
Assert.AreEqual(request.Context.Operation.Name, dependency.Context.Operation.Name);
-
}
}
#endif // NET45
diff --git a/WCF/Shared.Tests/Integration/HostingContext.cs b/WCF/Shared.Tests/Integration/HostingContext.cs
index 97674fd..f37b692 100644
--- a/WCF/Shared.Tests/Integration/HostingContext.cs
+++ b/WCF/Shared.Tests/Integration/HostingContext.cs
@@ -1,13 +1,13 @@
-using System;
-using System.Globalization;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-using System.ServiceModel.Description;
-using System.ServiceModel.Dispatcher;
-using System.Threading;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
{
+ using System;
+ using System.Globalization;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Description;
+ using System.ServiceModel.Dispatcher;
+ using System.Threading;
+
public sealed class HostingContext : IDisposable
where TServiceImpl : TServiceIFace
{
@@ -22,34 +22,35 @@ public sealed class HostingContext : IDisposable
public HostingContext()
{
- binding = new NetTcpBinding();
- baseAddress = new Uri(String.Format(CultureInfo.InvariantCulture, "net.tcp://localhost:57669/{0}/", Guid.NewGuid()));
+ this.binding = new NetTcpBinding();
+ this.baseAddress = new Uri(string.Format(CultureInfo.InvariantCulture, "net.tcp://localhost:57669/{0}/", Guid.NewGuid()));
- host = new ServiceHost(typeof(TServiceImpl), baseAddress);
- endpoint = host.AddServiceEndpoint(typeof(TServiceIFace), binding, "svc");
+ this.host = new ServiceHost(typeof(TServiceImpl), this.baseAddress);
+ this.endpoint = this.host.AddServiceEndpoint(typeof(TServiceIFace), this.binding, "svc");
}
- public String GetServiceAddress()
+ public string GetServiceAddress()
{
- return new Uri(baseAddress, new Uri("svc", UriKind.Relative)).ToString(); // endpoint.Address.Uri.ToString();
+ return new Uri(this.baseAddress, new Uri("svc", UriKind.Relative)).ToString(); // endpoint.Address.Uri.ToString();
}
public HostingContext IncludeDetailsInFaults()
{
- ServiceDebugBehavior sdb = host.Description.Behaviors.Find();
- if ( sdb == null )
+ var sdb = this.host.Description.Behaviors.Find();
+ if (sdb == null)
{
sdb = new ServiceDebugBehavior();
- host.Description.Behaviors.Add(sdb);
+ this.host.Description.Behaviors.Add(sdb);
}
+
sdb.IncludeExceptionDetailInFaults = true;
return this;
}
public HostingContext ShouldWaitForCompletion()
{
- completionWait = new EventWaitHandle(false, EventResetMode.ManualReset);
- endpoint.Behaviors.Add(new CompletionBehavior(completionWait));
+ this.completionWait = new EventWaitHandle(false, EventResetMode.ManualReset);
+ this.endpoint.Behaviors.Add(new CompletionBehavior(this.completionWait));
return this;
}
@@ -61,55 +62,61 @@ public String GetServiceAddress()
public void Open()
{
- host.Open();
+ this.host.Open();
- channelFactory = new ChannelFactory(binding, GetServiceAddress());
- channelFactory.Open();
+ this.channelFactory = new ChannelFactory(this.binding, this.GetServiceAddress());
+ this.channelFactory.Open();
}
public TServiceIFace GetChannel()
{
- if ( channel == null )
+ if (this.channel == null)
{
- channel = channelFactory.CreateChannel();
+ this.channel = this.channelFactory.CreateChannel();
}
- return channel;
+
+ return this.channel;
}
public void Dispose()
{
- if ( channel != null )
+ if (this.channel != null)
{
- Dispose((ICommunicationObject)channel);
- channel = default(TServiceIFace);
+ this.Dispose((ICommunicationObject)this.channel);
+ this.channel = default(TServiceIFace);
}
- if ( channelFactory != null )
+
+ if (this.channelFactory != null)
{
- Dispose(channelFactory);
- channelFactory = null;
+ this.Dispose(this.channelFactory);
+ this.channelFactory = null;
}
- if ( host != null )
+
+ if (this.host != null)
{
- Dispose(host);
- host = null;
+ this.Dispose(this.host);
+ this.host = null;
}
+
// WCF calls IErrorHandler on a background there
// by the time we've processed the reply and the
// ServiceHost has closed, it might not have gotten
// around to calling IErrorHander.HandleError()
-
- if ( completionWait != null )
- completionWait.WaitOne();
+ if (this.completionWait != null)
+ {
+ this.completionWait.WaitOne();
+ }
}
private void Dispose(ICommunicationObject obj)
{
- if ( expectFailure )
+ if (this.expectFailure)
{
obj.Abort();
return;
}
- switch ( obj.State )
+
+ switch (obj.State)
{
case CommunicationState.Created:
case CommunicationState.Opened:
@@ -127,12 +134,12 @@ private class CompletionBehavior : IErrorHandler, IEndpointBehavior
public CompletionBehavior(EventWaitHandle handle)
{
- completion = handle;
+ this.completion = handle;
}
public bool HandleError(Exception error)
{
- completion.Set();
+ this.completion.Set();
return false;
}
@@ -157,6 +164,5 @@ public void Validate(ServiceEndpoint endpoint)
{
}
}
-
}
}
diff --git a/WCF/Shared.Tests/Integration/MockClientChannel.cs b/WCF/Shared.Tests/Integration/MockClientChannel.cs
index 7e5a50a..3281b66 100644
--- a/WCF/Shared.Tests/Integration/MockClientChannel.cs
+++ b/WCF/Shared.Tests/Integration/MockClientChannel.cs
@@ -1,15 +1,34 @@
-using System;
-using System.Collections.Generic;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
{
- class MockClientChannel : IRequestChannel, IOutputChannel, IDuplexChannel
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.Threading;
+
+ internal class MockClientChannel : IRequestChannel, IOutputChannel, IDuplexChannel
{
+ public MockClientChannel(string remoteUrl)
+ {
+ this.RemoteAddress = new EndpointAddress(remoteUrl);
+ this.ChangeState(CommunicationState.Created);
+ }
+
+ public event EventHandler Closed;
+
+ public event EventHandler Closing;
+
+ public event EventHandler Faulted;
+
+ public event EventHandler Opened;
+
+ public event EventHandler Opening;
+
+ public event EventHandler UnknownMessageReceived
+ {
+ add { }
+ remove { }
+ }
+
public EndpointAddress LocalAddress { get; private set; }
public TimeSpan OperationTimeout { get; set; }
@@ -22,141 +41,109 @@ class MockClientChannel : IRequestChannel, IOutputChannel, IDuplexChannel
public Uri Via { get; private set; }
- public event EventHandler Closed;
- public event EventHandler Closing;
- public event EventHandler Faulted;
- public event EventHandler Opened;
- public event EventHandler Opening;
- public event EventHandler UnknownMessageReceived { add { } remove { } }
-
public bool FailOpen { get; set; }
+
public bool FailBeginOpen { get; set; }
+
public bool ReturnSoapFault { get; set; }
+
public bool FailRequest { get; set; }
+
public bool FailEndRequest { get; set; }
+
public Message LastMessageSent { get; private set; }
- public Message MessageToReceive { get; set; }
- public Exception ExceptionToThrowOnSend { get; set; }
+ public Message MessageToReceive { get; set; }
- public MockClientChannel(String remoteUrl)
- {
- this.RemoteAddress = new EndpointAddress(remoteUrl);
- ChangeState(CommunicationState.Created);
- }
+ public Exception ExceptionToThrowOnSend { get; set; }
public void Open()
{
- SimulateOpen(TimeSpan.MaxValue, FailOpen);
- if ( FailOpen )
- {
- throw new EndpointNotFoundException();
- }
+ this.Open(TimeSpan.MaxValue);
}
+
public void Open(TimeSpan timeout)
{
- SimulateOpen(TimeSpan.Zero, FailOpen);
- if ( FailOpen )
+ this.SimulateOpen(TimeSpan.Zero, this.FailOpen);
+ if (this.FailOpen)
{
throw new EndpointNotFoundException();
}
}
+
public void SimulateOpen(TimeSpan duration, bool fail)
{
- ChangeState(CommunicationState.Opening);
- if ( !fail )
+ this.ChangeState(CommunicationState.Opening);
+ if (!fail)
{
- ChangeState(CommunicationState.Opened);
- } else
+ this.ChangeState(CommunicationState.Opened);
+ }
+ else
{
- ChangeState(CommunicationState.Faulted);
+ this.ChangeState(CommunicationState.Faulted);
}
}
public void Close()
{
- Close(TimeSpan.MaxValue);
+ this.Close(TimeSpan.MaxValue);
}
public void Close(TimeSpan timeout)
{
- ChangeState(CommunicationState.Closing);
- ChangeState(CommunicationState.Closed);
+ this.ChangeState(CommunicationState.Closing);
+ this.ChangeState(CommunicationState.Closed);
}
public void Abort()
{
- Close();
+ this.Close();
}
public void Dispose()
{
- Close();
+ this.Close();
}
public bool OpeningIsHooked()
{
- return Opening != null && Opening.GetInvocationList().Length > 0;
+ return this.Opening != null && this.Opening.GetInvocationList().Length > 0;
}
+
public bool OpenedIsHooked()
{
- return Opened != null && Opened.GetInvocationList().Length > 0;
+ return this.Opened != null && this.Opened.GetInvocationList().Length > 0;
}
+
public bool ClosingIsHooked()
{
- return Closing != null && Closing.GetInvocationList().Length > 0;
+ return this.Closing != null && this.Closing.GetInvocationList().Length > 0;
}
+
public bool ClosedIsHooked()
{
- return Closed != null && Closed.GetInvocationList().Length > 0;
- }
- public bool FaultedIsHooked()
- {
- return Faulted != null && Faulted.GetInvocationList().Length > 0;
+ return this.Closed != null && this.Closed.GetInvocationList().Length > 0;
}
- private void ChangeState(CommunicationState state)
+ public bool FaultedIsHooked()
{
- this.State = state;
- switch ( state )
- {
- case CommunicationState.Opening:
- Opening?.Invoke(this, EventArgs.Empty);
- break;
- case CommunicationState.Opened:
- Opened?.Invoke(this, EventArgs.Empty);
- break;
- case CommunicationState.Closing:
- Closing?.Invoke(this, EventArgs.Empty);
- break;
- case CommunicationState.Closed:
- Closed?.Invoke(this, EventArgs.Empty);
- break;
- case CommunicationState.Faulted:
- Faulted?.Invoke(this, EventArgs.Empty);
- break;
- }
+ return this.Faulted != null && this.Faulted.GetInvocationList().Length > 0;
}
public IAsyncResult BeginOpen(AsyncCallback callback, object state)
{
- ChangeState(CommunicationState.Opening);
- if ( FailBeginOpen )
- {
- ChangeState(CommunicationState.Faulted);
- throw new EndpointNotFoundException();
- }
- return new SyncAsyncResult(callback, state);
+ return this.BeginOpen(TimeSpan.MaxValue, callback, state);
}
public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
- ChangeState(CommunicationState.Opening);
- if ( FailBeginOpen )
+ this.ChangeState(CommunicationState.Opening);
+ if (this.FailBeginOpen)
{
- ChangeState(CommunicationState.Faulted);
+ this.ChangeState(CommunicationState.Faulted);
throw new EndpointNotFoundException();
}
+
return new SyncAsyncResult(callback, state);
}
@@ -188,132 +175,119 @@ public void EndClose(IAsyncResult result)
// request channel methods
public Message Request(Message message)
{
- return Request(message, TimeSpan.FromSeconds(10));
+ return this.Request(message, TimeSpan.FromSeconds(10));
}
public Message Request(Message message, TimeSpan timeout)
{
- if ( FailRequest)
+ if (this.FailRequest)
{
throw new TimeoutException();
}
- return BuildMessage(message.Headers.Action);
+
+ return this.BuildMessage(message.Headers.Action);
}
public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
{
- return BeginRequest(message, TimeSpan.FromSeconds(10), callback, state);
+ return this.BeginRequest(message, TimeSpan.FromSeconds(10), callback, state);
}
public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
- LastMessageSent = message;
- if ( FailRequest )
+ this.LastMessageSent = message;
+ if (this.FailRequest)
{
- if ( ExceptionToThrowOnSend != null )
+ if (this.ExceptionToThrowOnSend != null)
{
- throw ExceptionToThrowOnSend;
+ throw this.ExceptionToThrowOnSend;
}
+
throw new TimeoutException();
}
+
return new SyncAsyncResult(callback, state);
}
public Message EndRequest(IAsyncResult result)
{
((SyncAsyncResult)result).End();
- if ( FailEndRequest )
+ if (this.FailEndRequest)
{
throw new TimeoutException();
}
- return BuildMessage("*");
- }
+ return this.BuildMessage("*");
+ }
- //
+ // -----------------------------------
// Output Channel Impl
- //
+ // -----------------------------------
public void Send(Message message)
{
- Send(message, TimeSpan.FromSeconds(10));
+ this.Send(message, TimeSpan.FromSeconds(10));
}
public void Send(Message message, TimeSpan timeout)
{
- LastMessageSent = message;
- if ( FailRequest )
+ this.LastMessageSent = message;
+ if (this.FailRequest)
{
- if ( ExceptionToThrowOnSend != null )
+ if (this.ExceptionToThrowOnSend != null)
{
- throw ExceptionToThrowOnSend;
+ throw this.ExceptionToThrowOnSend;
}
+
throw new TimeoutException();
}
}
public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
{
- return BeginSend(message, TimeSpan.FromSeconds(10), callback, state);
+ return this.BeginSend(message, TimeSpan.FromSeconds(10), callback, state);
}
public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
- LastMessageSent = message;
- if ( FailRequest )
+ this.LastMessageSent = message;
+ if (this.FailRequest)
{
throw new TimeoutException();
}
+
return new SyncAsyncResult(callback, state);
}
public void EndSend(IAsyncResult result)
{
- if ( FailEndRequest )
+ if (this.FailEndRequest)
{
throw new TimeoutException();
}
- ((SyncAsyncResult)result).End();
- }
-
- private Message BuildMessage(String action)
- {
- if ( ReturnSoapFault )
- {
- return BuildFaultMessage(action);
- }
- return Message.CreateMessage(MessageVersion.Default, action, "");
- }
- private Message BuildFaultMessage(String action)
- {
- return Message.CreateMessage(
- MessageVersion.Default,
- MessageFault.CreateFault(
- FaultCode.CreateReceiverFaultCode("e1", "http://tempuri.org"),
- "There was an error processing the message"
- ),
- action);
+ ((SyncAsyncResult)result).End();
}
- //
- //
+ // -------------------------------------------
// IDuplexChannel fields
- //
+ // -------------------------------------------
public Message Receive()
{
- if ( MessageToReceive != null )
+ if (this.MessageToReceive != null)
{
- return MessageToReceive;
+ return this.MessageToReceive;
}
+
throw new TimeoutException();
}
public Message Receive(TimeSpan timeout)
{
- if ( MessageToReceive != null )
+ if (this.MessageToReceive != null)
{
- return MessageToReceive;
+ return this.MessageToReceive;
}
+
throw new TimeoutException();
}
@@ -330,16 +304,17 @@ public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, objec
public Message EndReceive(IAsyncResult result)
{
((SyncAsyncResult)result).End();
- if ( MessageToReceive != null )
+ if (this.MessageToReceive != null)
{
- return MessageToReceive;
+ return this.MessageToReceive;
}
+
throw new TimeoutException();
}
public bool TryReceive(TimeSpan timeout, out Message message)
{
- message = MessageToReceive;
+ message = this.MessageToReceive;
return message != null;
}
@@ -351,13 +326,13 @@ public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, ob
public bool EndTryReceive(IAsyncResult result, out Message message)
{
((SyncAsyncResult)result).End();
- message = MessageToReceive;
+ message = this.MessageToReceive;
return message != null;
}
public bool WaitForMessage(TimeSpan timeout)
{
- return MessageToReceive != null;
+ return this.MessageToReceive != null;
}
public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
@@ -368,54 +343,100 @@ public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback
public bool EndWaitForMessage(IAsyncResult result)
{
((SyncAsyncResult)result).End();
- return MessageToReceive != null;
+ return this.MessageToReceive != null;
}
- class SyncAsyncResult : IAsyncResult, IDisposable
+ private void ChangeState(CommunicationState state)
{
- private EventWaitHandle waitHandle;
- private AsyncCallback callback;
- private Timer timer;
- public object AsyncState { get; private set; }
+ this.State = state;
+ switch (state)
+ {
+ case CommunicationState.Opening:
+ this.Opening?.Invoke(this, EventArgs.Empty);
+ break;
+ case CommunicationState.Opened:
+ this.Opened?.Invoke(this, EventArgs.Empty);
+ break;
+ case CommunicationState.Closing:
+ this.Closing?.Invoke(this, EventArgs.Empty);
+ break;
+ case CommunicationState.Closed:
+ this.Closed?.Invoke(this, EventArgs.Empty);
+ break;
+ case CommunicationState.Faulted:
+ this.Faulted?.Invoke(this, EventArgs.Empty);
+ break;
+ }
+ }
- public WaitHandle AsyncWaitHandle { get { return waitHandle; } }
+ private Message BuildMessage(string action)
+ {
+ if (this.ReturnSoapFault)
+ {
+ return this.BuildFaultMessage(action);
+ }
- public bool CompletedSynchronously { get; private set; }
+ return Message.CreateMessage(MessageVersion.Default, action, "");
+ }
- public bool IsCompleted { get; private set; }
+ private Message BuildFaultMessage(string action)
+ {
+ var fault = MessageFault.CreateFault(
+ FaultCode.CreateReceiverFaultCode("e1", "http://tempuri.org"),
+ "There was an error processing the message");
+ return Message.CreateMessage(MessageVersion.Default, fault, action);
+ }
+
+ private class SyncAsyncResult : IAsyncResult, IDisposable
+ {
+ private EventWaitHandle waitHandle;
+ private AsyncCallback callback;
+ private Timer timer;
public SyncAsyncResult(AsyncCallback callback, object state)
{
this.AsyncState = state;
this.callback = callback;
- waitHandle = new ManualResetEvent(false);
- CompletedSynchronously = false;
- IsCompleted = false;
- timer = new Timer(this.OnDone, null, TimeSpan.FromMilliseconds(10), TimeSpan.FromMilliseconds(-1));
+ this.waitHandle = new ManualResetEvent(false);
+ this.CompletedSynchronously = false;
+ this.IsCompleted = false;
+ this.timer = new Timer(this.OnDone, null, TimeSpan.FromMilliseconds(10), TimeSpan.FromMilliseconds(-1));
+ }
+
+ public object AsyncState { get; private set; }
+
+ public WaitHandle AsyncWaitHandle
+ {
+ get { return this.waitHandle; }
}
+ public bool CompletedSynchronously { get; private set; }
+
+ public bool IsCompleted { get; private set; }
+
public void End()
{
this.waitHandle.WaitOne();
this.waitHandle.Close();
this.timer.Dispose();
}
+
+ void IDisposable.Dispose()
+ {
+ this.End();
+ }
+
private void Complete()
{
this.IsCompleted = true;
this.waitHandle.Set();
- callback?.Invoke(this);
+ this.callback?.Invoke(this);
}
private void OnDone(object state)
{
this.Complete();
}
-
- void IDisposable.Dispose()
- {
- this.End();
- }
}
}
}
diff --git a/WCF/Shared.Tests/Integration/MultipleServiceCallsTests.cs b/WCF/Shared.Tests/Integration/MultipleServiceCallsTests.cs
index 270e997..e9052ae 100644
--- a/WCF/Shared.Tests/Integration/MultipleServiceCallsTests.cs
+++ b/WCF/Shared.Tests/Integration/MultipleServiceCallsTests.cs
@@ -1,10 +1,10 @@
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
{
+ using System;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class MultipleServiceCallsTests
{
@@ -13,8 +13,8 @@ public class MultipleServiceCallsTests
public void OperationMethodThatCallsAnotherServiceDoesNotLoseOperationContext()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
- using ( var hostSecond = new HostingContext() )
+ using (var host = new HostingContext())
+ using (var hostSecond = new HostingContext())
{
host.IncludeDetailsInFaults();
host.Open();
@@ -24,6 +24,5 @@ public void OperationMethodThatCallsAnotherServiceDoesNotLoseOperationContext()
Assert.IsTrue(TestTelemetryChannel.CollectedData().Count > 0);
}
}
-
}
}
diff --git a/WCF/Shared.Tests/Integration/OneWayTests.cs b/WCF/Shared.Tests/Integration/OneWayTests.cs
index 02a2a20..3964f34 100644
--- a/WCF/Shared.Tests/Integration/OneWayTests.cs
+++ b/WCF/Shared.Tests/Integration/OneWayTests.cs
@@ -1,12 +1,12 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
{
+ using System;
+ using System.Linq;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class OneWayTests
{
@@ -15,12 +15,13 @@ public class OneWayTests
public void SuccessfulOneWayCallGeneratesRequestEvent()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
IOneWayService client = host.GetChannel();
client.SuccessfullOneWayCall();
}
+
var req = TestTelemetryChannel.CollectedData()
.FirstOrDefault(x => x is RequestTelemetry);
@@ -34,17 +35,19 @@ public void FailedOneWayCallGeneratesExceptionEvent()
TestTelemetryChannel.Clear();
var host = new HostingContext()
.ExpectFailure().ShouldWaitForCompletion();
- using ( host )
+ using (host)
{
host.Open();
IOneWayService client = host.GetChannel();
try
{
client.FailureOneWayCall();
- } catch
+ }
+ catch
{
}
}
+
var req = TestTelemetryChannel.CollectedData()
.FirstOrDefault(x => x is ExceptionTelemetry);
diff --git a/WCF/Shared.Tests/Integration/OperationContextExtensionsTests.cs b/WCF/Shared.Tests/Integration/OperationContextExtensionsTests.cs
index 2eaaceb..834efca 100644
--- a/WCF/Shared.Tests/Integration/OperationContextExtensionsTests.cs
+++ b/WCF/Shared.Tests/Integration/OperationContextExtensionsTests.cs
@@ -1,12 +1,19 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
{
+ using System;
+ using System.ServiceModel;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class OperationContextExtensionsTests
{
+ [ServiceContract]
+ public interface IContextCheckService
+ {
+ [OperationContract]
+ bool CanGetRequestTelemetry();
+ }
+
[TestMethod]
public void WhenOperationContextIsNullReturnsNull()
{
@@ -18,11 +25,11 @@ public void WhenOperationContextIsNullReturnsNull()
[TestCategory("Integration")]
public void WhenOperationContextIsClientContextReturnsNull()
{
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
var client = host.GetChannel();
- using ( var scope = new OperationContextScope((IContextChannel)client) )
+ using (var scope = new OperationContextScope((IContextChannel)client))
{
Assert.IsNull(OperationContext.Current.GetRequestTelemetry());
}
@@ -33,27 +40,19 @@ public void WhenOperationContextIsClientContextReturnsNull()
[TestCategory("Integration")]
public void WhenOperationContextIsServiceContextReturnsRequest()
{
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
var client = host.GetChannel();
- using ( var scope = new OperationContextScope((IContextChannel)client) )
+ using (var scope = new OperationContextScope((IContextChannel)client))
{
Assert.IsTrue(client.CanGetRequestTelemetry());
}
}
}
-
- [ServiceContract]
- public interface IContextCheckService
- {
- [OperationContract]
- bool CanGetRequestTelemetry();
- }
-
[ServiceTelemetry]
- class ContextCheckService : IContextCheckService
+ internal class ContextCheckService : IContextCheckService
{
public bool CanGetRequestTelemetry()
{
diff --git a/WCF/Shared.Tests/Integration/SyncStackTests.cs b/WCF/Shared.Tests/Integration/SyncStackTests.cs
index 615002f..19be2a0 100644
--- a/WCF/Shared.Tests/Integration/SyncStackTests.cs
+++ b/WCF/Shared.Tests/Integration/SyncStackTests.cs
@@ -1,15 +1,15 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-using System.Xml;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
{
+ using System;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.Xml;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class FullStackTests
{
@@ -17,22 +17,23 @@ public class FullStackTests
[TestCategory("Integration"), TestCategory("Sync")]
public void IsClientSideContextReturnsTrueForClientChannel()
{
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
ISimpleService client = host.GetChannel();
- using ( var scope = new OperationContextScope((IContextChannel)client) )
+ using (var scope = new OperationContextScope((IContextChannel)client))
{
Assert.IsTrue(OperationContext.Current.IsClientSideContext());
}
}
}
+
[TestMethod]
[TestCategory("Integration"), TestCategory("Sync")]
public void IsClientSideContextReturnsFalseForServerChannel()
{
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
ISimpleService client = host.GetChannel();
@@ -46,7 +47,7 @@ public void IsClientSideContextReturnsFalseForServerChannel()
public void TelemetryEventsAreGeneratedOnServiceCall()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
ISimpleService client = host.GetChannel();
@@ -60,12 +61,13 @@ public void TelemetryEventsAreGeneratedOnServiceCall()
public void OperationNameIsSetBasedOnOperationCalled()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
ISimpleService client = host.GetChannel();
client.GetSimpleData();
}
+
var operationName = TestTelemetryChannel.CollectedData()
.Select(x => x.Context.Operation.Name)
.First();
@@ -78,12 +80,13 @@ public void OperationNameIsSetBasedOnOperationCalled()
public void AllTelemetryEventsFromOneCallHaveSameOperationId()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
ISimpleService client = host.GetChannel();
client.GetSimpleData();
}
+
var ids = TestTelemetryChannel.CollectedData()
.Select(x => x.Context.Operation.Id)
.Distinct();
@@ -97,22 +100,22 @@ public void CallWithUnknownActionReportsCatchAllOperation()
{
TestTelemetryChannel.Clear();
var host = new HostingContext();
- using ( host )
+ using (host)
{
host.Open();
ISimpleService client = host.GetChannel();
- using ( OperationContextScope scope = new OperationContextScope((IContextChannel)client) )
+ using (OperationContextScope scope = new OperationContextScope((IContextChannel)client))
{
OperationContext.Current.OutgoingMessageHeaders.Action = "http://someaction";
client.CatchAllOperation();
}
}
+
var evt = TestTelemetryChannel.CollectedData().First();
Assert.AreEqual("ISimpleService.CatchAllOperation", evt.Context.Operation.Name);
}
-
[TestMethod]
[TestCategory("Integration"), TestCategory("Sync")]
public void ErrorTelemetryEventsAreGeneratedOnFault()
@@ -120,17 +123,19 @@ public void ErrorTelemetryEventsAreGeneratedOnFault()
TestTelemetryChannel.Clear();
var host = new HostingContext()
.ShouldWaitForCompletion();
- using ( host )
+ using (host)
{
host.Open();
ISimpleService client = host.GetChannel();
try
{
client.CallFailsWithFault();
- } catch
+ }
+ catch
{
}
}
+
var errors = from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item;
@@ -144,17 +149,19 @@ public void ErrorTelemetryEventsContainDetailedInfo()
TestTelemetryChannel.Clear();
var host = new HostingContext()
.ShouldWaitForCompletion();
- using ( host )
+ using (host)
{
host.Open();
ISimpleService client = host.GetChannel();
try
{
client.CallFailsWithFault();
- } catch
+ }
+ catch
{
}
}
+
var error = (from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item).Cast().First();
@@ -170,17 +177,19 @@ public void ErrorTelemetryEventsContainDetailedInfoOnTypedFault()
TestTelemetryChannel.Clear();
var host = new HostingContext()
.ShouldWaitForCompletion();
- using ( host )
+ using (host)
{
host.Open();
ISimpleService client = host.GetChannel();
try
{
client.CallFailsWithTypedFault();
- } catch
+ }
+ catch
{
}
}
+
var error = (from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item).Cast().First();
@@ -189,7 +198,6 @@ public void ErrorTelemetryEventsContainDetailedInfoOnTypedFault()
Assert.IsNotNull(error.Context.Operation.Name);
}
-
[TestMethod]
[TestCategory("Integration"), TestCategory("Sync")]
public void ErrorTelemetryEventsAreGeneratedOnExceptionAndIEDIF_False()
@@ -197,17 +205,19 @@ public void ErrorTelemetryEventsAreGeneratedOnExceptionAndIEDIF_False()
TestTelemetryChannel.Clear();
var host = new HostingContext()
.ShouldWaitForCompletion();
- using ( host )
+ using (host)
{
host.Open();
ISimpleService client = host.GetChannel();
try
{
client.CallFailsWithException();
- } catch
+ }
+ catch
{
}
}
+
var errors = from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item;
@@ -222,7 +232,7 @@ public void ErrorTelemetryEventsAreGeneratedOnExceptionAndIEDIF_True()
var host = new HostingContext()
.ShouldWaitForCompletion()
.IncludeDetailsInFaults();
- using ( host )
+ using (host)
{
host.Open();
@@ -230,10 +240,12 @@ public void ErrorTelemetryEventsAreGeneratedOnExceptionAndIEDIF_True()
try
{
client.CallFailsWithException();
- } catch
+ }
+ catch
{
}
}
+
var errors = from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
select item;
@@ -245,7 +257,7 @@ public void ErrorTelemetryEventsAreGeneratedOnExceptionAndIEDIF_True()
public void TelemetryEventsEmittedInsideServiceCallContainExpectedContext()
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
ISimpleService client = host.GetChannel();
@@ -264,20 +276,20 @@ public void TelemetryEventsEmittedInsideServiceCallContainExpectedContext()
}
}
-
[TestMethod]
[TestCategory("Integration"), TestCategory("Sync")]
public void ErrorTelemetryEventsWrittenFromMethodAreLogged()
{
TestTelemetryChannel.Clear();
var host = new HostingContext();
- using ( host )
+ using (host)
{
host.Open();
ISimpleService client = host.GetChannel();
client.CallWritesExceptionEvent();
}
+
var request = TestTelemetryChannel.CollectedData().OfType().First();
var errors = from item in TestTelemetryChannel.CollectedData()
where item is ExceptionTelemetry
@@ -292,13 +304,14 @@ public void OperationMarksRequestAsFailedAndIsPropagated()
{
TestTelemetryChannel.Clear();
var host = new HostingContext();
- using ( host )
+ using (host)
{
host.Open();
ISimpleService client = host.GetChannel();
client.CallMarksRequestAsFailed();
}
+
var request = TestTelemetryChannel.CollectedData().OfType().First();
Assert.IsFalse(request.Success.Value);
}
@@ -309,13 +322,14 @@ public void CallsToOpMarkedWithOperationTelemetryGeneratesEvents()
{
TestTelemetryChannel.Clear();
var host = new HostingContext();
- using ( host )
+ using (host)
{
host.Open();
ISelectiveTelemetryService client = host.GetChannel();
client.OperationWithTelemetry();
}
+
Assert.IsTrue(TestTelemetryChannel.CollectedData().Count > 0);
}
@@ -325,13 +339,14 @@ public void CallsToOpWithoutOperationTelemetryGeneratesEvents()
{
TestTelemetryChannel.Clear();
var host = new HostingContext();
- using ( host )
+ using (host)
{
host.Open();
ISelectiveTelemetryService client = host.GetChannel();
client.OperationWithoutTelemetry();
}
+
Assert.AreEqual(0, TestTelemetryChannel.CollectedData().Count);
}
@@ -341,12 +356,12 @@ public void CallCanFlowRootOperationId()
{
TestTelemetryChannel.Clear();
var host = new HostingContext();
- using ( host )
+ using (host)
{
host.Open();
ISelectiveTelemetryService client = host.GetChannel();
- using ( var scope = new OperationContextScope((IContextChannel)client) )
+ using (var scope = new OperationContextScope((IContextChannel)client))
{
var rootId = new RootIdMessageHeader();
rootId.RootId = "rootId";
@@ -354,26 +369,28 @@ public void CallCanFlowRootOperationId()
client.OperationWithTelemetry();
}
}
+
Assert.AreEqual("rootId", TestTelemetryChannel.CollectedData().First().Context.Operation.Id);
}
public class RootIdMessageHeader : MessageHeader
{
- public override string Name {
+ public override string Name
+ {
get { return "requestRootId"; }
}
- public override string Namespace {
+ public override string Namespace
+ {
get { return "http://schemas.microsoft.com/application-insights"; }
}
- public String RootId { get; set; }
+ public string RootId { get; set; }
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
- writer.WriteString(RootId);
+ writer.WriteString(this.RootId);
}
}
-
}
}
diff --git a/WCF/Shared.Tests/Integration/TracingTests.cs b/WCF/Shared.Tests/Integration/TracingTests.cs
index 19054ca..4531d88 100644
--- a/WCF/Shared.Tests/Integration/TracingTests.cs
+++ b/WCF/Shared.Tests/Integration/TracingTests.cs
@@ -1,13 +1,13 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using System.Xml;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Integration
{
+ using System;
+ using System.Linq;
+ using System.Xml;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Channels;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class TracingTests
{
@@ -19,23 +19,26 @@ public void RequestIsTraced()
try
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
ISimpleService client = host.GetChannel();
client.GetSimpleData();
}
+
var trace = TestTelemetryChannel.CollectedData()
.OfType()
.FirstOrDefault(x => x.Name == "WcfRequest");
Assert.IsNotNull(trace, "No WcfRequest trace found");
XmlDocument doc = new XmlDocument();
doc.LoadXml(trace.Properties["Body"]);
- } finally
+ }
+ finally
{
TraceTelemetryModule.Disable();
}
}
+
[TestMethod]
[TestCategory("Integration"), TestCategory("MessageTracing")]
public void ResponseIsTraced()
@@ -44,19 +47,21 @@ public void ResponseIsTraced()
try
{
TestTelemetryChannel.Clear();
- using ( var host = new HostingContext() )
+ using (var host = new HostingContext())
{
host.Open();
ISimpleService client = host.GetChannel();
client.GetSimpleData();
}
+
var trace = TestTelemetryChannel.CollectedData()
.OfType()
.FirstOrDefault(x => x.Name == "WcfResponse");
Assert.IsNotNull(trace, "No WcfResponse trace found");
XmlDocument doc = new XmlDocument();
doc.LoadXml(trace.Properties["Body"]);
- } finally
+ }
+ finally
{
TraceTelemetryModule.Disable();
}
diff --git a/WCF/Shared.Tests/MessageCorrelatorTests.cs b/WCF/Shared.Tests/MessageCorrelatorTests.cs
index 2452e75..db893ad 100644
--- a/WCF/Shared.Tests/MessageCorrelatorTests.cs
+++ b/WCF/Shared.Tests/MessageCorrelatorTests.cs
@@ -1,12 +1,12 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Threading;
-using System.Xml;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Threading;
+ using System.Xml;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class MessageCorrelatorTests
{
@@ -19,10 +19,12 @@ public void WhenAddIsCalledWithNullId_ArgumentNullExceptionIsThrown()
try
{
correlator.Add(null, telemetry, TimeSpan.FromMilliseconds(100));
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "ArgumentNullException was not thrown");
}
@@ -34,14 +36,15 @@ public void WhenAddIsCalledWithNullTelemetry_ArgumentNullExceptionIsThrown()
try
{
correlator.Add(new UniqueId(), null, TimeSpan.FromMilliseconds(100));
- } catch ( ArgumentNullException )
+ }
+ catch (ArgumentNullException)
{
failed = true;
}
+
Assert.IsTrue(failed, "ArgumentNullException was not thrown");
}
-
[TestMethod]
public void WhenMessageIsAdded_TryLookupReturnsTrue()
{
@@ -84,8 +87,7 @@ public void WhenMessageIsAdded_AndNotRemoved_TimeoutCallbackIsFired()
timeoutId = messageId;
timeoutTelemetry = dependencyObj;
timeoutEvent.Set();
- }
- );
+ });
var telemetry = new DependencyTelemetry();
var id = new UniqueId();
@@ -104,8 +106,7 @@ public void WhenMessageIsAdded_AndRemoved_TimeoutCallbackIsNotFired()
(messageId, dependencyObj) =>
{
timeoutEvent.Set();
- }
- );
+ });
var telemetry = new DependencyTelemetry();
// add and remove right away
@@ -129,10 +130,12 @@ public void WhenDisposed_AddThrowsException()
try
{
correlator.Add(id, new DependencyTelemetry(), TimeSpan.FromMilliseconds(100));
- } catch ( ObjectDisposedException )
+ }
+ catch (ObjectDisposedException)
{
failed = true;
}
+
Assert.IsTrue(failed, "Add did not throw ObjectDisposedException");
}
}
diff --git a/WCF/Shared.Tests/MockOperationContext.cs b/WCF/Shared.Tests/MockOperationContext.cs
index e148e6a..025a5d8 100644
--- a/WCF/Shared.Tests/MockOperationContext.cs
+++ b/WCF/Shared.Tests/MockOperationContext.cs
@@ -1,35 +1,20 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Collections.Generic;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+
public class MockOperationContext : IOperationContext, IOperationContextState
{
- public IDictionary IncomingProperties { get; private set; }
- public IDictionary OutgoingProperties { get; private set; }
- public IDictionary IncomingHeaders { get; private set; }
- private Dictionary stateDictionary;
- public String OperationId { get { return Request.Id; } }
- public RequestTelemetry Request { get; private set; }
- public bool OwnsRequest { get; private set; }
- public Uri EndpointUri { get; set; }
- public Uri ToHeader { get; set; }
- public String OperationName { get; set; }
- public String ContractName { get; set; }
- public String ContractNamespace { get; set; }
- public ServiceSecurityContext SecurityContext { get; set; }
+ private Dictionary stateDictionary;
public MockOperationContext()
{
- this.IncomingProperties = new Dictionary();
- this.IncomingHeaders = new Dictionary();
- this.OutgoingProperties = new Dictionary();
+ this.IncomingProperties = new Dictionary();
+ this.IncomingHeaders = new Dictionary();
+ this.OutgoingProperties = new Dictionary();
this.ContractName = "IFakeService";
this.ContractNamespace = "urn:fake";
this.Request = new RequestTelemetry();
@@ -38,58 +23,89 @@ public MockOperationContext()
this.stateDictionary = new Dictionary();
}
+ public IDictionary IncomingProperties { get; private set; }
+
+ public IDictionary OutgoingProperties { get; private set; }
+
+ public IDictionary IncomingHeaders { get; private set; }
+
+ public string OperationId
+ {
+ get { return this.Request.Id; }
+ }
+
+ public RequestTelemetry Request { get; private set; }
+
+ public bool OwnsRequest { get; private set; }
+
+ public Uri EndpointUri { get; set; }
+
+ public Uri ToHeader { get; set; }
+
+ public string OperationName { get; set; }
+
+ public string ContractName { get; set; }
+
+ public string ContractNamespace { get; set; }
+
+ public ServiceSecurityContext SecurityContext { get; set; }
+
public bool HasIncomingMessageProperty(string propertyName)
{
- return IncomingProperties.ContainsKey(propertyName);
+ return this.IncomingProperties.ContainsKey(propertyName);
}
public object GetIncomingMessageProperty(string propertyName)
{
- return IncomingProperties[propertyName];
+ return this.IncomingProperties[propertyName];
}
- public bool HasOutgoingMessageProperty(String propertyName)
+ public bool HasOutgoingMessageProperty(string propertyName)
{
- return OutgoingProperties.ContainsKey(propertyName);
+ return this.OutgoingProperties.ContainsKey(propertyName);
}
- public object GetOutgoingMessageProperty(String propertyName)
+
+ public object GetOutgoingMessageProperty(string propertyName)
{
- return OutgoingProperties[propertyName];
+ return this.OutgoingProperties[propertyName];
}
- public T GetIncomingMessageHeader(String name, String ns)
+
+ public T GetIncomingMessageHeader(string name, string ns)
{
object value;
- if ( IncomingHeaders.TryGetValue(ns + "#" + name, out value) )
+ if (this.IncomingHeaders.TryGetValue(ns + "#" + name, out value))
{
return (T)value;
}
+
return default(T);
}
- public void AddIncomingMessageHeader(String name, String ns, T value)
+ public void AddIncomingMessageHeader(string name, string ns, T value)
{
- IncomingHeaders.Add(ns + "#" + name, value);
+ this.IncomingHeaders.Add(ns + "#" + name, value);
}
public void SetHttpHeaders(HttpRequestMessageProperty httpHeaders)
{
- IncomingProperties[HttpRequestMessageProperty.Name] = httpHeaders;
+ this.IncomingProperties[HttpRequestMessageProperty.Name] = httpHeaders;
}
public void SetState(string key, object value)
{
- stateDictionary.Add(key, value);
+ this.stateDictionary.Add(key, value);
}
public bool TryGetState(string key, out T value)
{
value = default(T);
object obj = null;
- if ( stateDictionary.TryGetValue(key, out obj) )
+ if (this.stateDictionary.TryGetValue(key, out obj))
{
value = (T)obj;
return true;
}
+
return false;
}
}
diff --git a/WCF/Shared.Tests/OperationCorrelationTelemetryInitializerTests.cs b/WCF/Shared.Tests/OperationCorrelationTelemetryInitializerTests.cs
index 54da39b..0ad84f9 100644
--- a/WCF/Shared.Tests/OperationCorrelationTelemetryInitializerTests.cs
+++ b/WCF/Shared.Tests/OperationCorrelationTelemetryInitializerTests.cs
@@ -1,9 +1,10 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class OperationCorrelationTelemetryInitializerTests
{
@@ -125,6 +126,5 @@ public void InitializeDoNotMakeRequestAParentOfItself()
Assert.AreEqual(null, requestTelemetry.Context.Operation.ParentId);
Assert.AreEqual(requestTelemetry.Id, requestTelemetry.Context.Operation.Id);
}
-
}
}
diff --git a/WCF/Shared.Tests/OperationFilterTests.cs b/WCF/Shared.Tests/OperationFilterTests.cs
index 755b0b6..aa382a6 100644
--- a/WCF/Shared.Tests/OperationFilterTests.cs
+++ b/WCF/Shared.Tests/OperationFilterTests.cs
@@ -1,12 +1,11 @@
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Reflection;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Description;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class OperationFilterTests
{
@@ -14,16 +13,16 @@ public class OperationFilterTests
public void WhenNoOpsAreInstrumentedShouldProcessReturnsTrue()
{
ContractDescription contract = ContractBuilder.CreateDescription(
- typeof(ISimpleService), typeof(SimpleService)
- );
+ typeof(ISimpleService),
+ typeof(SimpleService));
var filter = new OperationFilter(contract);
- foreach ( var operation in contract.Operations )
+ foreach (var operation in contract.Operations)
{
Assert.IsTrue(
filter.ShouldProcess(operation.Name),
- "Operation {0} not processed", operation.Name
- );
+ "Operation {0} not processed",
+ operation.Name);
}
}
@@ -31,29 +30,26 @@ public void WhenNoOpsAreInstrumentedShouldProcessReturnsTrue()
public void WhenAnOpIsInstrumentedShouldProcessReturnsTrue()
{
ContractDescription contract = ContractBuilder.CreateDescription(
- typeof(ISelectiveTelemetryService), typeof(SelectiveTelemetryService)
- );
+ typeof(ISelectiveTelemetryService),
+ typeof(SelectiveTelemetryService));
var filter = new OperationFilter(contract);
Assert.IsTrue(
filter.ShouldProcess("OperationWithTelemetry"),
- "ShouldProcessRequest('OperationWithTelemetry') returned false"
- );
+ "ShouldProcessRequest('OperationWithTelemetry') returned false");
}
[TestMethod]
public void WhenAnOpIsNotBeenInstrumentedShouldProcessReturnsFalse()
{
ContractDescription contract = ContractBuilder.CreateDescription(
- typeof(ISelectiveTelemetryService), typeof(SelectiveTelemetryService)
- );
+ typeof(ISelectiveTelemetryService),
+ typeof(SelectiveTelemetryService));
var filter = new OperationFilter(contract);
Assert.IsFalse(
filter.ShouldProcess("OperationWithoutTelemetry"),
- "ShouldProcessRequest('OperationWithoutTelemetry') returned true"
- );
+ "ShouldProcessRequest('OperationWithoutTelemetry') returned true");
}
-
}
}
diff --git a/WCF/Shared.Tests/OperationNameTelemetryInitializerTests.cs b/WCF/Shared.Tests/OperationNameTelemetryInitializerTests.cs
index 1ad0d08..01a0d8e 100644
--- a/WCF/Shared.Tests/OperationNameTelemetryInitializerTests.cs
+++ b/WCF/Shared.Tests/OperationNameTelemetryInitializerTests.cs
@@ -1,10 +1,10 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class OperationNameTelemetryInitializerTests
{
@@ -19,7 +19,7 @@ public void NonHttpEndpoint()
var telemetry = new RequestTelemetry();
initializer.Initialize(telemetry, context);
- String name = telemetry.Context.Operation.Name;
+ string name = telemetry.Context.Operation.Name;
Assert.AreEqual("IFakeService.GetData", name);
}
@@ -34,7 +34,7 @@ public void RequestNameEqualsOperationName()
var telemetry = new RequestTelemetry();
initializer.Initialize(telemetry, context);
- String name = telemetry.Context.Operation.Name;
+ string name = telemetry.Context.Operation.Name;
Assert.AreEqual(name, telemetry.Name);
}
@@ -53,25 +53,25 @@ public void HttpEndpointDoesNotHaveMethodInName()
var telemetry = new RequestTelemetry();
initializer.Initialize(telemetry, context);
- String name = telemetry.Context.Operation.Name;
+ string name = telemetry.Context.Operation.Name;
Assert.AreEqual(name, "IFakeService.GetData");
}
[TestMethod]
public void OperationNameIsCopiedFromRequestIfPresent()
{
- const String name = "MyOperationName";
+ const string Name = "MyOperationName";
var context = new MockOperationContext();
context.EndpointUri = new Uri("net.tcp://localhost/Service1.svc");
context.OperationName = "GetData";
- context.Request.Context.Operation.Name = name;
+ context.Request.Context.Operation.Name = Name;
var initializer = new OperationNameTelemetryInitializer();
var telemetry = new EventTelemetry();
initializer.Initialize(telemetry, context);
- Assert.AreEqual(name, telemetry.Context.Operation.Name);
+ Assert.AreEqual(Name, telemetry.Context.Operation.Name);
}
}
}
diff --git a/WCF/Shared.Tests/ProfilerWcfClientProcessingTests.cs b/WCF/Shared.Tests/ProfilerWcfClientProcessingTests.cs
index 343a235..43c1e9a 100644
--- a/WCF/Shared.Tests/ProfilerWcfClientProcessingTests.cs
+++ b/WCF/Shared.Tests/ProfilerWcfClientProcessingTests.cs
@@ -1,14 +1,14 @@
-using Microsoft.ApplicationInsights.Extensibility;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Tests.Service;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-using System.ServiceModel;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.ServiceModel.Description;
+ using Microsoft.ApplicationInsights.Extensibility;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Tests.Service;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class ProfilerWcfClientProcessingTests
{
@@ -17,7 +17,7 @@ public void WhenInitializeEndpoint1IsCalled_BehaviorIsAdded()
{
ServiceEndpoint endpoint = CreateEndpoint();
endpoint.Address = new EndpointAddress("http://localhost/Service1.svc");
- using ( ChannelFactory factory = new ChannelFactory(endpoint) )
+ using (ChannelFactory factory = new ChannelFactory(endpoint))
{
var module = new WcfDependencyTrackingTelemetryModule();
module.Initialize(TelemetryConfiguration.Active);
@@ -37,7 +37,7 @@ public void WhenInitializeEndpoint1IsCalled_AndBehaviorExists_BehaviorIsNotAdded
endpoint.Address = new EndpointAddress("http://localhost/Service1.svc");
endpoint.Behaviors.Add(new ClientTelemetryEndpointBehavior(TelemetryConfiguration.Active));
- using ( ChannelFactory factory = new ChannelFactory(endpoint) )
+ using (ChannelFactory factory = new ChannelFactory(endpoint))
{
var module = new WcfDependencyTrackingTelemetryModule();
module.Initialize(TelemetryConfiguration.Active);
@@ -55,7 +55,7 @@ public void WhenInitializeEndpoint2IsCalled_BehaviorIsAdded()
{
ServiceEndpoint endpoint = CreateEndpoint();
endpoint.Address = new EndpointAddress("http://localhost/Service1.svc");
- using ( ChannelFactory factory = new ChannelFactory(endpoint) )
+ using (ChannelFactory factory = new ChannelFactory(endpoint))
{
var module = new WcfDependencyTrackingTelemetryModule();
module.Initialize(TelemetryConfiguration.Active);
@@ -73,7 +73,7 @@ public void WhenInitializeEndpoint3IsCalled_BehaviorIsAdded()
{
ServiceEndpoint endpoint = CreateEndpoint();
endpoint.Address = new EndpointAddress("http://localhost/Service1.svc");
- using ( ChannelFactory factory = new ChannelFactory(endpoint) )
+ using (ChannelFactory factory = new ChannelFactory(endpoint))
{
var module = new WcfDependencyTrackingTelemetryModule();
module.Initialize(TelemetryConfiguration.Active);
@@ -86,7 +86,7 @@ public void WhenInitializeEndpoint3IsCalled_BehaviorIsAdded()
}
}
- private ServiceEndpoint CreateEndpoint()
+ private static ServiceEndpoint CreateEndpoint()
{
var contractDescription = ContractBuilder.CreateDescription(typeof(ISimpleService), typeof(SimpleService));
return new ServiceEndpoint(contractDescription);
diff --git a/WCF/Shared.Tests/Service/AsyncService.cs b/WCF/Shared.Tests/Service/AsyncService.cs
index 48ed971..b799b19 100644
--- a/WCF/Shared.Tests/Service/AsyncService.cs
+++ b/WCF/Shared.Tests/Service/AsyncService.cs
@@ -1,44 +1,46 @@
-using System;
-using System.IO;
-using System.ServiceModel;
-using System.Threading.Tasks;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+ using System.IO;
+ using System.ServiceModel;
+ using System.Threading.Tasks;
+
#if NET45
[ServiceTelemetry]
public class AsyncService : IAsyncService
{
- public async Task GetDataAsync()
+ public async Task GetDataAsync()
{
await Task.Delay(200);
return "Hello";
}
- public async Task FailWithFaultAsync()
+ public async Task FailWithFaultAsync()
{
await Task.Delay(200);
throw new FaultException("Call failed");
}
- public async Task FailWithExceptionAsync()
+ public async Task FailWithExceptionAsync()
{
await Task.Delay(200);
throw new InvalidOperationException();
}
- public async Task WriteDependencyEventAsync()
+
+ public async Task WriteDependencyEventAsync()
{
- String tempFile = Path.GetTempFileName();
+ var tempFile = Path.GetTempFileName();
DateTimeOffset start = DateTimeOffset.Now;
- using ( var file = File.CreateText(tempFile) )
+ using (var file = File.CreateText(tempFile))
{
- for ( int i=0; i < 10; i++ )
+ for (int i = 0; i < 10; i++)
{
await file.WriteLineAsync("This is a line " + i);
TelemetryClient client = new TelemetryClient();
client.TrackDependency("File", tempFile, start, TimeSpan.FromSeconds(1), true);
}
}
+
File.Delete(tempFile);
return "Some value";
}
diff --git a/WCF/Shared.Tests/Service/IAsyncService.cs b/WCF/Shared.Tests/Service/IAsyncService.cs
index cc09016..a283efd 100644
--- a/WCF/Shared.Tests/Service/IAsyncService.cs
+++ b/WCF/Shared.Tests/Service/IAsyncService.cs
@@ -1,19 +1,19 @@
-using System;
-using System.ServiceModel;
-using System.Threading.Tasks;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+ using System.ServiceModel;
+ using System.Threading.Tasks;
+
[ServiceContract]
public interface IAsyncService
{
[OperationContract]
- Task GetDataAsync();
+ Task GetDataAsync();
[OperationContract]
- Task FailWithFaultAsync();
+ Task FailWithFaultAsync();
[OperationContract]
- Task FailWithExceptionAsync();
+ Task FailWithExceptionAsync();
[OperationContract]
- Task WriteDependencyEventAsync();
+ Task WriteDependencyEventAsync();
}
}
diff --git a/WCF/Shared.Tests/Service/IOneWayService.cs b/WCF/Shared.Tests/Service/IOneWayService.cs
index 30d7b89..ce4a2ea 100644
--- a/WCF/Shared.Tests/Service/IOneWayService.cs
+++ b/WCF/Shared.Tests/Service/IOneWayService.cs
@@ -1,13 +1,14 @@
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+ using System.ServiceModel;
+
[ServiceContract]
public interface IOneWayService
{
[OperationContract(IsOneWay = true)]
void SuccessfullOneWayCall();
+
[OperationContract(IsOneWay = true)]
void FailureOneWayCall();
}
diff --git a/WCF/Shared.Tests/Service/ISelectiveTelemetryService.cs b/WCF/Shared.Tests/Service/ISelectiveTelemetryService.cs
index 3683023..56202f9 100644
--- a/WCF/Shared.Tests/Service/ISelectiveTelemetryService.cs
+++ b/WCF/Shared.Tests/Service/ISelectiveTelemetryService.cs
@@ -1,8 +1,8 @@
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+ using System.ServiceModel;
+
[ServiceContract]
public interface ISelectiveTelemetryService
{
diff --git a/WCF/Shared.Tests/Service/ISimpleService.cs b/WCF/Shared.Tests/Service/ISimpleService.cs
index d739f1e..c788cb4 100644
--- a/WCF/Shared.Tests/Service/ISimpleService.cs
+++ b/WCF/Shared.Tests/Service/ISimpleService.cs
@@ -1,29 +1,38 @@
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+ using System.ServiceModel;
+
[ServiceContract]
public interface ISimpleService
{
[OperationContract]
- String GetSimpleData();
+ string GetSimpleData();
+
[OperationContract]
void CallFailsWithFault();
+
[OperationContract]
void CallFailsWithTypedFault();
+
[OperationContract]
void CallFailsWithException();
+
[OperationContract]
void CallWritesExceptionEvent();
+
[OperationContract]
void CallMarksRequestAsFailed();
- [OperationContract(Action="*")]
+
+ [OperationContract(Action = "*")]
void CatchAllOperation();
+
[OperationContract]
void CallThatEmitsEvent();
+
[OperationContract]
- void CallAnotherServiceAndLeakOperationContext(String address);
+ void CallAnotherServiceAndLeakOperationContext(string address);
+
[OperationContract]
bool CallIsClientSideContext();
}
diff --git a/WCF/Shared.Tests/Service/ISimpleService2.cs b/WCF/Shared.Tests/Service/ISimpleService2.cs
index 8d133ad..212d1d6 100644
--- a/WCF/Shared.Tests/Service/ISimpleService2.cs
+++ b/WCF/Shared.Tests/Service/ISimpleService2.cs
@@ -1,8 +1,8 @@
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+ using System.ServiceModel;
+
[ServiceContract]
public interface ISimpleService2
{
diff --git a/WCF/Shared.Tests/Service/OneWayService.cs b/WCF/Shared.Tests/Service/OneWayService.cs
index 276ab67..837a9f0 100644
--- a/WCF/Shared.Tests/Service/OneWayService.cs
+++ b/WCF/Shared.Tests/Service/OneWayService.cs
@@ -1,13 +1,14 @@
-using System;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+
[ServiceTelemetry]
public class OneWayService : IOneWayService
{
public void SuccessfullOneWayCall()
{
}
+
public void FailureOneWayCall()
{
throw new InvalidOperationException("Call failed");
diff --git a/WCF/Shared.Tests/Service/SelectiveTelemetryService.cs b/WCF/Shared.Tests/Service/SelectiveTelemetryService.cs
index 5c7abac..99b5b09 100644
--- a/WCF/Shared.Tests/Service/SelectiveTelemetryService.cs
+++ b/WCF/Shared.Tests/Service/SelectiveTelemetryService.cs
@@ -1,7 +1,7 @@
-using System;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+
[ServiceTelemetry]
public class SelectiveTelemetryService : ISelectiveTelemetryService
{
diff --git a/WCF/Shared.Tests/Service/SimpleService.cs b/WCF/Shared.Tests/Service/SimpleService.cs
index 1a92c0d..5f3361d 100644
--- a/WCF/Shared.Tests/Service/SimpleService.cs
+++ b/WCF/Shared.Tests/Service/SimpleService.cs
@@ -1,46 +1,51 @@
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
+namespace Microsoft.ApplicationInsights.Wcf.Tests.Service
{
+ using System;
+ using System.ServiceModel;
+
[ServiceTelemetry]
public class SimpleService : ISimpleService, ISimpleService2
{
- public String GetSimpleData()
+ public string GetSimpleData()
{
return "Hello world";
}
- public String OtherGetSimpleData()
+ public string OtherGetSimpleData()
{
return "Hello World";
}
+
public void CallFailsWithFault()
{
throw new FaultException();
}
+
public void CallFailsWithTypedFault()
{
throw new FaultException(
new TypedFault { Name = "Hello" },
- "Call failed with typed fault"
- );
+ "Call failed with typed fault");
}
+
public void CallFailsWithException()
{
throw new InvalidOperationException();
}
+
public void CallWritesExceptionEvent()
{
try
{
throw new InvalidOperationException("Some exception");
- } catch ( Exception ex )
+ }
+ catch (Exception ex)
{
TelemetryClient client = new TelemetryClient();
client.TrackException(ex);
}
}
+
public void CallMarksRequestAsFailed()
{
var request = OperationContext.Current.GetRequestTelemetry();
@@ -54,27 +59,31 @@ public void SampleOperation()
public void CatchAllOperation()
{
}
+
public void CallThatEmitsEvent()
{
TelemetryClient client = new TelemetryClient();
client.TrackEvent("MyCustomEvent");
}
- public void CallAnotherServiceAndLeakOperationContext(String address)
+ public void CallAnotherServiceAndLeakOperationContext(string address)
{
var factory = new ChannelFactory(new NetTcpBinding(), new EndpointAddress(address));
var channel = factory.CreateChannel();
+
// THIS IS INCORRECT CODE
// The scope will be leaked, meaning that OperationContext.Current
// will return the wrong scope later on.
// We want to reproduce that behavior here so that it breaks
// and we can check that the problem is fixed.
var scope = new OperationContextScope((IContextChannel)channel);
- //using ( scope )
+
+ // using ( scope )
{
channel.GetSimpleData();
((IClientChannel)channel).Close();
}
+
factory.Close();
}
@@ -82,10 +91,10 @@ public bool CallIsClientSideContext()
{
return OperationContext.Current.IsClientSideContext();
}
- }
- public class TypedFault
- {
- public String Name { get; set; }
+ internal class TypedFault
+ {
+ public string Name { get; set; }
+ }
}
}
diff --git a/WCF/Shared.Tests/SimpleAuthorizationContext.cs b/WCF/Shared.Tests/SimpleAuthorizationContext.cs
index 84a8d97..af7af95 100644
--- a/WCF/Shared.Tests/SimpleAuthorizationContext.cs
+++ b/WCF/Shared.Tests/SimpleAuthorizationContext.cs
@@ -1,18 +1,26 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IdentityModel.Claims;
-using System.IdentityModel.Policy;
-using System.Security.Principal;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.IdentityModel.Claims;
+ using System.IdentityModel.Policy;
+ using System.Security.Principal;
+
public class SimpleAuthorizationContext : AuthorizationContext
{
private List claimSets;
private DateTime expirationTime;
- private String id;
- private Dictionary properties;
+ private string id;
+ private Dictionary properties;
+
+ public SimpleAuthorizationContext()
+ {
+ this.id = Guid.NewGuid().ToString();
+ this.expirationTime = DateTime.Now.AddDays(1);
+ this.claimSets = new List();
+ this.properties = new Dictionary();
+ }
public override ReadOnlyCollection ClaimSets
{
@@ -38,7 +46,7 @@ public override string Id
}
}
- public override IDictionary Properties
+ public override IDictionary Properties
{
get
{
@@ -46,29 +54,22 @@ public override string Id
}
}
- public SimpleAuthorizationContext()
- {
- this.id = Guid.NewGuid().ToString();
- this.expirationTime = DateTime.Now.AddDays(1);
- this.claimSets = new List();
- this.properties = new Dictionary();
- }
-
internal void AddIdentity(IIdentity genericIdentity)
{
List identities = null;
- if ( this.properties.ContainsKey("Identities") )
+ if (this.properties.ContainsKey("Identities"))
{
identities = (List)this.properties["Identities"];
- } else
+ }
+ else
{
identities = new List();
this.properties["Identities"] = identities;
}
+
identities.Add(genericIdentity);
this.claimSets.Add(new DefaultClaimSet(
- new Claim(ClaimTypes.Authentication, genericIdentity, Rights.Identity)
- ));
+ new Claim(ClaimTypes.Authentication, genericIdentity, Rights.Identity)));
}
}
}
diff --git a/WCF/Shared.Tests/TraceTelemetryModule.cs b/WCF/Shared.Tests/TraceTelemetryModule.cs
index 5a582d0..0ff5add 100644
--- a/WCF/Shared.Tests/TraceTelemetryModule.cs
+++ b/WCF/Shared.Tests/TraceTelemetryModule.cs
@@ -1,31 +1,32 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Extensibility;
-using System;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Extensibility;
+
public class TraceTelemetryModule : IWcfTelemetryModule, IWcfMessageTrace
{
private static bool enabled = false;
private TelemetryClient client;
- public void Initialize(TelemetryConfiguration configuration)
- {
- client = new TelemetryClient(configuration);
- }
-
// needed to avoid breaking other tests
// by tracking events that are not expected
public static void Enable()
{
enabled = true;
}
+
public static void Disable()
{
enabled = false;
}
+ public void Initialize(TelemetryConfiguration configuration)
+ {
+ this.client = new TelemetryClient(configuration);
+ }
+
public void OnBeginRequest(IOperationContext operation)
{
}
@@ -40,35 +41,36 @@ public void OnError(IOperationContext operation, Exception error)
public void OnTraceRequest(IOperationContext operation, ref Message request)
{
- if ( enabled )
+ if (enabled)
{
EventTelemetry ev = new EventTelemetry("WcfRequest");
ev.Properties.Add("Body", ReadMessageBody(ref request));
- client.TrackEvent(ev);
+ this.client.TrackEvent(ev);
}
}
public void OnTraceResponse(IOperationContext operation, ref Message response)
{
- if ( enabled )
+ if (enabled)
{
EventTelemetry ev = new EventTelemetry("WcfResponse");
ev.Properties.Add("Body", ReadMessageBody(ref response));
- client.TrackEvent(ev);
+ this.client.TrackEvent(ev);
}
}
- private String ReadMessageBody(ref Message msg)
+ private static string ReadMessageBody(ref Message msg)
{
var buffer = msg.CreateBufferedCopy(int.MaxValue);
- var result = "";
- using ( msg = buffer.CreateMessage() )
+ var result = string.Empty;
+ using (msg = buffer.CreateMessage())
{
- using ( var reader = msg.GetReaderAtBodyContents() )
+ using (var reader = msg.GetReaderAtBodyContents())
{
result = reader.ReadOuterXml();
}
}
+
msg = buffer.CreateMessage();
return result;
}
diff --git a/WCF/Shared.Tests/UserAgentTelemetryInitializerTests.cs b/WCF/Shared.Tests/UserAgentTelemetryInitializerTests.cs
index 9075b55..5266772 100644
--- a/WCF/Shared.Tests/UserAgentTelemetryInitializerTests.cs
+++ b/WCF/Shared.Tests/UserAgentTelemetryInitializerTests.cs
@@ -1,10 +1,10 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class UserAgentTelemetryInitializerTests
{
@@ -25,6 +25,7 @@ public void ContextUserAgentIsSetIfPresent()
Assert.AreEqual("MyUserAgent", telemetry.Context.User.UserAgent);
}
+
[TestMethod]
public void UserAgentIsCopiedFromRequestIfPresent()
{
diff --git a/WCF/Shared.Tests/UserTelemetryInitializerTests.cs b/WCF/Shared.Tests/UserTelemetryInitializerTests.cs
index 22a0753..ee11dbc 100644
--- a/WCF/Shared.Tests/UserTelemetryInitializerTests.cs
+++ b/WCF/Shared.Tests/UserTelemetryInitializerTests.cs
@@ -1,11 +1,11 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Security.Principal;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
+namespace Microsoft.ApplicationInsights.Wcf.Tests
{
+ using System;
+ using System.Security.Principal;
+ using System.ServiceModel;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class UserTelemetryInitializerTests
{
@@ -47,18 +47,18 @@ public void AuthenticatedRequestFillsUserIdWithUserName()
[TestMethod]
public void UserIdCopiedFromRequestIfPresent()
{
- const String userName = "MyUserName";
+ const string UserName = "MyUserName";
var context = new MockOperationContext();
context.EndpointUri = new Uri("http://localhost/Service1.svc");
context.OperationName = "GetData";
- context.Request.Context.User.Id = userName;
+ context.Request.Context.User.Id = UserName;
var initializer = new UserTelemetryInitializer();
var telemetry = new EventTelemetry();
initializer.Initialize(telemetry, context);
- Assert.AreEqual(userName, telemetry.Context.User.Id);
+ Assert.AreEqual(UserName, telemetry.Context.User.Id);
}
}
}
diff --git a/WCF/Shared.Tests/WcfEventSourceTests.cs b/WCF/Shared.Tests/WcfEventSourceTests.cs
index 3316d90..153db09 100644
--- a/WCF/Shared.Tests/WcfEventSourceTests.cs
+++ b/WCF/Shared.Tests/WcfEventSourceTests.cs
@@ -1,177 +1,179 @@
-using Microsoft.ApplicationInsights.Wcf.Implementation;
+namespace Microsoft.ApplicationInsights.Wcf.Tests
+{
+ using System;
+ using System.Collections.Generic;
+#if !NET40
+ using System.Diagnostics.Tracing;
+#endif
+ using System.Globalization;
+ using System.Linq;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
#if NET40
-using Microsoft.Diagnostics.Tracing;
-#else
-using System.Diagnostics.Tracing;
+ using Microsoft.Diagnostics.Tracing;
#endif
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Linq;
-using System.Collections.Generic;
-using System.Text;
-using System.Globalization;
-
-namespace Microsoft.ApplicationInsights.Wcf.Tests
-{
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
[TestClass]
public class WcfEventSourceTests
{
- private void CheckMessage(WcfEventListener listener, String format, params object[] args)
- {
- Assert.AreEqual(String.Format(CultureInfo.CurrentCulture, format, args), listener.FirstEventMessage);
-
- }
[TestMethod]
public void InitializationFailure_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var msg = "Exception message";
WcfEventSource.Log.InitializationFailure(msg);
- CheckMessage(listener, WcfEventSource.InitializationFailure_Message, msg);
+ CheckMessage(listener, WcfEventSource.InitializationFailureMessage, msg);
}
}
[TestMethod]
public void TelemetryModuleExecutionStarted_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var typeName = "MyType";
var stageName = "MyStage";
WcfEventSource.Log.TelemetryModuleExecutionStarted(typeName, stageName);
- CheckMessage(listener, WcfEventSource.TelemetryModuleExecutionStarted_Message, typeName, stageName);
+ CheckMessage(listener, WcfEventSource.TelemetryModuleExecutionStartedMessage, typeName, stageName);
}
}
[TestMethod]
public void TelemetryModuleExecutionStopped_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var typeName = "MyType";
var stageName = "MyStage";
WcfEventSource.Log.TelemetryModuleExecutionStopped(typeName, stageName);
- CheckMessage(listener, WcfEventSource.TelemetryModuleExecutionStopped_Message, typeName, stageName);
+ CheckMessage(listener, WcfEventSource.TelemetryModuleExecutionStoppedMessage, typeName, stageName);
}
}
[TestMethod]
public void TelemetryModuleExecutionFailed_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var typeName = "MyType";
var stageName = "MyStage";
var exception = "MyException";
WcfEventSource.Log.TelemetryModuleExecutionFailed(typeName, stageName, exception);
- CheckMessage(listener, WcfEventSource.TelemetryModuleExecutionFailed_Message, typeName, stageName, exception);
+ CheckMessage(listener, WcfEventSource.TelemetryModuleExecutionFailedMessage, typeName, stageName, exception);
}
}
[TestMethod]
public void NoOperationContextFound_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
WcfEventSource.Log.NoOperationContextFound();
- CheckMessage(listener, WcfEventSource.NoOperationContextFound_Message);
+ CheckMessage(listener, WcfEventSource.NoOperationContextFoundMessage);
}
}
[TestMethod]
public void OperationIgnored_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var contractName = "MyContract";
var contractNamespace = "MyNS";
var operationName = "MyOperation";
WcfEventSource.Log.OperationIgnored(contractName, contractNamespace, operationName);
- CheckMessage(listener, WcfEventSource.OperationIgnored_Message, contractName, contractNamespace, operationName);
+ CheckMessage(listener, WcfEventSource.OperationIgnoredMessage, contractName, contractNamespace, operationName);
}
}
[TestMethod]
public void WcfTelemetryInitializerLoaded_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var typeName = "MyType";
WcfEventSource.Log.WcfTelemetryInitializerLoaded(typeName);
- CheckMessage(listener, WcfEventSource.WcfTelemetryInitializerLoaded_Message, typeName);
+ CheckMessage(listener, WcfEventSource.WcfTelemetryInitializerLoadedMessage, typeName);
}
}
[TestMethod]
public void LocationIdSet_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var ip = "10.0.0.1";
WcfEventSource.Log.LocationIdSet(ip);
- CheckMessage(listener, WcfEventSource.LocationIdSet_Message, ip);
+ CheckMessage(listener, WcfEventSource.LocationIdSetMessage, ip);
}
}
[TestMethod]
public void OperationContextCreated_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var operationId = "abcdef";
var ownsContext = true;
WcfEventSource.Log.OperationContextCreated(operationId, ownsContext);
- CheckMessage(listener, WcfEventSource.OperationContextCreated_Message, operationId, ownsContext);
+ CheckMessage(listener, WcfEventSource.OperationContextCreatedMessage, operationId, ownsContext);
}
}
[TestMethod]
public void RequestMessageClosed_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var action = "reading property";
var argument = "Myproperty";
WcfEventSource.Log.RequestMessageClosed(action, argument);
- CheckMessage(listener, WcfEventSource.RequestMessageClosed_Message, action, argument);
+ CheckMessage(listener, WcfEventSource.RequestMessageClosedMessage, action, argument);
}
}
[TestMethod]
public void ResponseMessageClosed_Message()
{
- using ( var listener = new WcfEventListener() )
+ using (var listener = new WcfEventListener())
{
var action = "reading property";
var argument = "Myproperty";
WcfEventSource.Log.ResponseMessageClosed(action, argument);
- CheckMessage(listener, WcfEventSource.ResponseMessageClosed_Message, action, argument);
+ CheckMessage(listener, WcfEventSource.ResponseMessageClosedMessage, action, argument);
}
}
- class WcfEventListener : EventListener
+ private static void CheckMessage(WcfEventListener listener, string format, params object[] args)
+ {
+ Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, format, args), listener.FirstEventMessage);
+ }
+
+ private class WcfEventListener : EventListener
{
- public String FirstEventMessage { get; private set; }
- public List AllMessages { get; private set; }
private object lockObj;
public WcfEventListener()
{
- lockObj = new object();
- AllMessages = new List();
+ this.lockObj = new object();
+ this.AllMessages = new List();
this.EnableEvents(WcfEventSource.Log, EventLevel.Verbose);
}
+ public string FirstEventMessage { get; private set; }
+
+ public List AllMessages { get; private set; }
+
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
- lock ( lockObj )
+ lock (this.lockObj)
{
- var str = String.Format(CultureInfo.CurrentCulture, eventData.Message, eventData.Payload.ToArray());
- AllMessages.Add(str);
- if ( String.IsNullOrEmpty(FirstEventMessage) )
+ var str = string.Format(CultureInfo.CurrentCulture, eventData.Message, eventData.Payload.ToArray());
+ this.AllMessages.Add(str);
+ if (string.IsNullOrEmpty(this.FirstEventMessage))
{
- FirstEventMessage = str;
+ this.FirstEventMessage = str;
}
}
}
diff --git a/WCF/Shared/ClientIpTelemetryInitializer.cs b/WCF/Shared/ClientIpTelemetryInitializer.cs
index 559821d..af5c5d8 100644
--- a/WCF/Shared/ClientIpTelemetryInitializer.cs
+++ b/WCF/Shared/ClientIpTelemetryInitializer.cs
@@ -1,37 +1,38 @@
-using Microsoft.ApplicationInsights.Channel;
-using Microsoft.ApplicationInsights.Extensibility.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using System;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+
///
- /// Collects the IP of the client calling the WCF service
+ /// Collects the IP of the client calling the WCF service.
///
public sealed class ClientIpTelemetryInitializer : WcfTelemetryInitializer
{
///
- /// Initialize the telemetry event with the client IP if available
+ /// Initialize the telemetry event with the client IP if available.
///
- /// The telemetry event
- /// The WCF operation context
+ /// The telemetry event.
+ /// The WCF operation context.
protected override void OnInitialize(ITelemetry telemetry, IOperationContext operation)
{
- if ( String.IsNullOrEmpty(telemetry.Context.Location.Ip) )
+ if (string.IsNullOrEmpty(telemetry.Context.Location.Ip))
{
var location = operation.Request.Context.Location;
- if ( String.IsNullOrEmpty(location.Ip) )
+ if (string.IsNullOrEmpty(location.Ip))
{
- UpdateClientIp(location, operation);
+ this.UpdateClientIp(location, operation);
}
+
telemetry.Context.Location.Ip = location.Ip;
}
}
private void UpdateClientIp(LocationContext location, IOperationContext operation)
{
- if ( operation.HasIncomingMessageProperty(RemoteEndpointMessageProperty.Name) )
+ if (operation.HasIncomingMessageProperty(RemoteEndpointMessageProperty.Name))
{
var property = (RemoteEndpointMessageProperty)
operation.GetIncomingMessageProperty(RemoteEndpointMessageProperty.Name);
diff --git a/WCF/Shared/ClientTelemetryEndpointBehavior.cs b/WCF/Shared/ClientTelemetryEndpointBehavior.cs
index 18a19ff..bff9f75 100644
--- a/WCF/Shared/ClientTelemetryEndpointBehavior.cs
+++ b/WCF/Shared/ClientTelemetryEndpointBehavior.cs
@@ -1,13 +1,13 @@
-using Microsoft.ApplicationInsights.Extensibility;
-using Microsoft.ApplicationInsights.Extensibility.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using System;
-using System.ServiceModel.Channels;
-using System.ServiceModel.Description;
-using System.ServiceModel.Dispatcher;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Description;
+ using System.ServiceModel.Dispatcher;
+ using Microsoft.ApplicationInsights.Extensibility;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+
///
/// Instruments client-side WCF endpoints to generate DependencyTelemetry
/// events on calls.
@@ -17,59 +17,65 @@ public sealed class ClientTelemetryEndpointBehavior : IEndpointBehavior
private TelemetryClient telemetryClient;
///
- /// Gets or sets the name of the HTTP header to get root operation Id from.
- ///
- public String RootOperationIdHeaderName { get; set; }
- ///
- /// Gets or sets the name of the HTTP header to get parent operation Id from.
- ///
- public String ParentOperationIdHeaderName { get; set; }
- ///
- /// Gets or sets the name of the SOAP header to get root operation Id from.
- ///
- public String SoapRootOperationIdHeaderName { get; set; }
- ///
- /// Gets or sets the name of the SOAP header to get parent operation Id from.
- ///
- public String SoapParentOperationIdHeaderName { get; set; }
- ///
- /// Gets or sets the name of the SOAP header to get parent operation Id from.
- ///
- public String SoapHeaderNamespace { get; set; }
-
- ///
- /// Initializes a new instance using the default
- /// Application Insights configuration
+ /// Initializes a new instance of the
+ /// class using the default Application Insights configuration.
///
public ClientTelemetryEndpointBehavior()
: this(TelemetryConfiguration.Active)
{
-
}
///
- /// Initializes a new instance using the specified configuration
+ /// Initializes a new instance of the
+ /// class using the specified configuration.
///
- /// The Application Insights configuration to use
+ /// The Application Insights configuration to use.
public ClientTelemetryEndpointBehavior(TelemetryConfiguration configuration)
: this(configuration != null ? new TelemetryClient(configuration) : null)
{
}
///
- /// Initializes a new instance using the specified telemetry client
+ /// Initializes a new instance of the class
+ /// using the specified telemetry client.
///
- /// The TelemetryClient instance to use to emit telemetry events
+ /// The TelemetryClient instance to use to emit telemetry events.
public ClientTelemetryEndpointBehavior(TelemetryClient client)
{
- if ( client == null )
+ if (client == null)
{
- throw new ArgumentNullException(nameof(client));
+ throw new ArgumentNullException(nameof(client));
}
+
this.telemetryClient = client;
this.telemetryClient.Context.GetInternalContext().SdkVersion = "wcf: " + SdkVersionUtils.GetAssemblyVersion();
}
+ ///
+ /// Gets or sets the name of the HTTP header to get root operation Id from.
+ ///
+ public string RootOperationIdHeaderName { get; set; }
+
+ ///
+ /// Gets or sets the name of the HTTP header to get parent operation Id from.
+ ///
+ public string ParentOperationIdHeaderName { get; set; }
+
+ ///
+ /// Gets or sets the name of the SOAP header to get root operation Id from.
+ ///
+ public string SoapRootOperationIdHeaderName { get; set; }
+
+ ///
+ /// Gets or sets the name of the SOAP header to get parent operation Id from.
+ ///
+ public string SoapParentOperationIdHeaderName { get; set; }
+
+ ///
+ /// Gets or sets the name of the SOAP header to get parent operation Id from.
+ ///
+ public string SoapHeaderNamespace { get; set; }
+
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
var contract = endpoint.Contract.ContractType;
@@ -80,13 +86,13 @@ void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingPar
// since channel factories are cached by default in ClientBase.
// We could possibly cache this to avoid the hit in other scenarios.
var description = new ClientContract(endpoint.Contract);
- var element = new ClientTelemetryBindingElement(telemetryClient, description)
+ var element = new ClientTelemetryBindingElement(this.telemetryClient, description)
{
- RootOperationIdHeaderName = RootOperationIdHeaderName,
- ParentOperationIdHeaderName = ParentOperationIdHeaderName,
- SoapRootOperationIdHeaderName = SoapRootOperationIdHeaderName,
- SoapParentOperationIdHeaderName = SoapParentOperationIdHeaderName,
- SoapHeaderNamespace = SoapHeaderNamespace
+ RootOperationIdHeaderName = this.RootOperationIdHeaderName,
+ ParentOperationIdHeaderName = this.ParentOperationIdHeaderName,
+ SoapRootOperationIdHeaderName = this.SoapRootOperationIdHeaderName,
+ SoapParentOperationIdHeaderName = this.SoapParentOperationIdHeaderName,
+ SoapHeaderNamespace = this.SoapHeaderNamespace
};
var collection = endpoint.Binding.CreateBindingElements();
collection.Insert(0, element);
@@ -106,5 +112,4 @@ void IEndpointBehavior.Validate(ServiceEndpoint endpoint)
{
}
}
-
}
diff --git a/WCF/Shared/ClientTelemetryExtensionElement.cs b/WCF/Shared/ClientTelemetryExtensionElement.cs
index b7739fb..2aa8048 100644
--- a/WCF/Shared/ClientTelemetryExtensionElement.cs
+++ b/WCF/Shared/ClientTelemetryExtensionElement.cs
@@ -1,22 +1,21 @@
-using Microsoft.ApplicationInsights.Extensibility;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using System;
-using System.Configuration;
-using System.ServiceModel.Configuration;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+ using System.Configuration;
+ using System.ServiceModel.Configuration;
+ using Microsoft.ApplicationInsights.Extensibility;
+
///
/// Supports generating Application Insights dependency
/// events for calls to Web Services done using the
- /// WCF client-side stack through the configuration file
+ /// WCF client-side stack through the configuration file.
///
public sealed class ClientTelemetryExtensionElement : BehaviorExtensionElement
{
private ConfigurationPropertyCollection properties;
///
- /// Gets the type of the behavior
+ /// Gets the type of the behavior.
///
public override Type BehaviorType
{
@@ -26,87 +25,97 @@ public override Type BehaviorType
///
/// Gets or sets the name of the HTTP header to get root operation Id from.
///
- public String RootOperationIdHeaderName
+ public string RootOperationIdHeaderName
{
- get { return (String)base["rootOperationIdHeaderName"]; }
+ get { return (string)base["rootOperationIdHeaderName"]; }
set { base["rootOperationIdHeaderName"] = value; }
}
+
///
/// Gets or sets the name of the HTTP header to get parent operation Id from.
///
- public String ParentOperationIdHeaderName
+ public string ParentOperationIdHeaderName
{
- get { return (String)base["parentOperationIdHeaderName"]; }
+ get { return (string)base["parentOperationIdHeaderName"]; }
set { base["parentOperationIdHeaderName"] = value; }
}
+
///
/// Gets or sets the name of the SOAP header to get root operation Id from.
///
- public String SoapRootOperationIdHeaderName
+ public string SoapRootOperationIdHeaderName
{
- get { return (String)base["soapRootOperationIdHeaderName"]; }
+ get { return (string)base["soapRootOperationIdHeaderName"]; }
set { base["soapRootOperationIdHeaderName"] = value; }
}
+
///
/// Gets or sets the name of the SOAP header to get parent operation Id from.
///
- public String SoapParentOperationIdHeaderName
+ public string SoapParentOperationIdHeaderName
{
- get { return (String)base["soapParentOperationIdHeaderName"]; }
+ get { return (string)base["soapParentOperationIdHeaderName"]; }
set { base["soapParentOperationIdHeaderName"] = value; }
}
+
///
/// Gets or sets the XML Namespace for the root/parent operation ID SOAP headers.
///
- public String SoapHeaderNamespace
+ public string SoapHeaderNamespace
{
- get { return (String)base["soapHeaderNamespace"]; }
+ get { return (string)base["soapHeaderNamespace"]; }
set { base["soapHeaderNamespace"] = value; }
}
///
- /// The list of properties supported by this behavior
+ /// The list of properties supported by this behavior.
///
protected override ConfigurationPropertyCollection Properties
{
get
{
- if ( properties == null )
+ if (this.properties == null)
{
- properties = CreateProperties();
+ this.properties = this.CreateProperties();
}
- return properties;
- }
- }
- ///
- /// Creates the ApplicationInsights behavior
- ///
- /// A new Endpoint Behavior that will track client-side calls
- protected override object CreateBehavior()
- {
- return CreateBehaviorInternal();
+ return this.properties;
+ }
}
internal ClientTelemetryEndpointBehavior CreateBehaviorInternal()
{
- var behavior = new ClientTelemetryEndpointBehavior(TelemetryConfiguration.Active);
- behavior.ParentOperationIdHeaderName = ParentOperationIdHeaderName;
- behavior.RootOperationIdHeaderName = RootOperationIdHeaderName;
- behavior.SoapParentOperationIdHeaderName = SoapParentOperationIdHeaderName;
- behavior.SoapRootOperationIdHeaderName = SoapRootOperationIdHeaderName;
- behavior.SoapHeaderNamespace = SoapHeaderNamespace;
+ var behavior = new ClientTelemetryEndpointBehavior(TelemetryConfiguration.Active)
+ {
+ ParentOperationIdHeaderName = this.ParentOperationIdHeaderName,
+ RootOperationIdHeaderName = this.RootOperationIdHeaderName,
+ SoapParentOperationIdHeaderName = this.SoapParentOperationIdHeaderName,
+ SoapRootOperationIdHeaderName = this.SoapRootOperationIdHeaderName,
+ SoapHeaderNamespace = this.SoapHeaderNamespace
+ };
return behavior;
}
+
internal ConfigurationPropertyCollection CreateProperties()
{
- var props = new ConfigurationPropertyCollection();
- props.Add(new ConfigurationProperty("parentOperationIdHeaderName", typeof(String), CorrelationHeaders.HttpStandardParentIdHeader));
- props.Add(new ConfigurationProperty("rootOperationIdHeaderName", typeof(String), CorrelationHeaders.HttpStandardRootIdHeader));
- props.Add(new ConfigurationProperty("soapParentOperationIdHeaderName", typeof(String), CorrelationHeaders.SoapStandardParentIdHeader));
- props.Add(new ConfigurationProperty("soapRootOperationIdHeaderName", typeof(String), CorrelationHeaders.SoapStandardRootIdHeader));
- props.Add(new ConfigurationProperty("soapHeaderNamespace", typeof(String), CorrelationHeaders.SoapStandardNamespace));
+ var props = new ConfigurationPropertyCollection
+ {
+ new ConfigurationProperty("parentOperationIdHeaderName", typeof(string), CorrelationHeaders.HttpStandardParentIdHeader),
+ new ConfigurationProperty("rootOperationIdHeaderName", typeof(string), CorrelationHeaders.HttpStandardRootIdHeader),
+ new ConfigurationProperty("soapParentOperationIdHeaderName", typeof(string), CorrelationHeaders.SoapStandardParentIdHeader),
+ new ConfigurationProperty("soapRootOperationIdHeaderName", typeof(string), CorrelationHeaders.SoapStandardRootIdHeader),
+ new ConfigurationProperty("soapHeaderNamespace", typeof(string), CorrelationHeaders.SoapStandardNamespace)
+ };
return props;
}
+
+ ///
+ /// Creates the ApplicationInsights behavior.
+ ///
+ /// A new Endpoint Behavior that will track client-side calls.
+ protected override object CreateBehavior()
+ {
+ return this.CreateBehaviorInternal();
+ }
}
}
diff --git a/WCF/Shared/CorrelationHeaders.cs b/WCF/Shared/CorrelationHeaders.cs
index ab4a044..1939cc2 100644
--- a/WCF/Shared/CorrelationHeaders.cs
+++ b/WCF/Shared/CorrelationHeaders.cs
@@ -1,31 +1,35 @@
-using System;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+
///
- /// Default correlation header names
+ /// Default correlation header names.
///
public static class CorrelationHeaders
{
///
- /// Default HTTP header name for ParentId
+ /// Default HTTP header name for ParentId.
///
- public const String HttpStandardParentIdHeader = "x-ms-request-id";
+ public const string HttpStandardParentIdHeader = "x-ms-request-id";
+
///
- /// Default HTTP header name for RootId
+ /// Default HTTP header name for RootId.
///
- public const String HttpStandardRootIdHeader = "x-ms-request-root-id";
+ public const string HttpStandardRootIdHeader = "x-ms-request-root-id";
+
///
- /// Default SOAP header name for ParentId
+ /// Default SOAP header name for ParentId.
///
- public const String SoapStandardParentIdHeader = "requestId";
+ public const string SoapStandardParentIdHeader = "requestId";
+
///
- /// Default SOAP header name for RootId
+ /// Default SOAP header name for RootId.
///
- public const String SoapStandardRootIdHeader = "requestRootId";
+ public const string SoapStandardRootIdHeader = "requestRootId";
+
///
- /// Default XML namespace for SOAP headers
+ /// Default XML namespace for SOAP headers.
///
- public const String SoapStandardNamespace = "http://schemas.microsoft.com/application-insights";
+ public const string SoapStandardNamespace = "http://schemas.microsoft.com/application-insights";
}
}
diff --git a/WCF/Shared/ExceptionTrackingTelemetryModule.cs b/WCF/Shared/ExceptionTrackingTelemetryModule.cs
index ad7dedd..a2e1c53 100644
--- a/WCF/Shared/ExceptionTrackingTelemetryModule.cs
+++ b/WCF/Shared/ExceptionTrackingTelemetryModule.cs
@@ -1,22 +1,22 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using Microsoft.ApplicationInsights.Extensibility;
-using Microsoft.ApplicationInsights.Extensibility.Implementation;
-using Microsoft.ApplicationInsights.Wcf.Implementation;
-using System;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Extensibility;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation;
+ using Microsoft.ApplicationInsights.Wcf.Implementation;
+
///
- /// Implements exception tracking for WCF services
+ /// Implements exception tracking for WCF services.
///
public sealed class ExceptionTrackingTelemetryModule : IWcfTelemetryModule
{
private TelemetryClient telemetryClient;
///
- /// Initializes a new instance of this module
+ /// Initializes a new instance of the class.
///
public ExceptionTrackingTelemetryModule()
{
@@ -38,22 +38,32 @@ void IWcfTelemetryModule.OnEndRequest(IOperationContext operation, Message reply
void IWcfTelemetryModule.OnError(IOperationContext operation, Exception error)
{
- if ( operation == null )
+ if (operation == null)
+ {
throw new ArgumentNullException("operation");
- if ( error == null )
+ }
+
+ if (error == null)
+ {
throw new ArgumentNullException("error");
- if ( telemetryClient == null )
+ }
+
+ if (this.telemetryClient == null)
+ {
return;
+ }
ExceptionTelemetry telemetry = new ExceptionTelemetry(error);
- if ( error is FaultException )
+ if (error is FaultException)
{
telemetry.SeverityLevel = SeverityLevel.Error;
- } else
+ }
+ else
{
telemetry.SeverityLevel = SeverityLevel.Critical;
}
- telemetryClient.TrackException(error);
+
+ this.telemetryClient.TrackException(error);
}
}
}
diff --git a/WCF/Shared/IOperationContext.cs b/WCF/Shared/IOperationContext.cs
index 50959a4..81d3930 100644
--- a/WCF/Shared/IOperationContext.cs
+++ b/WCF/Shared/IOperationContext.cs
@@ -1,82 +1,95 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+ using System.ServiceModel;
+ using Microsoft.ApplicationInsights.DataContracts;
+
///
/// Represents the context of the currently executing
/// operation. Wraps the underlying
- /// OperationContext
+ /// OperationContext.
///
public interface IOperationContext
{
///
- /// The ID assigned to this request
+ /// Gets the ID assigned to this request.
///
- String OperationId { get; }
+ string OperationId { get; }
+
///
- /// The URI of the service endpoint
+ /// Gets the URI of the service endpoint.
///
Uri EndpointUri { get; }
+
///
- /// The URI the message was addressed to
+ /// Gets the URI the message was addressed to.
///
Uri ToHeader { get; }
+
///
- /// The RequestTelemetry event
+ /// Gets the RequestTelemetry event.
///
RequestTelemetry Request { get; }
+
///
- /// True if WCF owns the Request telemetry object
+ /// Gets a value indicating whether WCF owns the Request telemetry object.
///
bool OwnsRequest { get; }
+
///
- /// Name of the service contract being invoked
+ /// Gets the name of the service contract being invoked.
///
- String ContractName { get; }
+ string ContractName { get; }
+
///
- /// Namespace of the service contract being invoked
+ /// Gets the namespace of the service contract being invoked.
///
- String ContractNamespace { get; }
+ string ContractNamespace { get; }
+
///
- /// The name of the operation being invoked
+ /// Gets the name of the operation being invoked.
///
- String OperationName { get; }
+ string OperationName { get; }
+
///
- /// The service security context
+ /// Gets the service security context.
///
ServiceSecurityContext SecurityContext { get; }
+
///
- /// Checks if the incoming message has a given property
+ /// Checks if the incoming message has a given property.
///
- /// The name of the property to be checked
- /// True if the property exists; false otherwise
- bool HasIncomingMessageProperty(String propertyName);
+ /// The name of the property to be checked.
+ /// True if the property exists; false otherwise.
+ bool HasIncomingMessageProperty(string propertyName);
+
///
- /// Returns the value of the given property in the incoming message
+ /// Returns the value of the given property in the incoming message.
///
- /// The name of the property to be checked
- /// The property value
- object GetIncomingMessageProperty(String propertyName);
+ /// The name of the property to be checked.
+ /// The property value.
+ object GetIncomingMessageProperty(string propertyName);
+
///
- /// Checks if the outgoing message has a given property
+ /// Checks if the outgoing message has a given property.
///
- /// The name of the property to be checked
- /// True if the property exists; false otherwise
- bool HasOutgoingMessageProperty(String propertyName);
+ /// The name of the property to be checked.
+ /// True if the property exists; false otherwise.
+ bool HasOutgoingMessageProperty(string propertyName);
+
///
- /// Returns the value of the given property in the outgoing message
+ /// Returns the value of the given property in the outgoing message.
///
- /// The name of the property
- /// The property value
- object GetOutgoingMessageProperty(String propertyName);
+ /// The name of the property.
+ /// The property value.
+ object GetOutgoingMessageProperty(string propertyName);
+
///
- /// Returns the specified SOAP header on the request message
+ /// Returns the specified SOAP header on the request message.
///
- /// The header name
- /// The header XML namespace
- /// The header, or null if it is not present
- T GetIncomingMessageHeader(String name, String ns);
+ /// The header name.
+ /// The header XML namespace.
+ /// The header, or null if it is not present.
+ T GetIncomingMessageHeader(string name, string ns);
}
}
diff --git a/WCF/Shared/IOperationContextState.cs b/WCF/Shared/IOperationContextState.cs
index 7ec0ab3..fdd229e 100644
--- a/WCF/Shared/IOperationContextState.cs
+++ b/WCF/Shared/IOperationContextState.cs
@@ -1,29 +1,29 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+
///
/// Allows a TelemetryModule or TelemetryInitializer to store temporary
- /// state between request/response processing
+ /// state between request/response processing.
///
public interface IOperationContextState
{
///
- /// Store a value in the context
+ /// Store a value in the context.
///
- /// The key to store the state under
- /// The value to store
- void SetState(String key, object value);
+ /// The key to store the state under.
+ /// The value to store.
+ void SetState(string key, object value);
+
///
- /// Retrieve a value from the context
+ /// Retrieve a value from the context.
///
- /// The type of value
- /// The key the state is stored under
- /// The value, if found
+ /// The type of value.
+ /// The key the state is stored under.
+ /// The value, if found.
/// True if the specified key was found, false otherwise.
- bool TryGetState(String key, out T value);
-
+ bool TryGetState(string key, out T value);
}
}
diff --git a/WCF/Shared/IWcfMessageTrace.cs b/WCF/Shared/IWcfMessageTrace.cs
index 476c9e6..3d3bdd3 100644
--- a/WCF/Shared/IWcfMessageTrace.cs
+++ b/WCF/Shared/IWcfMessageTrace.cs
@@ -1,8 +1,8 @@
-using System;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+ using System.ServiceModel.Channels;
+
///
/// Represents a telemetry module that also is interested
/// in tracing request messages before the request is executed.
@@ -10,18 +10,18 @@ namespace Microsoft.ApplicationInsights.Wcf
public interface IWcfMessageTrace
{
///
- /// Called after IWcfTelemetryModule.OnBeginRequest()
+ /// Called after
/// but before the request is executed.
///
- /// The operation context
+ /// The operation context.
/// The request message. You can modify the request by returning a new, unread Message object.
void OnTraceRequest(IOperationContext operation, ref Message request);
///
/// Called after the request is executed, but before
- /// IWcfTelemetryModule.OnEndRequest() is called.
+ /// is called.
///
- /// The operation context
+ /// The operation context.
/// The response message. You can modify the response by returning a new, unread Message object.
void OnTraceResponse(IOperationContext operation, ref Message response);
}
diff --git a/WCF/Shared/IWcfTelemetryModule.cs b/WCF/Shared/IWcfTelemetryModule.cs
index a443099..46322d7 100644
--- a/WCF/Shared/IWcfTelemetryModule.cs
+++ b/WCF/Shared/IWcfTelemetryModule.cs
@@ -1,30 +1,32 @@
-using Microsoft.ApplicationInsights.Extensibility;
-using System;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf
+namespace Microsoft.ApplicationInsights.Wcf
{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.Extensibility;
+
///
- /// Represents a telemetry module used during WCF processing
+ /// Represents a telemetry module used during WCF processing.
///
public interface IWcfTelemetryModule : ITelemetryModule
{
///
- /// Fired when the request message arrives
+ /// Fired when the request message arrives.
///
- /// The operation context
+ /// The operation context.
void OnBeginRequest(IOperationContext operation);
+
///
- /// Fired before the response message is sent
+ /// Fired before the response message is sent.
///
- /// The operation context
- /// The response message
+ /// The operation context.
+ /// The response message.
void OnEndRequest(IOperationContext operation, Message reply);
+
///
- /// Fired when an exception occurs
+ /// Fired when an exception occurs.
///
- /// The operation context
- /// The exception object
+ /// The operation context.
+ /// The exception object.
void OnError(IOperationContext operation, Exception error);
}
}
diff --git a/WCF/Shared/Implementation/ChannelAsyncResult.cs b/WCF/Shared/Implementation/ChannelAsyncResult.cs
index 6fe68ba..a9315e5 100644
--- a/WCF/Shared/Implementation/ChannelAsyncResult.cs
+++ b/WCF/Shared/Implementation/ChannelAsyncResult.cs
@@ -1,291 +1,114 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using System;
-using System.ServiceModel.Channels;
-using System.Threading;
-using System.Xml;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel.Channels;
+ using System.Threading;
+ using Microsoft.ApplicationInsights.DataContracts;
+
internal abstract class ChannelAsyncResult : IAsyncResult, IDisposable
{
+ private const int Incomplete = 0;
+ private const int CompletedSync = 1;
+ private const int CompletedAsync = 2;
private AsyncCallback callback;
private EventWaitHandle waitHandle;
private AsyncCallback channelCompletionCallback;
- const int Incomplete = 0;
- const int CompletedSync = 1;
- const int CompletedAsync = 2;
private int completed;
+ public ChannelAsyncResult(AsyncCallback completeCallback, AsyncCallback callback, object state, DependencyTelemetry channelState)
+ {
+ this.AsyncState = state;
+ this.waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
+ this.Telemetry = channelState;
+ this.channelCompletionCallback = completeCallback;
+ this.callback = callback;
+ }
+
public object AsyncState { get; private set; }
- public WaitHandle AsyncWaitHandle { get { return waitHandle; } }
+ public WaitHandle AsyncWaitHandle
+ {
+ get { return this.waitHandle; }
+ }
public bool CompletedSynchronously
{
- get { return Thread.VolatileRead(ref completed) == CompletedSync; }
+ get { return Thread.VolatileRead(ref this.completed) == CompletedSync; }
}
public bool IsCompleted
{
- get { return Thread.VolatileRead(ref completed) != Incomplete; }
+ get { return Thread.VolatileRead(ref this.completed) != Incomplete; }
}
+
// should only be read once we're complete and we don't care if
// it's not read in order
public Exception LastException { get; private set; }
// these get set during construction, so no need for much check
public DependencyTelemetry Telemetry { get; private set; }
- public IAsyncResult OriginalResult { get; protected set; }
- public ChannelAsyncResult(AsyncCallback completeCallback, AsyncCallback callback, object state, DependencyTelemetry channelState)
- {
- this.AsyncState = state;
- this.waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
- this.Telemetry = channelState;
- this.channelCompletionCallback = completeCallback;
- this.callback = callback;
- }
-
- protected void Complete(bool completedSync, Exception exception = null)
- {
- this.LastException = exception;
-
- Thread.VolatileWrite(ref this.completed, completedSync ? CompletedSync : CompletedAsync);
-
- try
- {
- // tell channel the async operation is done
- NotifyCompletionToChannel();
- } catch ( Exception ex )
- {
- LastException = ex;
- }
- // set the waitHandle so that when callback() calls EndWhatever()
- // it doesn't hang
- this.waitHandle.Set();
- try
- {
- callback?.Invoke(this);
- } catch ( Exception ex )
- {
- LastException = ex;
- }
- }
-
- protected void NotifyCompletionToChannel()
- {
- this.channelCompletionCallback?.Invoke(this);
- }
+ public IAsyncResult OriginalResult { get; protected set; }
public static TAsyncResult End(IAsyncResult result) where TAsyncResult : ChannelAsyncResult
{
- ChannelAsyncResult car = (ChannelAsyncResult)result;
- if ( !car.IsCompleted )
+ var car = (ChannelAsyncResult)result;
+ if (!car.IsCompleted)
{
car.AsyncWaitHandle.WaitOne();
}
((IDisposable)car).Dispose();
- if ( car.LastException != null )
+ if (car.LastException != null)
{
throw car.LastException;
}
+
return (TAsyncResult)car;
}
void IDisposable.Dispose()
{
// done here only to avoid CA1001
- if ( this.waitHandle != null )
+ if (this.waitHandle != null)
{
this.waitHandle.Close();
}
}
- }
-
- internal sealed class OpenAsyncResult : ChannelAsyncResult
- {
- public IChannel InnerChannel { get; private set; }
-
- public OpenAsyncResult(IChannel innerChannel, TimeSpan timeout, AsyncCallback onOpenDone, AsyncCallback callback, object state, DependencyTelemetry telemetry)
- : base(onOpenDone, callback, state, telemetry)
- {
- this.InnerChannel = innerChannel;
-
- OriginalResult = innerChannel.BeginOpen(timeout, OnComplete, this);
- if ( OriginalResult.CompletedSynchronously )
- {
- innerChannel.EndOpen(OriginalResult);
- this.Complete(true);
- }
- }
-
- private static void OnComplete(IAsyncResult result)
- {
- if ( result.CompletedSynchronously )
- {
- return;
- }
- OpenAsyncResult oar = (OpenAsyncResult)result.AsyncState;
- try
- {
- oar.InnerChannel.EndOpen(oar.OriginalResult);
- oar.Complete(false);
- } catch ( Exception ex )
- {
- oar.Complete(false, ex);
- }
- }
- }
- internal sealed class SendAsyncResult : ChannelAsyncResult
- {
- public IOutputChannel InnerChannel { get; private set; }
- public UniqueId RequestId { get; private set; }
-
- public SendAsyncResult(IOutputChannel innerChannel, Message message, TimeSpan timeout, AsyncCallback onSendDone, AsyncCallback callback, object state, DependencyTelemetry telemetry)
- : base(onSendDone, callback, state, telemetry)
- {
- this.InnerChannel = innerChannel;
- this.RequestId = message.Headers.MessageId;
-
- this.OriginalResult = innerChannel.BeginSend(message, timeout, OnComplete, this);
- if ( OriginalResult.CompletedSynchronously )
- {
- innerChannel.EndSend(OriginalResult);
- this.Complete(true);
- }
- }
-
- private static void OnComplete(IAsyncResult result)
- {
- if ( result.CompletedSynchronously )
- {
- return;
- }
- SendAsyncResult sar = (SendAsyncResult)result.AsyncState;
- try
- {
- sar.InnerChannel.EndSend(sar.OriginalResult);
- sar.Complete(false);
- } catch ( Exception ex )
- {
- sar.Complete(false, ex);
- }
- }
- }
-
- internal sealed class RequestAsyncResult : ChannelAsyncResult
- {
- public IRequestChannel InnerChannel { get; private set; }
- public Message Reply { get; private set; }
-
- public RequestAsyncResult(IRequestChannel innerChannel, Message message, TimeSpan timeout, AsyncCallback onRequestDone, AsyncCallback callback, object state, DependencyTelemetry telemetry)
- : base(onRequestDone, callback, state, telemetry)
+ protected void Complete(bool completedSync, Exception exception = null)
{
- this.InnerChannel = innerChannel;
+ this.LastException = exception;
- OriginalResult = innerChannel.BeginRequest(message, timeout, OnComplete, this);
- if ( OriginalResult.CompletedSynchronously )
- {
- this.Reply = innerChannel.EndRequest(OriginalResult);
- this.Complete(true);
- }
- }
+ Thread.VolatileWrite(ref this.completed, completedSync ? CompletedSync : CompletedAsync);
- private static void OnComplete(IAsyncResult result)
- {
- if ( result.CompletedSynchronously )
- {
- return;
- }
- RequestAsyncResult rar = (RequestAsyncResult)result.AsyncState;
try
{
- rar.Reply = rar.InnerChannel.EndRequest(rar.OriginalResult);
- rar.Complete(false);
- } catch ( Exception ex )
- {
- rar.Complete(false, ex);
+ // tell channel the async operation is done
+ this.NotifyCompletionToChannel();
}
- }
- }
-
- internal sealed class ReceiveAsyncResult : ChannelAsyncResult
- {
- public IInputChannel InnerChannel { get; private set; }
- public Message Message { get; private set; }
-
- public ReceiveAsyncResult(IInputChannel innerChannel, TimeSpan timeout, AsyncCallback onReceiveDone, AsyncCallback callback, object state)
- : base(onReceiveDone, callback, state, null)
- {
- this.InnerChannel = innerChannel;
-
- OriginalResult = innerChannel.BeginReceive(timeout, OnComplete, this);
- if ( OriginalResult.CompletedSynchronously )
+ catch (Exception ex)
{
- this.Message = innerChannel.EndReceive(OriginalResult);
- this.Complete(true);
+ this.LastException = ex;
}
- }
- private static void OnComplete(IAsyncResult result)
- {
- if ( result.CompletedSynchronously )
- {
- return;
- }
- ReceiveAsyncResult rar = (ReceiveAsyncResult)result.AsyncState;
+ // set the waitHandle so that when callback() calls EndWhatever()
+ // it doesn't hang
+ this.waitHandle.Set();
try
{
- rar.Message = rar.InnerChannel.EndReceive(rar.OriginalResult);
- rar.Complete(false);
- } catch ( Exception ex )
- {
- rar.Complete(false, ex);
+ this.callback?.Invoke(this);
}
- }
- }
-
- internal sealed class TryReceiveAsyncResult : ChannelAsyncResult
- {
- public IInputChannel InnerChannel { get; private set; }
- public Message Message { get; private set; }
- public bool Result { get; private set; }
-
- public TryReceiveAsyncResult(IInputChannel innerChannel, TimeSpan timeout, AsyncCallback onReceiveDone, AsyncCallback callback, object state)
- : base(onReceiveDone, callback, state, null)
- {
- this.InnerChannel = innerChannel;
-
- OriginalResult = innerChannel.BeginTryReceive(timeout, OnComplete, this);
- if ( OriginalResult.CompletedSynchronously )
+ catch (Exception ex)
{
- Message message = null;
- this.Result = innerChannel.EndTryReceive(OriginalResult, out message);
- this.Message = message;
- this.Complete(true);
+ this.LastException = ex;
}
}
- private static void OnComplete(IAsyncResult result)
+ protected void NotifyCompletionToChannel()
{
- if ( result.CompletedSynchronously )
- {
- return;
- }
- TryReceiveAsyncResult trar = (TryReceiveAsyncResult)result.AsyncState;
- try
- {
- Message message = null;
- trar.Result = trar.InnerChannel.EndTryReceive(trar.OriginalResult, out message);
- trar.Message = message;
- trar.Complete(false);
- } catch ( Exception ex )
- {
- trar.Complete(false, ex);
- }
+ this.channelCompletionCallback?.Invoke(this);
}
}
}
diff --git a/WCF/Shared/Implementation/ClientContract.cs b/WCF/Shared/Implementation/ClientContract.cs
index a86a305..1ced296 100644
--- a/WCF/Shared/Implementation/ClientContract.cs
+++ b/WCF/Shared/Implementation/ClientContract.cs
@@ -1,13 +1,12 @@
-using System;
-using System.Collections.Generic;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.Collections.Generic;
+ using System.ServiceModel.Description;
+
internal class ClientContract
{
- private IDictionary dictionary;
- public Type ContractType { get; private set; }
+ private IDictionary dictionary;
public ClientContract(Type contractType)
: this(ContractDescription.GetContract(contractType))
@@ -16,18 +15,20 @@ public ClientContract(Type contractType)
public ClientContract(ContractDescription description)
{
- ContractType = description.ContractType;
- dictionary = new Dictionary();
- foreach ( var op in description.Operations )
+ this.ContractType = description.ContractType;
+ this.dictionary = new Dictionary();
+ foreach (var op in description.Operations)
{
- var opDesc = new ClientOperation(ContractType.Name, op);
- dictionary.Add(opDesc.Action, opDesc);
+ var operationDesc = new ClientOperation(this.ContractType.Name, op);
+ this.dictionary.Add(operationDesc.Action, operationDesc);
}
}
- public bool TryLookupByAction(String soapAction, out ClientOperation operation)
+ public Type ContractType { get; private set; }
+
+ public bool TryLookupByAction(string soapAction, out ClientOperation operation)
{
- return dictionary.TryGetValue(soapAction, out operation);
+ return this.dictionary.TryGetValue(soapAction, out operation);
}
}
}
diff --git a/WCF/Shared/Implementation/ClientExceptionExtensions.cs b/WCF/Shared/Implementation/ClientExceptionExtensions.cs
index 6853719..5ca745a 100644
--- a/WCF/Shared/Implementation/ClientExceptionExtensions.cs
+++ b/WCF/Shared/Implementation/ClientExceptionExtensions.cs
@@ -1,32 +1,37 @@
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel;
+
internal static class ClientExceptionExtensions
{
- public static String ToResultCode(this Exception exception)
+ public static string ToResultCode(this Exception exception)
{
- if ( exception == null )
+ if (exception == null)
{
throw new ArgumentNullException(nameof(exception));
}
- if ( exception is TimeoutException )
+
+ if (exception is TimeoutException)
{
return "Timeout";
}
- if ( exception is EndpointNotFoundException )
+
+ if (exception is EndpointNotFoundException)
{
return "EndpointNotFound";
}
- if ( exception is ServerTooBusyException )
+
+ if (exception is ServerTooBusyException)
{
return "ServerTooBusy";
}
- if ( exception is FaultException )
+
+ if (exception is FaultException)
{
return "SoapFault";
}
+
return exception.GetType().Name;
}
}
diff --git a/WCF/Shared/Implementation/ClientOperation.cs b/WCF/Shared/Implementation/ClientOperation.cs
index 0a98b01..c8a16fa 100644
--- a/WCF/Shared/Implementation/ClientOperation.cs
+++ b/WCF/Shared/Implementation/ClientOperation.cs
@@ -1,20 +1,23 @@
-using System;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel.Description;
+
internal struct ClientOperation
{
- public String Action { get; private set; }
- public String Name { get; private set; }
- public bool IsOneWay { get; private set; }
-
- public ClientOperation(String contractName, OperationDescription description)
+ public ClientOperation(string contractName, OperationDescription description)
{
- Action = description.Messages[0].Action;
- IsOneWay = description.IsOneWay;
+ this.Action = description.Messages[0].Action;
+ this.IsOneWay = description.IsOneWay;
+
// Doing this here means we won't need to concatenate on each service call
- Name = contractName + "." + description.Name;
+ this.Name = contractName + "." + description.Name;
}
+
+ public string Action { get; private set; }
+
+ public string Name { get; private set; }
+
+ public bool IsOneWay { get; private set; }
}
}
diff --git a/WCF/Shared/Implementation/ClientTelemetryBindingElement.cs b/WCF/Shared/Implementation/ClientTelemetryBindingElement.cs
index 69e0d62..ef872f7 100644
--- a/WCF/Shared/Implementation/ClientTelemetryBindingElement.cs
+++ b/WCF/Shared/Implementation/ClientTelemetryBindingElement.cs
@@ -1,36 +1,42 @@
-using System;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel.Channels;
+
internal sealed class ClientTelemetryBindingElement : BindingElement
{
private TelemetryClient telemetryClient;
private ClientContract operationMap;
- public String RootOperationIdHeaderName { get; set; }
- public String ParentOperationIdHeaderName { get; set; }
- public String SoapRootOperationIdHeaderName { get; set; }
- public String SoapParentOperationIdHeaderName { get; set; }
- public String SoapHeaderNamespace { get; set; }
-
public ClientTelemetryBindingElement(TelemetryClient client, ClientContract map)
{
- if ( client == null )
+ if (client == null)
{
throw new ArgumentNullException(nameof(client));
}
- if ( map == null )
+
+ if (map == null)
{
throw new ArgumentNullException(nameof(map));
}
+
this.telemetryClient = client;
this.operationMap = map;
}
+ public string RootOperationIdHeaderName { get; set; }
+
+ public string ParentOperationIdHeaderName { get; set; }
+
+ public string SoapRootOperationIdHeaderName { get; set; }
+
+ public string SoapParentOperationIdHeaderName { get; set; }
+
+ public string SoapHeaderNamespace { get; set; }
+
public override BindingElement Clone()
{
- return new ClientTelemetryBindingElement(telemetryClient, operationMap);
+ return new ClientTelemetryBindingElement(this.telemetryClient, this.operationMap);
}
public override T GetProperty(BindingContext context)
@@ -38,57 +44,63 @@ public override T GetProperty(BindingContext context)
return context.GetInnerProperty();
}
-
public override bool CanBuildChannelFactory(BindingContext context)
{
- if ( context == null )
+ if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
- if ( IsSupportedChannelShape(typeof(TChannel)) )
+
+ if (this.IsSupportedChannelShape(typeof(TChannel)))
{
return context.CanBuildInnerChannelFactory();
}
+
return false;
}
public override IChannelFactory BuildChannelFactory(BindingContext context)
{
- if ( context == null )
+ if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
- if ( !IsSupportedChannelShape(typeof(TChannel)) )
+
+ if (!this.IsSupportedChannelShape(typeof(TChannel)))
{
throw new InvalidOperationException("Unsupported channel shape: " + typeof(TChannel));
}
- var innerFactory = context.BuildInnerChannelFactory();
- var factory = new ClientTelemetryChannelFactory(context.Binding, innerFactory, telemetryClient, operationMap);
- factory.RootOperationIdHeaderName = RootOperationIdHeaderName;
- factory.ParentOperationIdHeaderName = ParentOperationIdHeaderName;
- factory.SoapRootOperationIdHeaderName = SoapRootOperationIdHeaderName;
- factory.SoapParentOperationIdHeaderName = SoapParentOperationIdHeaderName;
- factory.SoapHeaderNamespace = SoapHeaderNamespace;
+ var innerFactory = context.BuildInnerChannelFactory();
+ var factory = new ClientTelemetryChannelFactory(context.Binding, innerFactory, this.telemetryClient, this.operationMap)
+ {
+ RootOperationIdHeaderName = this.RootOperationIdHeaderName,
+ ParentOperationIdHeaderName = this.ParentOperationIdHeaderName,
+ SoapRootOperationIdHeaderName = this.SoapRootOperationIdHeaderName,
+ SoapParentOperationIdHeaderName = this.SoapParentOperationIdHeaderName,
+ SoapHeaderNamespace = this.SoapHeaderNamespace
+ };
return factory;
}
private bool IsSupportedChannelShape(Type type)
{
- if ( type == typeof(IRequestChannel) || type == typeof(IRequestSessionChannel) )
+ if (type == typeof(IRequestChannel) || type == typeof(IRequestSessionChannel))
{
return true;
}
- if ( type == typeof(IOutputChannel) || type == typeof(IOutputSessionChannel) )
+
+ if (type == typeof(IOutputChannel) || type == typeof(IOutputSessionChannel))
{
return true;
}
- if ( type == typeof(IDuplexChannel) || type == typeof(IDuplexSessionChannel) )
+
+ if (type == typeof(IDuplexChannel) || type == typeof(IDuplexSessionChannel))
{
return true;
}
+
return false;
}
-
}
}
diff --git a/WCF/Shared/Implementation/ClientTelemetryChannelBase.cs b/WCF/Shared/Implementation/ClientTelemetryChannelBase.cs
index 29a9149..01f2e79 100644
--- a/WCF/Shared/Implementation/ClientTelemetryChannelBase.cs
+++ b/WCF/Shared/Implementation/ClientTelemetryChannelBase.cs
@@ -1,247 +1,182 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using System;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-using System.Threading;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+
internal abstract class ClientTelemetryChannelBase : IDisposable
{
- protected IChannel InnerChannel { get; private set; }
- protected IChannelManager ChannelManager { get; private set; }
-
- public CommunicationState State
- {
- get { return InnerChannel.State; }
- }
-
- public abstract EndpointAddress RemoteAddress { get; }
-
- public event EventHandler Closed;
- public event EventHandler Closing;
- public event EventHandler Faulted;
- public event EventHandler Opened;
- public event EventHandler Opening;
-
public ClientTelemetryChannelBase(IChannelManager channelManager, IChannel channel)
{
- if ( channelManager == null )
+ if (channelManager == null)
{
throw new ArgumentNullException(nameof(channelManager));
}
- if ( channel == null )
+
+ if (channel == null)
{
throw new ArgumentNullException(nameof(channel));
}
+
this.ChannelManager = channelManager;
this.InnerChannel = channel;
}
+ public event EventHandler Closed;
+
+ public event EventHandler Closing;
+
+ public event EventHandler Faulted;
+
+ public event EventHandler Opened;
+
+ public event EventHandler Opening;
+
+ public CommunicationState State
+ {
+ get { return this.InnerChannel.State; }
+ }
+
+ public abstract EndpointAddress RemoteAddress { get; }
+
+ protected IChannel InnerChannel { get; private set; }
+
+ protected IChannelManager ChannelManager { get; private set; }
+
public void Open()
{
- Open(ChannelManager.OpenTimeout);
+ this.Open(this.ChannelManager.OpenTimeout);
}
public void Open(TimeSpan timeout)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(Open));
- HookChannelEvents();
- var telemetry = this.StartOpenTelemetry(nameof(Open));
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.Open));
+ this.HookChannelEvents();
+ var telemetry = this.StartOpenTelemetry(nameof(this.Open));
try
{
- InnerChannel.Open(timeout);
- this.StopOpenTelemetry(telemetry, null, nameof(Open));
- } catch ( Exception ex )
+ this.InnerChannel.Open(timeout);
+ this.StopOpenTelemetry(telemetry, null, nameof(this.Open));
+ }
+ catch (Exception ex)
{
- this.StopOpenTelemetry(telemetry, ex, nameof(Open));
+ this.StopOpenTelemetry(telemetry, ex, nameof(this.Open));
throw;
}
}
public void Close()
{
- Close(ChannelManager.CloseTimeout);
+ this.Close(this.ChannelManager.CloseTimeout);
}
public void Close(TimeSpan timeout)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(Close));
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.Close));
try
{
- InnerChannel.Close(timeout);
- } finally
+ this.InnerChannel.Close(timeout);
+ }
+ finally
{
- Dispose(true);
+ this.Dispose(true);
}
}
public void Abort()
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(Abort));
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.Abort));
try
{
- InnerChannel.Abort();
- } finally
+ this.InnerChannel.Abort();
+ }
+ finally
{
- Dispose(true);
+ this.Dispose(true);
}
}
public T GetProperty() where T : class
{
- return InnerChannel.GetProperty();
+ return this.InnerChannel.GetProperty();
}
- //
+ // -------------------------------------
// Async Methods
- //
+ // -------------------------------------
public IAsyncResult BeginOpen(AsyncCallback callback, object state)
{
- return BeginOpen(this.ChannelManager.OpenTimeout, callback, state);
+ return this.BeginOpen(this.ChannelManager.OpenTimeout, callback, state);
}
public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(BeginOpen));
- HookChannelEvents();
- var telemetry = StartOpenTelemetry(nameof(BeginOpen));
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.BeginOpen));
+ this.HookChannelEvents();
+ var telemetry = this.StartOpenTelemetry(nameof(this.BeginOpen));
try
{
- return new OpenAsyncResult(InnerChannel, timeout, this.OpenCompleted, callback, state, telemetry);
- } catch ( Exception ex )
+ return new OpenAsyncResult(this.InnerChannel, timeout, this.OpenCompleted, callback, state, telemetry);
+ }
+ catch (Exception ex)
{
- StopOpenTelemetry(telemetry, ex, nameof(BeginOpen));
+ this.StopOpenTelemetry(telemetry, ex, nameof(this.BeginOpen));
throw;
}
}
public void EndOpen(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(EndOpen));
- OpenAsyncResult.End(result);
- }
- private void OpenCompleted(IAsyncResult result)
- {
- if ( result == null )
- {
- throw new ArgumentNullException(nameof(result));
- }
- var oar = (OpenAsyncResult)result;
- StopOpenTelemetry(oar.Telemetry, oar.LastException, nameof(OpenCompleted));
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.EndOpen));
+ OpenAsyncResult.End(result);
}
public IAsyncResult BeginClose(AsyncCallback callback, object state)
{
- return BeginClose(ChannelManager.CloseTimeout, callback, state);
+ return this.BeginClose(this.ChannelManager.CloseTimeout, callback, state);
}
public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(BeginClose));
- return InnerChannel.BeginClose(timeout, callback, state);
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.BeginClose));
+ return this.InnerChannel.BeginClose(timeout, callback, state);
}
public void EndClose(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(EndClose));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.EndClose));
try
{
- InnerChannel.EndClose(result);
- } finally
+ this.InnerChannel.EndClose(result);
+ }
+ finally
{
- Dispose(true);
+ this.Dispose(true);
}
}
-
- private void HookChannelEvents()
- {
- InnerChannel.Closed += OnChannelClosed;
- InnerChannel.Closing += OnChannelClosing;
- InnerChannel.Opened += OnChannelOpened;
- InnerChannel.Opening += OnChannelOpening;
- InnerChannel.Faulted += OnChannelFaulted;
- }
- private void UnhookChannelEvents()
- {
- InnerChannel.Closed -= OnChannelClosed;
- InnerChannel.Closing -= OnChannelClosing;
- InnerChannel.Opened -= OnChannelOpened;
- InnerChannel.Opening -= OnChannelOpening;
- InnerChannel.Faulted -= OnChannelFaulted;
- }
- private void OnChannelOpened(object sender, EventArgs e)
- {
- Opened?.Invoke(this, e);
- }
- private void OnChannelOpening(object sender, EventArgs e)
- {
- Opening?.Invoke(this, e);
- }
- private void OnChannelClosed(object sender, EventArgs e)
- {
- Closed?.Invoke(sender, e);
- }
- private void OnChannelClosing(object sender, EventArgs e)
- {
- Closing?.Invoke(sender, e);
- }
- private void OnChannelFaulted(object sender, EventArgs e)
+ void IDisposable.Dispose()
{
- Faulted?.Invoke(sender, e);
+ this.Dispose(true);
}
-
// telemetry implementation
- private DependencyTelemetry StartOpenTelemetry(String method)
- {
- try
- {
- var telemetry = new DependencyTelemetry();
- telemetry.Start();
- telemetry.Type = DependencyConstants.WcfChannelOpen;
- telemetry.Target = RemoteAddress.Uri.Host;
- telemetry.Data = RemoteAddress.Uri.ToString();
- telemetry.Name = ChannelManager.OperationMap.ContractType.Name;
- return telemetry;
- } catch ( Exception ex )
- {
- WcfClientEventSource.Log.ClientTelemetryError(method, ex.ToString());
- return null;
- }
- }
- private void StopOpenTelemetry(DependencyTelemetry telemetry, Exception error, String method)
- {
- if ( telemetry == null )
- {
- return;
- }
- try
- {
- telemetry.Success = error == null;
- telemetry.Stop();
- ChannelManager.TelemetryClient.TrackDependency(telemetry);
- } catch ( Exception ex )
- {
- WcfClientEventSource.Log.ClientTelemetryError(method, ex.ToString());
- }
- }
-
- protected DependencyTelemetry StartSendTelemetry(Message request, String method)
+ protected DependencyTelemetry StartSendTelemetry(Message request, string method)
{
var soapAction = request.Headers.Action;
ClientOperation operation;
- if ( !ChannelManager.OperationMap.TryLookupByAction(soapAction, out operation) )
+ if (!this.ChannelManager.OperationMap.TryLookupByAction(soapAction, out operation))
{
return null;
}
@@ -249,113 +184,211 @@ protected DependencyTelemetry StartSendTelemetry(Message request, String method)
try
{
var telemetry = new DependencyTelemetry();
- ChannelManager.TelemetryClient.Initialize(telemetry);
+ this.ChannelManager.TelemetryClient.Initialize(telemetry);
telemetry.Start();
telemetry.Type = DependencyConstants.WcfClientCall;
- telemetry.Target = RemoteAddress.Uri.Host;
- telemetry.Data = RemoteAddress.Uri.ToString();
+ telemetry.Target = this.RemoteAddress.Uri.Host;
+ telemetry.Data = this.RemoteAddress.Uri.ToString();
telemetry.Name = operation.Name;
telemetry.Properties[DependencyConstants.SoapActionProperty] = soapAction;
- if ( operation.IsOneWay )
+ if (operation.IsOneWay)
{
- telemetry.Properties[DependencyConstants.IsOneWayProperty] = Boolean.TrueString;
+ telemetry.Properties[DependencyConstants.IsOneWayProperty] = bool.TrueString;
}
- SetCorrelationHeaders(telemetry, request);
+
+ this.SetCorrelationHeaders(telemetry, request);
return telemetry;
- } catch ( Exception ex )
+ }
+ catch (Exception ex)
{
WcfClientEventSource.Log.ClientTelemetryError(method, ex.ToString());
return null;
}
}
- protected void StopSendTelemetry(DependencyTelemetry telemetry, Message response, Exception error, String method)
+
+ protected void StopSendTelemetry(DependencyTelemetry telemetry, Message response, Exception error, string method)
{
- if ( telemetry == null )
+ if (telemetry == null)
{
return;
}
+
try
{
- if ( error != null )
+ if (error != null)
{
telemetry.Success = false;
telemetry.ResultCode = error.ToResultCode();
}
- if ( response != null && response.IsFault )
+
+ if (response != null && response.IsFault)
{
telemetry.Success = false;
telemetry.ResultCode = "SoapFault";
}
+
telemetry.Stop();
- ChannelManager.TelemetryClient.TrackDependency(telemetry);
- } catch ( Exception ex )
+ this.ChannelManager.TelemetryClient.TrackDependency(telemetry);
+ }
+ catch (Exception ex)
{
WcfClientEventSource.Log.ClientTelemetryError(method, ex.ToString());
}
}
+
protected bool IsOneWay(DependencyTelemetry telemetry)
{
- String value;
- if ( telemetry.Properties.TryGetValue(DependencyConstants.IsOneWayProperty, out value) )
+ string value;
+ if (telemetry.Properties.TryGetValue(DependencyConstants.IsOneWayProperty, out value))
{
- return Boolean.Parse(value);
+ return bool.Parse(value);
}
+
return false;
}
- void IDisposable.Dispose()
+ protected void Dispose(bool disposing)
{
- this.Dispose(true);
+ this.UnhookChannelEvents();
+ this.OnClosed();
}
- protected void Dispose(bool disposing)
+ protected virtual void OnClosed()
{
- UnhookChannelEvents();
- OnClosed();
}
- protected virtual void OnClosed()
+
+ private static void SetSoapHeader(Message message, string soapNS, string header, string value)
{
+ var currentHeader = message.Headers.FindHeader(header, soapNS);
+ if (currentHeader < 0)
+ {
+ var soapHeader = MessageHeader.CreateHeader(header, soapNS, value);
+ message.Headers.Add(soapHeader);
+ }
+ }
+
+ private static string ValueOrDefault(string value, string defaultValue)
+ {
+ return string.IsNullOrEmpty(value) ? defaultValue : value;
+ }
+
+ private void HookChannelEvents()
+ {
+ this.InnerChannel.Closed += this.OnChannelClosed;
+ this.InnerChannel.Closing += this.OnChannelClosing;
+ this.InnerChannel.Opened += this.OnChannelOpened;
+ this.InnerChannel.Opening += this.OnChannelOpening;
+ this.InnerChannel.Faulted += this.OnChannelFaulted;
+ }
+
+ private void UnhookChannelEvents()
+ {
+ this.InnerChannel.Closed -= this.OnChannelClosed;
+ this.InnerChannel.Closing -= this.OnChannelClosing;
+ this.InnerChannel.Opened -= this.OnChannelOpened;
+ this.InnerChannel.Opening -= this.OnChannelOpening;
+ this.InnerChannel.Faulted -= this.OnChannelFaulted;
+ }
+
+ private void OpenCompleted(IAsyncResult result)
+ {
+ if (result == null)
+ {
+ throw new ArgumentNullException(nameof(result));
+ }
+
+ var oar = (OpenAsyncResult)result;
+ this.StopOpenTelemetry(oar.Telemetry, oar.LastException, nameof(this.OpenCompleted));
+ }
+
+ private void OnChannelOpened(object sender, EventArgs e)
+ {
+ this.Opened?.Invoke(this, e);
+ }
+
+ private void OnChannelOpening(object sender, EventArgs e)
+ {
+ this.Opening?.Invoke(this, e);
+ }
+
+ private void OnChannelClosed(object sender, EventArgs e)
+ {
+ this.Closed?.Invoke(sender, e);
+ }
+
+ private void OnChannelClosing(object sender, EventArgs e)
+ {
+ this.Closing?.Invoke(sender, e);
+ }
+
+ private void OnChannelFaulted(object sender, EventArgs e)
+ {
+ this.Faulted?.Invoke(sender, e);
+ }
+
+ private DependencyTelemetry StartOpenTelemetry(string method)
+ {
+ try
+ {
+ var telemetry = new DependencyTelemetry();
+ telemetry.Start();
+ telemetry.Type = DependencyConstants.WcfChannelOpen;
+ telemetry.Target = this.RemoteAddress.Uri.Host;
+ telemetry.Data = this.RemoteAddress.Uri.ToString();
+ telemetry.Name = this.ChannelManager.OperationMap.ContractType.Name;
+ return telemetry;
+ }
+ catch (Exception ex)
+ {
+ WcfClientEventSource.Log.ClientTelemetryError(method, ex.ToString());
+ return null;
+ }
+ }
+
+ private void StopOpenTelemetry(DependencyTelemetry telemetry, Exception error, string method)
+ {
+ if (telemetry == null)
+ {
+ return;
+ }
+
+ try
+ {
+ telemetry.Success = error == null;
+ telemetry.Stop();
+ this.ChannelManager.TelemetryClient.TrackDependency(telemetry);
+ }
+ catch (Exception ex)
+ {
+ WcfClientEventSource.Log.ClientTelemetryError(method, ex.ToString());
+ }
}
private void SetCorrelationHeaders(DependencyTelemetry telemetry, Message message)
{
var httpHeaders = message.GetHttpRequestHeaders();
- var rootIdHttpHeader = ValueOrDefault(ChannelManager.RootOperationIdHeaderName, CorrelationHeaders.HttpStandardRootIdHeader);
- var rootIdSoapHeader = ValueOrDefault(ChannelManager.SoapRootOperationIdHeaderName, CorrelationHeaders.SoapStandardRootIdHeader);
- var parentIdHttpHeader = ValueOrDefault(ChannelManager.ParentOperationIdHeaderName, CorrelationHeaders.HttpStandardParentIdHeader);
- var parentIdSoapHeader = ValueOrDefault(ChannelManager.SoapParentOperationIdHeaderName, CorrelationHeaders.SoapStandardParentIdHeader);
+ var rootIdHttpHeader = ValueOrDefault(this.ChannelManager.RootOperationIdHeaderName, CorrelationHeaders.HttpStandardRootIdHeader);
+ var rootIdSoapHeader = ValueOrDefault(this.ChannelManager.SoapRootOperationIdHeaderName, CorrelationHeaders.SoapStandardRootIdHeader);
+ var parentIdHttpHeader = ValueOrDefault(this.ChannelManager.ParentOperationIdHeaderName, CorrelationHeaders.HttpStandardParentIdHeader);
+ var parentIdSoapHeader = ValueOrDefault(this.ChannelManager.SoapParentOperationIdHeaderName, CorrelationHeaders.SoapStandardParentIdHeader);
+
// "" is a valid value for the namespace
- var soapNS = ChannelManager.SoapHeaderNamespace != null ? ChannelManager.SoapHeaderNamespace : CorrelationHeaders.SoapStandardNamespace;
+ var soapNS = this.ChannelManager.SoapHeaderNamespace ?? CorrelationHeaders.SoapStandardNamespace;
var rootId = telemetry.Context.Operation.Id;
- if ( !String.IsNullOrEmpty(rootId) )
+ if (!string.IsNullOrEmpty(rootId))
{
httpHeaders.Headers[rootIdHttpHeader] = rootId;
SetSoapHeader(message, soapNS, rootIdSoapHeader, rootId);
}
var parentId = telemetry.Id;
- if ( !String.IsNullOrEmpty(parentId) )
+ if (!string.IsNullOrEmpty(parentId))
{
httpHeaders.Headers[parentIdHttpHeader] = parentId;
SetSoapHeader(message, soapNS, parentIdSoapHeader, parentId);
}
}
-
- private void SetSoapHeader(Message message, String soapNS, String header, String value)
- {
- int currentHeader = message.Headers.FindHeader(header, soapNS);
- if ( currentHeader < 0 )
- {
- var soapHeader = MessageHeader.CreateHeader(header, soapNS, value);
- message.Headers.Add(soapHeader);
- }
- }
-
- private String ValueOrDefault(String value, String defaultValue)
- {
- return String.IsNullOrEmpty(value) ? defaultValue : value;
- }
}
}
diff --git a/WCF/Shared/Implementation/ClientTelemetryChannelFactory.cs b/WCF/Shared/Implementation/ClientTelemetryChannelFactory.cs
index fd011dd..43d9b41 100644
--- a/WCF/Shared/Implementation/ClientTelemetryChannelFactory.cs
+++ b/WCF/Shared/Implementation/ClientTelemetryChannelFactory.cs
@@ -1,35 +1,31 @@
-using System;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+
internal sealed class ClientTelemetryChannelFactory : ChannelFactoryBase, IChannelManager
{
private IChannelFactory innerFactory;
- public TelemetryClient TelemetryClient { get; private set; }
- public ClientContract OperationMap { get; set; }
- public String RootOperationIdHeaderName { get; set; }
- public String ParentOperationIdHeaderName { get; set; }
- public String SoapRootOperationIdHeaderName { get; set; }
- public String SoapParentOperationIdHeaderName { get; set; }
- public String SoapHeaderNamespace { get; set; }
public ClientTelemetryChannelFactory(Binding binding, IChannelFactory factory, TelemetryClient client, ClientContract map)
: base(binding)
{
- if ( factory == null )
+ if (factory == null)
{
- throw new ArgumentNullException(nameof(factory));
+ throw new ArgumentNullException(nameof(factory));
}
- if ( client == null )
+
+ if (client == null)
{
throw new ArgumentNullException(nameof(client));
}
- if ( map == null )
+
+ if (map == null)
{
throw new ArgumentNullException(nameof(map));
}
+
this.innerFactory = factory;
this.TelemetryClient = client;
this.OperationMap = map;
@@ -37,25 +33,42 @@ public ClientTelemetryChannelFactory(Binding binding, IChannelFactory
WcfClientEventSource.Log.ChannelFactoryCreated(typeof(TChannel).FullName);
}
+ public TelemetryClient TelemetryClient { get; private set; }
+
+ public ClientContract OperationMap { get; set; }
+
+ public string RootOperationIdHeaderName { get; set; }
+
+ public string ParentOperationIdHeaderName { get; set; }
+
+ public string SoapRootOperationIdHeaderName { get; set; }
+
+ public string SoapParentOperationIdHeaderName { get; set; }
+
+ public string SoapHeaderNamespace { get; set; }
+
public override T GetProperty()
{
- return innerFactory.GetProperty();
+ return this.innerFactory.GetProperty();
}
protected override void OnOpen(TimeSpan timeout)
{
this.innerFactory.Open(timeout);
}
+
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
return this.innerFactory.BeginOpen(timeout, callback, state);
}
+
protected override void OnEndOpen(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
+
this.innerFactory.EndOpen(result);
}
@@ -63,18 +76,22 @@ protected override void OnClose(TimeSpan timeout)
{
this.innerFactory.Close(timeout);
}
+
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
return this.innerFactory.BeginClose(timeout, callback, state);
}
+
protected override void OnEndClose(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
+
this.innerFactory.EndClose(result);
}
+
protected override void OnAbort()
{
this.innerFactory.Abort();
@@ -82,28 +99,31 @@ protected override void OnAbort()
protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
{
- if ( address == null )
+ if (address == null)
{
throw new ArgumentNullException(nameof(address));
}
var channel = this.innerFactory.CreateChannel(address, via);
IChannel newChannel = null;
- if ( typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel) )
+ if (typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel))
{
newChannel = new ClientTelemetryRequestChannel(this, (IChannel)channel);
- } else if ( typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IOutputSessionChannel) )
+ }
+ else if (typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IOutputSessionChannel))
{
newChannel = new ClientTelemetryOutputChannel(this, (IChannel)channel);
- } else if ( typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel) )
+ }
+ else if (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel))
{
newChannel = new ClientTelemetryDuplexChannel(this, (IChannel)channel);
- } else
+ }
+ else
{
throw new NotSupportedException("Channel shape is not supported: " + typeof(TChannel));
}
+
return (TChannel)(object)newChannel;
}
-
}
}
diff --git a/WCF/Shared/Implementation/ClientTelemetryDuplexChannel.cs b/WCF/Shared/Implementation/ClientTelemetryDuplexChannel.cs
index a714c2d..1459815 100644
--- a/WCF/Shared/Implementation/ClientTelemetryDuplexChannel.cs
+++ b/WCF/Shared/Implementation/ClientTelemetryDuplexChannel.cs
@@ -1,13 +1,10 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using System;
-using System.Collections.Generic;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-using System.Text;
-using System.Xml;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.Xml;
+ using Microsoft.ApplicationInsights.DataContracts;
// An IRequestChannel is simulated on top of a duplex channel is
// done by DuplexChannelBinder.Request() by correlating messages based on the message id
@@ -22,238 +19,255 @@ internal sealed class ClientTelemetryDuplexChannel : ClientTelemetryChannelBase,
{
private MessageCorrelator correlator;
- private IDuplexChannel DuplexChannel
+ public ClientTelemetryDuplexChannel(IChannelManager channelManager, IChannel channel)
+ : base(channelManager, channel)
{
- get { return (IDuplexChannel)InnerChannel; }
+ this.correlator = new MessageCorrelator(this.OnRequestTimeout);
}
+
public EndpointAddress LocalAddress
{
- get { return DuplexChannel.LocalAddress; }
+ get { return this.DuplexChannel.LocalAddress; }
}
+
public IDuplexSession Session
{
- get { return ((IDuplexSessionChannel)DuplexChannel).Session; }
+ get { return ((IDuplexSessionChannel)this.DuplexChannel).Session; }
}
+
public Uri Via
{
- get { return DuplexChannel.Via; }
+ get { return this.DuplexChannel.Via; }
}
public override EndpointAddress RemoteAddress
{
- get { return DuplexChannel.RemoteAddress; }
+ get { return this.DuplexChannel.RemoteAddress; }
}
- public ClientTelemetryDuplexChannel(IChannelManager channelManager, IChannel channel)
- : base(channelManager, channel)
+ private IDuplexChannel DuplexChannel
{
- correlator = new MessageCorrelator(this.OnRequestTimeout);
+ get { return (IDuplexChannel)this.InnerChannel; }
}
- //
+ // ------------------------
// Send side
- //
+ // ------------------------
public void Send(Message message)
{
- Send(message, ChannelManager.SendTimeout);
+ this.Send(message, this.ChannelManager.SendTimeout);
}
public void Send(Message message, TimeSpan timeout)
{
- if ( message == null )
+ if (message == null)
{
throw new ArgumentNullException(nameof(message));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(Send));
- var telemetry = StartSendTelemetry(message, nameof(Send));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.Send));
+ var telemetry = StartSendTelemetry(message, nameof(this.Send));
try
{
- bool isOneWay = IsOneWay(telemetry);
- DuplexChannel.Send(message, timeout);
- if ( isOneWay )
+ var isOneWay = IsOneWay(telemetry);
+ this.DuplexChannel.Send(message, timeout);
+ if (isOneWay)
{
// no matching receive
- StopSendTelemetry(telemetry, null, null, nameof(Send));
- } else
+ this.StopSendTelemetry(telemetry, null, null, nameof(this.Send));
+ }
+ else
{
- correlator.Add(message.Headers.MessageId, telemetry, timeout);
+ this.correlator.Add(message.Headers.MessageId, telemetry, timeout);
}
- } catch ( Exception ex )
+ }
+ catch (Exception ex)
{
- StopSendTelemetry(telemetry, null, ex, nameof(Send));
+ this.StopSendTelemetry(telemetry, null, ex, nameof(this.Send));
throw;
}
}
public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
{
- return BeginSend(message, ChannelManager.SendTimeout, callback, state);
+ return this.BeginSend(message, this.ChannelManager.SendTimeout, callback, state);
}
public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
- if ( message == null )
+ if (message == null)
{
throw new ArgumentNullException(nameof(message));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(BeginSend));
- var telemetry = StartSendTelemetry(message, nameof(BeginSend));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.BeginSend));
+ var telemetry = StartSendTelemetry(message, nameof(this.BeginSend));
try
{
- var result = new SendAsyncResult(DuplexChannel, message, timeout, this.OnSendDone, callback, state, telemetry);
- correlator.Add(message.Headers.MessageId, telemetry, timeout);
+ var result = new SendAsyncResult(this.DuplexChannel, message, timeout, this.OnSendDone, callback, state, telemetry);
+ this.correlator.Add(message.Headers.MessageId, telemetry, timeout);
return result;
- } catch ( Exception ex )
+ }
+ catch (Exception ex)
{
- StopSendTelemetry(telemetry, null, ex, nameof(BeginSend));
+ this.StopSendTelemetry(telemetry, null, ex, nameof(this.BeginSend));
throw;
}
}
public void EndSend(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(EndSend));
- SendAsyncResult.End(result);
- }
- private void OnSendDone(IAsyncResult result)
- {
- SendAsyncResult sar = (SendAsyncResult)result;
-
- if ( IsOneWay(sar.Telemetry) || sar.LastException != null )
- {
- // not expecting reply
- correlator.Remove(sar.RequestId);
- StopSendTelemetry(sar.Telemetry, null, sar.LastException, nameof(OnSendDone));
- }
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.EndSend));
+ SendAsyncResult.End(result);
}
-
- //
+ // -------------------------------------------
// Receive Side
- //
-
+ // -------------------------------------------
// Both Receive and Receive(timeout) should fail with a
// if we get a timeout, we have no way of knowing which
// outstanding message it closed :(
public Message Receive()
{
- return Receive(ChannelManager.ReceiveTimeout);
+ return this.Receive(this.ChannelManager.ReceiveTimeout);
}
public Message Receive(TimeSpan timeout)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(Receive));
- var response = DuplexChannel.Receive(timeout);
- if ( response != null )
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.Receive));
+ var response = this.DuplexChannel.Receive(timeout);
+ if (response != null)
{
- HandleReply(response);
+ this.HandleReply(response);
}
+
return response;
}
public bool TryReceive(TimeSpan timeout, out Message message)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(TryReceive));
- bool success = DuplexChannel.TryReceive(timeout, out message);
- if ( success && message != null )
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.TryReceive));
+ var success = this.DuplexChannel.TryReceive(timeout, out message);
+ if (success && message != null)
{
- HandleReply(message);
+ this.HandleReply(message);
}
+
return success;
}
public bool WaitForMessage(TimeSpan timeout)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(WaitForMessage));
- return DuplexChannel.WaitForMessage(timeout);
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.WaitForMessage));
+ return this.DuplexChannel.WaitForMessage(timeout);
}
public IAsyncResult BeginReceive(AsyncCallback callback, object state)
{
- return BeginReceive(ChannelManager.ReceiveTimeout, callback, state);
+ return this.BeginReceive(this.ChannelManager.ReceiveTimeout, callback, state);
}
public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(BeginReceive));
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.BeginReceive));
return new ReceiveAsyncResult(this.DuplexChannel, timeout, null, callback, state);
}
+
public Message EndReceive(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(EndReceive));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.EndReceive));
var rar = ReceiveAsyncResult.End(result);
- if ( rar.Message != null )
+ if (rar.Message != null)
{
this.HandleReply(rar.Message);
}
+
return rar.Message;
}
public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(BeginTryReceive));
- return new TryReceiveAsyncResult(DuplexChannel, timeout, null, callback, state);
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.BeginTryReceive));
+ return new TryReceiveAsyncResult(this.DuplexChannel, timeout, null, callback, state);
}
+
public bool EndTryReceive(IAsyncResult result, out Message message)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(EndTryReceive));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.EndTryReceive));
var trar = TryReceiveAsyncResult.End(result);
message = trar.Message;
- if ( trar.Result && message != null )
+ if (trar.Result && message != null)
{
this.HandleReply(message);
}
+
return trar.Result;
}
-
public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
{
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(BeginWaitForMessage));
- return DuplexChannel.BeginWaitForMessage(timeout, callback, state);
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.BeginWaitForMessage));
+ return this.DuplexChannel.BeginWaitForMessage(timeout, callback, state);
}
+
public bool EndWaitForMessage(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(EndWaitForMessage));
- return DuplexChannel.EndWaitForMessage(result);
- }
-
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.EndWaitForMessage));
+ return this.DuplexChannel.EndWaitForMessage(result);
+ }
protected override void OnClosed()
{
- correlator.Dispose();
+ this.correlator.Dispose();
base.OnClosed();
}
+
+ private void OnSendDone(IAsyncResult result)
+ {
+ var sar = (SendAsyncResult)result;
+
+ if (this.IsOneWay(sar.Telemetry) || sar.LastException != null)
+ {
+ // not expecting reply
+ this.correlator.Remove(sar.RequestId);
+ this.StopSendTelemetry(sar.Telemetry, null, sar.LastException, nameof(this.OnSendDone));
+ }
+ }
+
private void HandleReply(Message reply)
{
DependencyTelemetry telemetry = null;
- if ( correlator.TryLookup(reply.Headers.RelatesTo, out telemetry) )
+ if (this.correlator.TryLookup(reply.Headers.RelatesTo, out telemetry))
{
- StopSendTelemetry(telemetry, reply, null, nameof(HandleReply));
+ this.StopSendTelemetry(telemetry, reply, null, nameof(this.HandleReply));
}
+
// not our message, leave it be
}
+
private void OnRequestTimeout(UniqueId messageId, DependencyTelemetry telemetry)
{
- StopSendTelemetry(telemetry, null, new TimeoutException(), nameof(OnRequestTimeout));
+ this.StopSendTelemetry(telemetry, null, new TimeoutException(), nameof(this.OnRequestTimeout));
}
}
}
diff --git a/WCF/Shared/Implementation/ClientTelemetryOutputChannel.cs b/WCF/Shared/Implementation/ClientTelemetryOutputChannel.cs
index 8f368f9..df7ec2b 100644
--- a/WCF/Shared/Implementation/ClientTelemetryOutputChannel.cs
+++ b/WCF/Shared/Implementation/ClientTelemetryOutputChannel.cs
@@ -1,100 +1,107 @@
-using System;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
- sealed class ClientTelemetryOutputChannel : ClientTelemetryChannelBase, IOutputChannel, IOutputSessionChannel
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+
+ internal sealed class ClientTelemetryOutputChannel : ClientTelemetryChannelBase, IOutputChannel, IOutputSessionChannel
{
- private IOutputChannel OutputChannel
+ public ClientTelemetryOutputChannel(IChannelManager channelManager, IChannel channel)
+ : base(channelManager, channel)
{
- get { return (IOutputChannel)InnerChannel; }
}
public override EndpointAddress RemoteAddress
{
- get { return OutputChannel.RemoteAddress; }
+ get { return this.OutputChannel.RemoteAddress; }
}
+
public Uri Via
{
- get { return OutputChannel.Via; }
+ get { return this.OutputChannel.Via; }
}
public IOutputSession Session
{
- get { return ((IOutputSessionChannel)InnerChannel).Session; }
+ get { return ((IOutputSessionChannel)this.InnerChannel).Session; }
}
- public ClientTelemetryOutputChannel(IChannelManager channelManager, IChannel channel)
- : base(channelManager, channel)
+ private IOutputChannel OutputChannel
{
+ get { return (IOutputChannel)this.InnerChannel; }
}
public void Send(Message message)
{
- Send(message, ChannelManager.SendTimeout);
+ this.Send(message, this.ChannelManager.SendTimeout);
}
public void Send(Message message, TimeSpan timeout)
{
- if ( message == null )
+ if (message == null)
{
throw new ArgumentNullException(nameof(message));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(Send));
- var telemetry = StartSendTelemetry(message, nameof(Send));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.Send));
+ var telemetry = StartSendTelemetry(message, nameof(this.Send));
try
{
- OutputChannel.Send(message, timeout);
- StopSendTelemetry(telemetry, null, null, nameof(Send));
- } catch ( Exception ex )
+ this.OutputChannel.Send(message, timeout);
+ this.StopSendTelemetry(telemetry, null, null, nameof(this.Send));
+ }
+ catch (Exception ex)
{
- StopSendTelemetry(telemetry, null, ex, nameof(Send));
+ this.StopSendTelemetry(telemetry, null, ex, nameof(this.Send));
throw;
}
}
public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
{
- return BeginSend(message, ChannelManager.SendTimeout, callback, state);
+ return this.BeginSend(message, this.ChannelManager.SendTimeout, callback, state);
}
public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
- if ( message == null )
+ if (message == null)
{
throw new ArgumentNullException(nameof(message));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(BeginSend));
- var telemetry = StartSendTelemetry(message, nameof(BeginSend));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.BeginSend));
+ var telemetry = StartSendTelemetry(message, nameof(this.BeginSend));
try
{
- return new SendAsyncResult(OutputChannel, message, timeout, this.OnSendComplete, callback, state, telemetry);
- } catch ( Exception ex )
+ return new SendAsyncResult(this.OutputChannel, message, timeout, this.OnSendComplete, callback, state, telemetry);
+ }
+ catch (Exception ex)
{
- StopSendTelemetry(telemetry, null, ex, nameof(BeginSend));
+ this.StopSendTelemetry(telemetry, null, ex, nameof(this.BeginSend));
throw;
}
}
public void EndSend(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(EndSend));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.EndSend));
SendAsyncResult.End(result);
}
private void OnSendComplete(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
+
var sar = (SendAsyncResult)result;
- StopSendTelemetry(sar.Telemetry, null, sar.LastException, nameof(OnSendComplete));
+ this.StopSendTelemetry(sar.Telemetry, null, sar.LastException, nameof(this.OnSendComplete));
}
}
}
diff --git a/WCF/Shared/Implementation/ClientTelemetryRequestChannel.cs b/WCF/Shared/Implementation/ClientTelemetryRequestChannel.cs
index 8c0653f..6f3af29 100644
--- a/WCF/Shared/Implementation/ClientTelemetryRequestChannel.cs
+++ b/WCF/Shared/Implementation/ClientTelemetryRequestChannel.cs
@@ -1,98 +1,103 @@
-using System;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
- sealed class ClientTelemetryRequestChannel : ClientTelemetryChannelBase, IRequestChannel, IRequestSessionChannel
+ using System;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+
+ internal sealed class ClientTelemetryRequestChannel : ClientTelemetryChannelBase, IRequestChannel, IRequestSessionChannel
{
- private IRequestChannel RequestChannel
+ public ClientTelemetryRequestChannel(IChannelManager channelManager, IChannel channel)
+ : base(channelManager, channel)
{
- get { return (IRequestChannel)InnerChannel; }
}
public override EndpointAddress RemoteAddress
{
- get { return RequestChannel.RemoteAddress; }
+ get { return this.RequestChannel.RemoteAddress; }
}
+
public Uri Via
{
- get { return RequestChannel.Via; }
+ get { return this.RequestChannel.Via; }
}
public IOutputSession Session
{
- get { return ((IRequestSessionChannel)InnerChannel).Session; }
+ get { return ((IRequestSessionChannel)this.InnerChannel).Session; }
}
- public ClientTelemetryRequestChannel(IChannelManager channelManager, IChannel channel)
- : base(channelManager, channel)
+ private IRequestChannel RequestChannel
{
+ get { return (IRequestChannel)this.InnerChannel; }
}
public Message Request(Message message)
{
- return Request(message, ChannelManager.SendTimeout);
+ return this.Request(message, this.ChannelManager.SendTimeout);
}
public Message Request(Message message, TimeSpan timeout)
{
- if ( message == null )
+ if (message == null)
{
throw new ArgumentNullException(nameof(message));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(Request));
- var telemetry = StartSendTelemetry(message, nameof(Request));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.Request));
+ var telemetry = this.StartSendTelemetry(message, nameof(this.Request));
try
{
- var response = RequestChannel.Request(message, timeout);
- StopSendTelemetry(telemetry, response, null, nameof(Request));
+ var response = this.RequestChannel.Request(message, timeout);
+ this.StopSendTelemetry(telemetry, response, null, nameof(this.Request));
return response;
- } catch ( Exception ex )
+ }
+ catch (Exception ex)
{
- StopSendTelemetry(telemetry, null, ex, nameof(Request));
+ this.StopSendTelemetry(telemetry, null, ex, nameof(this.Request));
throw;
}
}
public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
{
- return BeginRequest(message, ChannelManager.SendTimeout, callback, state);
+ return this.BeginRequest(message, ChannelManager.SendTimeout, callback, state);
}
public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
- if ( message == null )
+ if (message == null)
{
throw new ArgumentNullException(nameof(message));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(BeginRequest));
- var telemetry = StartSendTelemetry(message, nameof(BeginRequest));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.BeginRequest));
+ var telemetry = this.StartSendTelemetry(message, nameof(this.BeginRequest));
try
{
- return new RequestAsyncResult(RequestChannel, message, timeout, this.OnRequestDone, callback, state, telemetry);
- } catch ( Exception ex )
+ return new RequestAsyncResult(this.RequestChannel, message, timeout, this.OnRequestDone, callback, state, telemetry);
+ }
+ catch (Exception ex)
{
- StopSendTelemetry(telemetry, null, ex, nameof(BeginRequest));
+ this.StopSendTelemetry(telemetry, null, ex, nameof(this.BeginRequest));
throw;
}
}
public Message EndRequest(IAsyncResult result)
{
- if ( result == null )
+ if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
- WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(EndRequest));
+
+ WcfClientEventSource.Log.ChannelCalled(GetType().FullName, nameof(this.EndRequest));
return RequestAsyncResult.End(result).Reply;
}
private void OnRequestDone(IAsyncResult result)
{
- RequestAsyncResult rar = (RequestAsyncResult)result;
- StopSendTelemetry(rar.Telemetry, rar.Reply, rar.LastException, nameof(OnRequestDone));
+ var rar = (RequestAsyncResult)result;
+ this.StopSendTelemetry(rar.Telemetry, rar.Reply, rar.LastException, nameof(this.OnRequestDone));
}
-
}
}
diff --git a/WCF/Shared/Implementation/ContractFilter.cs b/WCF/Shared/Implementation/ContractFilter.cs
index 998ca2e..84dd357 100644
--- a/WCF/Shared/Implementation/ContractFilter.cs
+++ b/WCF/Shared/Implementation/ContractFilter.cs
@@ -1,41 +1,42 @@
-using System;
-using System.Collections.Generic;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
- class ContractFilter
+ using System;
+ using System.Collections.Generic;
+ using System.ServiceModel.Description;
+
+ internal class ContractFilter
{
- private Dictionary filters;
+ private Dictionary filters;
public ContractFilter(IEnumerable contracts)
{
- filters = new Dictionary();
- foreach ( var contract in contracts )
+ this.filters = new Dictionary();
+ foreach (var contract in contracts)
{
- String key = GetKeyForContract(contract.Name, contract.Namespace);
- if ( !filters.ContainsKey(key) )
+ var key = this.GetKeyForContract(contract.Name, contract.Namespace);
+ if (!this.filters.ContainsKey(key))
{
- filters[key] = new OperationFilter(contract);
+ this.filters[key] = new OperationFilter(contract);
}
}
}
- public bool ShouldProcess(String contractName, String contractNamespace, String operationName)
+ public bool ShouldProcess(string contractName, string contractNamespace, string operationName)
{
- String key = GetKeyForContract(contractName, contractNamespace);
+ var key = this.GetKeyForContract(contractName, contractNamespace);
OperationFilter filter = null;
- if ( filters.TryGetValue(key, out filter) )
+ if (this.filters.TryGetValue(key, out filter))
{
return filter.ShouldProcess(operationName);
}
+
// if unknown contract, err on the safe side
return true;
}
// TODO: Avoid string concatenation to avoid extra allocation
- private String GetKeyForContract(String contractName, String contractNamespace)
+ private string GetKeyForContract(string contractName, string contractNamespace)
{
return contractNamespace + '#' + contractName;
}
diff --git a/WCF/Shared/Implementation/DependencyConstants.cs b/WCF/Shared/Implementation/DependencyConstants.cs
index 5036a07..f5f8014 100644
--- a/WCF/Shared/Implementation/DependencyConstants.cs
+++ b/WCF/Shared/Implementation/DependencyConstants.cs
@@ -1,13 +1,13 @@
-using System;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+
internal static class DependencyConstants
{
- public const String WcfClientCall = "WCF Service Call";
- public const String WcfChannelOpen = "WCF Channel Open";
+ public const string WcfClientCall = "WCF Service Call";
+ public const string WcfChannelOpen = "WCF Channel Open";
- public const String IsOneWayProperty = "isOneWay";
- public const String SoapActionProperty = "soapAction";
+ public const string IsOneWayProperty = "isOneWay";
+ public const string SoapActionProperty = "soapAction";
}
}
diff --git a/WCF/Shared/Implementation/Executor.cs b/WCF/Shared/Implementation/Executor.cs
index 2b3f1f2..9613e92 100644
--- a/WCF/Shared/Implementation/Executor.cs
+++ b/WCF/Shared/Implementation/Executor.cs
@@ -1,43 +1,48 @@
-using System;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+
internal static class Executor
{
public delegate void LogAction(TCtxt ctxt, ref TParam param);
- public static void ExceptionSafe(String moduleName, String activityName, Action action, TCtxt context)
+ public static void ExceptionSafe(string moduleName, string activityName, Action action, TCtxt context)
{
WcfEventSource.Log.TelemetryModuleExecutionStarted(moduleName, activityName);
try
{
action(context);
WcfEventSource.Log.TelemetryModuleExecutionStopped(moduleName, activityName);
- } catch ( Exception ex )
+ }
+ catch (Exception ex)
{
WcfEventSource.Log.TelemetryModuleExecutionFailed(moduleName, activityName, ex.ToString());
}
}
- public static void ExceptionSafe(String moduleName, String activityName, LogAction action, TCtxt context, ref TParam param)
+
+ public static void ExceptionSafe(string moduleName, string activityName, LogAction action, TCtxt context, ref TParam param)
{
WcfEventSource.Log.TelemetryModuleExecutionStarted(moduleName, activityName);
try
{
action(context, ref param);
WcfEventSource.Log.TelemetryModuleExecutionStopped(moduleName, activityName);
- } catch ( Exception ex )
+ }
+ catch (Exception ex)
{
WcfEventSource.Log.TelemetryModuleExecutionFailed(moduleName, activityName, ex.ToString());
}
}
- public static void ExceptionSafe(String moduleName, String activityName, Action action, TCtxt context, TValue value)
+
+ public static void ExceptionSafe(string moduleName, string activityName, Action action, TCtxt context, TValue value)
{
WcfEventSource.Log.TelemetryModuleExecutionStarted(moduleName, activityName);
try
{
action(context, value);
WcfEventSource.Log.TelemetryModuleExecutionStopped(moduleName, activityName);
- } catch ( Exception ex )
+ }
+ catch (Exception ex)
{
WcfEventSource.Log.TelemetryModuleExecutionFailed(moduleName, activityName, ex.ToString());
}
diff --git a/WCF/Shared/Implementation/IChannelManager.cs b/WCF/Shared/Implementation/IChannelManager.cs
index 68562b9..0fef700 100644
--- a/WCF/Shared/Implementation/IChannelManager.cs
+++ b/WCF/Shared/Implementation/IChannelManager.cs
@@ -1,17 +1,22 @@
-using System;
-using System.ServiceModel;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel;
+
internal interface IChannelManager : IDefaultCommunicationTimeouts
{
TelemetryClient TelemetryClient { get; }
+
ClientContract OperationMap { get; }
- String RootOperationIdHeaderName { get; }
- String ParentOperationIdHeaderName { get; }
- String SoapRootOperationIdHeaderName { get; }
- String SoapParentOperationIdHeaderName { get; }
- String SoapHeaderNamespace { get; }
+ string RootOperationIdHeaderName { get; }
+
+ string ParentOperationIdHeaderName { get; }
+
+ string SoapRootOperationIdHeaderName { get; }
+
+ string SoapParentOperationIdHeaderName { get; }
+
+ string SoapHeaderNamespace { get; }
}
}
diff --git a/WCF/Shared/Implementation/MessageCorrelator.cs b/WCF/Shared/Implementation/MessageCorrelator.cs
index 4afe304..cfe09a9 100644
--- a/WCF/Shared/Implementation/MessageCorrelator.cs
+++ b/WCF/Shared/Implementation/MessageCorrelator.cs
@@ -1,14 +1,14 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Xml;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.Collections.Generic;
+ using System.Threading;
+ using System.Xml;
+ using Microsoft.ApplicationInsights.DataContracts;
+
internal sealed class MessageCorrelator : IDisposable
{
- private Dictionary pendingMessages;
+ private Dictionary pendingMessages;
private Action timeoutCallback;
private object lockObject;
private bool disposed;
@@ -16,29 +16,32 @@ internal sealed class MessageCorrelator : IDisposable
public MessageCorrelator(Action callback = null)
{
this.timeoutCallback = callback;
- this.pendingMessages = new Dictionary();
+ this.pendingMessages = new Dictionary();
this.lockObject = new object();
this.disposed = false;
}
public void Add(UniqueId messageId, DependencyTelemetry telemetry, TimeSpan timeout)
{
- if ( messageId == null )
+ if (messageId == null)
{
throw new ArgumentNullException(nameof(messageId));
}
- if ( telemetry == null )
+
+ if (telemetry == null)
{
throw new ArgumentNullException(nameof(telemetry));
}
- lock ( lockObject )
+
+ lock (this.lockObject)
{
- if ( disposed )
+ if (this.disposed)
{
throw new ObjectDisposedException(nameof(MessageCorrelator));
}
+
var pending = new PendingMessage(messageId, telemetry);
- pendingMessages[messageId.ToString()] = pending;
+ this.pendingMessages[messageId.ToString()] = pending;
pending.Start(timeout, this.OnTimeout);
}
}
@@ -46,83 +49,91 @@ public void Add(UniqueId messageId, DependencyTelemetry telemetry, TimeSpan time
public bool TryLookup(UniqueId messageId, out DependencyTelemetry telemetry)
{
telemetry = null;
- lock ( this.lockObject )
+ lock (this.lockObject)
{
PendingMessage pending = null;
- if ( pendingMessages.TryGetValue(messageId.ToString(), out pending) )
+ if (this.pendingMessages.TryGetValue(messageId.ToString(), out pending))
{
- pendingMessages.Remove(messageId.ToString());
+ this.pendingMessages.Remove(messageId.ToString());
telemetry = pending.Telemetry;
pending.Dispose();
return true;
}
}
+
return false;
}
public void Remove(UniqueId messageId)
{
DependencyTelemetry telemetry;
- TryLookup(messageId, out telemetry);
+ this.TryLookup(messageId, out telemetry);
}
public void Dispose()
{
- lock ( this.lockObject )
+ lock (this.lockObject)
{
- foreach ( var obj in pendingMessages.Values )
+ foreach (var obj in this.pendingMessages.Values)
{
obj.Dispose();
}
- pendingMessages.Clear();
- disposed = true;
+
+ this.pendingMessages.Clear();
+ this.disposed = true;
}
}
private void OnTimeout(object state)
{
var pending = (PendingMessage)state;
- Remove(pending.Id);
+ this.Remove(pending.Id);
this.timeoutCallback?.Invoke(pending.Id, pending.Telemetry);
}
private class PendingMessage : IDisposable
{
- public UniqueId Id { get; private set; }
- public DependencyTelemetry Telemetry { get; private set; }
- public Timer TimeoutTimer { get; private set; }
-
public PendingMessage(UniqueId id, DependencyTelemetry telemetry)
{
- if ( id == null )
+ if (id == null)
{
throw new ArgumentNullException(nameof(id));
}
- if ( telemetry == null )
+
+ if (telemetry == null)
{
throw new ArgumentNullException(nameof(telemetry));
}
+
this.Id = id;
this.Telemetry = telemetry;
}
+ public UniqueId Id { get; private set; }
+
+ public DependencyTelemetry Telemetry { get; private set; }
+
+ public Timer TimeoutTimer { get; private set; }
+
public void Start(TimeSpan timeout, TimerCallback callback)
{
- if ( TimeoutTimer != null )
+ if (this.TimeoutTimer != null)
{
throw new InvalidOperationException("Start cannot be called twice");
}
- if ( timeout > TimeSpan.Zero )
+
+ if (timeout > TimeSpan.Zero)
{
this.TimeoutTimer = new Timer(callback, this, timeout, TimeSpan.FromMilliseconds(-1));
}
}
+
public void Dispose()
{
- if ( TimeoutTimer != null )
+ if (this.TimeoutTimer != null)
{
- TimeoutTimer.Dispose();
- TimeoutTimer = null;
+ this.TimeoutTimer.Dispose();
+ this.TimeoutTimer = null;
}
}
}
diff --git a/WCF/Shared/Implementation/OpenAsyncResult.cs b/WCF/Shared/Implementation/OpenAsyncResult.cs
new file mode 100644
index 0000000..6615416
--- /dev/null
+++ b/WCF/Shared/Implementation/OpenAsyncResult.cs
@@ -0,0 +1,43 @@
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
+{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ internal sealed class OpenAsyncResult : ChannelAsyncResult
+ {
+ public OpenAsyncResult(IChannel innerChannel, TimeSpan timeout, AsyncCallback onOpenDone, AsyncCallback callback, object state, DependencyTelemetry telemetry)
+ : base(onOpenDone, callback, state, telemetry)
+ {
+ this.InnerChannel = innerChannel;
+
+ this.OriginalResult = innerChannel.BeginOpen(timeout, OnComplete, this);
+ if (this.OriginalResult.CompletedSynchronously)
+ {
+ innerChannel.EndOpen(this.OriginalResult);
+ this.Complete(true);
+ }
+ }
+
+ public IChannel InnerChannel { get; private set; }
+
+ private static void OnComplete(IAsyncResult result)
+ {
+ if (result.CompletedSynchronously)
+ {
+ return;
+ }
+
+ var oar = (OpenAsyncResult)result.AsyncState;
+ try
+ {
+ oar.InnerChannel.EndOpen(oar.OriginalResult);
+ oar.Complete(false);
+ }
+ catch (Exception ex)
+ {
+ oar.Complete(false, ex);
+ }
+ }
+ }
+}
diff --git a/WCF/Shared/Implementation/OperationFilter.cs b/WCF/Shared/Implementation/OperationFilter.cs
index 5732af9..5f8e62c 100644
--- a/WCF/Shared/Implementation/OperationFilter.cs
+++ b/WCF/Shared/Implementation/OperationFilter.cs
@@ -1,39 +1,46 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
- class OperationFilter
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.ServiceModel.Description;
+
+ internal class OperationFilter
{
- private HashSet instrumentedOperations;
+ private HashSet instrumentedOperations;
public OperationFilter(ContractDescription serviceContract)
{
- instrumentedOperations = InspectContract(serviceContract);
+ this.instrumentedOperations = this.InspectContract(serviceContract);
}
- public bool ShouldProcess(String operationName)
+ public bool ShouldProcess(string operationName)
{
// if no operations had [OperationTelemetry], all are instrumented
- if ( instrumentedOperations == null || instrumentedOperations.Count == 0 )
+ if (this.instrumentedOperations == null || this.instrumentedOperations.Count == 0)
+ {
return true;
- return instrumentedOperations.Contains(operationName);
+ }
+
+ return this.instrumentedOperations.Contains(operationName);
}
- private HashSet InspectContract(ContractDescription serviceContract)
+ private HashSet InspectContract(ContractDescription serviceContract)
{
- HashSet result = null;
- foreach ( var op in serviceContract.Operations )
+ HashSet result = null;
+ foreach (var op in serviceContract.Operations)
{
- if ( ShouldInstrument(op) )
+ if (this.ShouldInstrument(op))
{
- if ( result == null )
- result = new HashSet();
+ if (result == null)
+ {
+ result = new HashSet();
+ }
+
result.Add(op.Name);
}
}
+
return result;
}
diff --git a/WCF/Shared/Implementation/PlatformContext.cs b/WCF/Shared/Implementation/PlatformContext.cs
index 67aaa27..edc8282 100644
--- a/WCF/Shared/Implementation/PlatformContext.cs
+++ b/WCF/Shared/Implementation/PlatformContext.cs
@@ -1,28 +1,42 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using System;
-using System.Runtime.CompilerServices;
-using System.ServiceModel;
-using System.Web;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.Runtime.CompilerServices;
+ using System.ServiceModel;
+ using System.Web;
+ using Microsoft.ApplicationInsights.DataContracts;
+
///
/// Helper class used to speed up checks for RequestTelemetry
- /// created by the Web SDK, which is stored in HttpContext
+ /// created by the Web SDK, which is stored in HttpContext.
///
internal static class PlatformContext
{
- static readonly bool aspNetCompat = ServiceHostingEnvironment.AspNetCompatibilityEnabled;
+ private static readonly bool AspNetCompat = ServiceHostingEnvironment.AspNetCompatibilityEnabled;
internal static RequestTelemetry RequestFromHttpContext()
{
// only check HttpContext if WCF hosting is configured with
//
// See: https://msdn.microsoft.com/en-us/library/aa702682(v=vs.110).aspx
- if ( aspNetCompat )
+ if (AspNetCompat)
{
return GetRequestTelemetryFromHttpContext();
}
+
+ return null;
+ }
+
+ internal static HttpContext GetContext()
+ {
+ // only check HttpContext if WCF hosting is configured with
+ //
+ // See: https://msdn.microsoft.com/en-us/library/aa702682(v=vs.110).aspx
+ if (AspNetCompat)
+ {
+ return HttpContext.Current;
+ }
+
return null;
}
@@ -32,26 +46,12 @@ internal static RequestTelemetry RequestFromHttpContext()
private static RequestTelemetry GetRequestTelemetryFromHttpContext()
{
var context = HttpContext.Current;
- if ( context != null )
+ if (context != null)
{
return context.Items[RequestTrackingConstants.HttpContextRequestTelemetryName]
as RequestTelemetry;
}
- return null;
- }
- ///
- /// Returns the HttpContext for the current thread
- ///
- /// Null if not running on IIS or not available
- internal static HttpContext GetContext()
- {
- // only check HttpContext if WCF hosting is configured with
- //
- // See: https://msdn.microsoft.com/en-us/library/aa702682(v=vs.110).aspx
- if ( aspNetCompat )
- {
- return HttpContext.Current;
- }
+
return null;
}
}
diff --git a/WCF/Shared/Implementation/ProfilerWcfClientProcessing.cs b/WCF/Shared/Implementation/ProfilerWcfClientProcessing.cs
index 2e94756..e363584 100644
--- a/WCF/Shared/Implementation/ProfilerWcfClientProcessing.cs
+++ b/WCF/Shared/Implementation/ProfilerWcfClientProcessing.cs
@@ -1,34 +1,38 @@
-using System;
-using System.Linq;
-using System.ServiceModel;
-using System.ServiceModel.Description;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.ServiceModel.Description;
+
internal sealed class ProfilerWcfClientProcessing
{
private WcfDependencyTrackingTelemetryModule trackingModule;
public ProfilerWcfClientProcessing(WcfDependencyTrackingTelemetryModule module)
{
- if ( module == null )
+ if (module == null)
{
throw new ArgumentNullException(nameof(module));
}
+
this.trackingModule = module;
}
+
public object OnStartInitializeEndpoint1(object thisObj, object serviceEndpoint)
{
return null;
}
+
public object OnEndInitializeEndpoint1(object context, object returnValue, object thisObj, object serviceEndpoint)
{
- if ( thisObj == null )
+ if (thisObj == null)
{
- WcfClientEventSource.Log.NotExpectedCallback(0, nameof(OnEndInitializeEndpoint1), "thisObj == null");
+ WcfClientEventSource.Log.NotExpectedCallback(0, nameof(this.OnEndInitializeEndpoint1), "thisObj == null");
return returnValue;
}
- AddBehaviorIfNotPresent(((ChannelFactory)thisObj).Endpoint);
+
+ this.AddBehaviorIfNotPresent(((ChannelFactory)thisObj).Endpoint);
return returnValue;
}
@@ -37,14 +41,16 @@ public object OnStartInitializeEndpoint2(object thisObj, object configuratioName
Console.WriteLine("onStartInitializeEndpoint2");
return null;
}
+
public object OnEndInitializeEndpoint2(object context, object returnValue, object thisObj, object configuratioNameOrBinding, object address)
{
- if ( thisObj == null )
+ if (thisObj == null)
{
- WcfClientEventSource.Log.NotExpectedCallback(0, nameof(OnEndInitializeEndpoint2), "thisObj == null");
+ WcfClientEventSource.Log.NotExpectedCallback(0, nameof(this.OnEndInitializeEndpoint2), "thisObj == null");
return returnValue;
}
- AddBehaviorIfNotPresent(((ChannelFactory)thisObj).Endpoint);
+
+ this.AddBehaviorIfNotPresent(((ChannelFactory)thisObj).Endpoint);
return returnValue;
}
@@ -52,25 +58,28 @@ public object OnStartInitializeEndpoint3(object thisObj, object configurationNam
{
return null;
}
+
public object OnEndInitializeEndpoint3(object context, object returnValue, object thisObj, object configurationName, object address, object configuration)
{
- if ( thisObj == null )
+ if (thisObj == null)
{
- WcfClientEventSource.Log.NotExpectedCallback(0, nameof(OnEndInitializeEndpoint3), "thisObj == null");
+ WcfClientEventSource.Log.NotExpectedCallback(0, nameof(this.OnEndInitializeEndpoint3), "thisObj == null");
return returnValue;
}
- AddBehaviorIfNotPresent(((ChannelFactory)thisObj).Endpoint);
+
+ this.AddBehaviorIfNotPresent(((ChannelFactory)thisObj).Endpoint);
return returnValue;
}
private void AddBehaviorIfNotPresent(ServiceEndpoint endpoint)
{
- if ( endpoint.Behaviors.OfType().Any() )
+ if (endpoint.Behaviors.OfType().Any())
{
// don't add behavior if it's already been added by user code
// or the configuration
return;
}
+
var behavior = new ClientTelemetryEndpointBehavior(this.trackingModule.TelemetryClient)
{
RootOperationIdHeaderName = this.trackingModule.RootOperationIdHeaderName,
diff --git a/WCF/Shared/Implementation/ReceiveAsyncResult.cs b/WCF/Shared/Implementation/ReceiveAsyncResult.cs
new file mode 100644
index 0000000..0629c31
--- /dev/null
+++ b/WCF/Shared/Implementation/ReceiveAsyncResult.cs
@@ -0,0 +1,44 @@
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
+{
+ using System;
+ using System.ServiceModel.Channels;
+
+ internal sealed class ReceiveAsyncResult : ChannelAsyncResult
+ {
+ public ReceiveAsyncResult(IInputChannel innerChannel, TimeSpan timeout, AsyncCallback onReceiveDone, AsyncCallback callback, object state)
+ : base(onReceiveDone, callback, state, null)
+ {
+ this.InnerChannel = innerChannel;
+
+ this.OriginalResult = innerChannel.BeginReceive(timeout, OnComplete, this);
+ if (this.OriginalResult.CompletedSynchronously)
+ {
+ this.Message = innerChannel.EndReceive(this.OriginalResult);
+ this.Complete(true);
+ }
+ }
+
+ public IInputChannel InnerChannel { get; private set; }
+
+ public Message Message { get; private set; }
+
+ private static void OnComplete(IAsyncResult result)
+ {
+ if (result.CompletedSynchronously)
+ {
+ return;
+ }
+
+ var rar = (ReceiveAsyncResult)result.AsyncState;
+ try
+ {
+ rar.Message = rar.InnerChannel.EndReceive(rar.OriginalResult);
+ rar.Complete(false);
+ }
+ catch (Exception ex)
+ {
+ rar.Complete(false, ex);
+ }
+ }
+ }
+}
diff --git a/WCF/Shared/Implementation/RequestAsyncResult.cs b/WCF/Shared/Implementation/RequestAsyncResult.cs
new file mode 100644
index 0000000..10607d0
--- /dev/null
+++ b/WCF/Shared/Implementation/RequestAsyncResult.cs
@@ -0,0 +1,45 @@
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
+{
+ using System;
+ using System.ServiceModel.Channels;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ internal sealed class RequestAsyncResult : ChannelAsyncResult
+ {
+ public RequestAsyncResult(IRequestChannel innerChannel, Message message, TimeSpan timeout, AsyncCallback onRequestDone, AsyncCallback callback, object state, DependencyTelemetry telemetry)
+ : base(onRequestDone, callback, state, telemetry)
+ {
+ this.InnerChannel = innerChannel;
+
+ this.OriginalResult = innerChannel.BeginRequest(message, timeout, OnComplete, this);
+ if (this.OriginalResult.CompletedSynchronously)
+ {
+ this.Reply = innerChannel.EndRequest(this.OriginalResult);
+ this.Complete(true);
+ }
+ }
+
+ public IRequestChannel InnerChannel { get; private set; }
+
+ public Message Reply { get; private set; }
+
+ private static void OnComplete(IAsyncResult result)
+ {
+ if (result.CompletedSynchronously)
+ {
+ return;
+ }
+
+ var rar = (RequestAsyncResult)result.AsyncState;
+ try
+ {
+ rar.Reply = rar.InnerChannel.EndRequest(rar.OriginalResult);
+ rar.Complete(false);
+ }
+ catch (Exception ex)
+ {
+ rar.Complete(false, ex);
+ }
+ }
+ }
+}
diff --git a/WCF/Shared/Implementation/RequestTrackingConstants.cs b/WCF/Shared/Implementation/RequestTrackingConstants.cs
index f37346f..2a5c512 100644
--- a/WCF/Shared/Implementation/RequestTrackingConstants.cs
+++ b/WCF/Shared/Implementation/RequestTrackingConstants.cs
@@ -1,7 +1,7 @@
-using System;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+
internal static class RequestTrackingConstants
{
internal const string HttpContextRequestTelemetryName = "Microsoft.ApplicationInsights.RequestTelemetry";
diff --git a/WCF/Shared/Implementation/SdkVersionUtils.cs b/WCF/Shared/Implementation/SdkVersionUtils.cs
index 31f3462..15d1bbd 100644
--- a/WCF/Shared/Implementation/SdkVersionUtils.cs
+++ b/WCF/Shared/Implementation/SdkVersionUtils.cs
@@ -1,12 +1,12 @@
-using System;
-using System.Linq;
-using System.Reflection;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.Linq;
+ using System.Reflection;
+
internal static class SdkVersionUtils
{
- public static String GetAssemblyVersion()
+ public static string GetAssemblyVersion()
{
return typeof(SdkVersionUtils).Assembly.GetCustomAttributes(false)
.OfType()
diff --git a/WCF/Shared/Implementation/SendAsyncResult.cs b/WCF/Shared/Implementation/SendAsyncResult.cs
new file mode 100644
index 0000000..caa917b
--- /dev/null
+++ b/WCF/Shared/Implementation/SendAsyncResult.cs
@@ -0,0 +1,47 @@
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
+{
+ using System;
+ using System.ServiceModel.Channels;
+ using System.Xml;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ internal sealed class SendAsyncResult : ChannelAsyncResult
+ {
+ public SendAsyncResult(IOutputChannel innerChannel, Message message, TimeSpan timeout, AsyncCallback onSendDone, AsyncCallback callback, object state, DependencyTelemetry telemetry)
+ : base(onSendDone, callback, state, telemetry)
+ {
+ this.InnerChannel = innerChannel;
+ this.RequestId = message.Headers.MessageId;
+
+ this.OriginalResult = innerChannel.BeginSend(message, timeout, OnComplete, this);
+ if (this.OriginalResult.CompletedSynchronously)
+ {
+ innerChannel.EndSend(this.OriginalResult);
+ this.Complete(true);
+ }
+ }
+
+ public IOutputChannel InnerChannel { get; private set; }
+
+ public UniqueId RequestId { get; private set; }
+
+ private static void OnComplete(IAsyncResult result)
+ {
+ if (result.CompletedSynchronously)
+ {
+ return;
+ }
+
+ var sar = (SendAsyncResult)result.AsyncState;
+ try
+ {
+ sar.InnerChannel.EndSend(sar.OriginalResult);
+ sar.Complete(false);
+ }
+ catch (Exception ex)
+ {
+ sar.Complete(false, ex);
+ }
+ }
+ }
+}
diff --git a/WCF/Shared/Implementation/TryReceiveAsyncResult.cs b/WCF/Shared/Implementation/TryReceiveAsyncResult.cs
new file mode 100644
index 0000000..786965e
--- /dev/null
+++ b/WCF/Shared/Implementation/TryReceiveAsyncResult.cs
@@ -0,0 +1,50 @@
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
+{
+ using System;
+ using System.ServiceModel.Channels;
+
+ internal sealed class TryReceiveAsyncResult : ChannelAsyncResult
+ {
+ public TryReceiveAsyncResult(IInputChannel innerChannel, TimeSpan timeout, AsyncCallback onReceiveDone, AsyncCallback callback, object state)
+ : base(onReceiveDone, callback, state, null)
+ {
+ this.InnerChannel = innerChannel;
+
+ this.OriginalResult = innerChannel.BeginTryReceive(timeout, OnComplete, this);
+ if (this.OriginalResult.CompletedSynchronously)
+ {
+ Message message = null;
+ this.Result = innerChannel.EndTryReceive(this.OriginalResult, out message);
+ this.Message = message;
+ this.Complete(true);
+ }
+ }
+
+ public IInputChannel InnerChannel { get; private set; }
+
+ public Message Message { get; private set; }
+
+ public bool Result { get; private set; }
+
+ private static void OnComplete(IAsyncResult result)
+ {
+ if (result.CompletedSynchronously)
+ {
+ return;
+ }
+
+ var trar = (TryReceiveAsyncResult)result.AsyncState;
+ try
+ {
+ Message message = null;
+ trar.Result = trar.InnerChannel.EndTryReceive(trar.OriginalResult, out message);
+ trar.Message = message;
+ trar.Complete(false);
+ }
+ catch (Exception ex)
+ {
+ trar.Complete(false, ex);
+ }
+ }
+ }
+}
diff --git a/WCF/Shared/Implementation/WcfClientEventSource.cs b/WCF/Shared/Implementation/WcfClientEventSource.cs
index 754366b..8214459 100644
--- a/WCF/Shared/Implementation/WcfClientEventSource.cs
+++ b/WCF/Shared/Implementation/WcfClientEventSource.cs
@@ -1,55 +1,50 @@
-#if NET40
-using Microsoft.Diagnostics.Tracing;
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
+{
+ using System;
+#if NET40
+ using Microsoft.Diagnostics.Tracing;
#else
-using System.Diagnostics.Tracing;
+ using System.Diagnostics.Tracing;
#endif
-using System;
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
-{
[EventSource(Name = "Microsoft-ApplicationInsights-Wcf-Client")]
internal sealed class WcfClientEventSource : EventSource
{
- public sealed class Keywords
- {
- public const EventKeywords DependencyTracking = (EventKeywords)0x10;
- }
-
public static readonly WcfClientEventSource Log = new WcfClientEventSource();
- public String ApplicationName { [NonEvent] get; [NonEvent] private set; }
-
public WcfClientEventSource()
{
- this.ApplicationName = GetApplicationName();
+ this.ApplicationName = this.GetApplicationName();
}
+ public string ApplicationName { [NonEvent] get; [NonEvent] private set; }
+
[Event(1, Keywords = Keywords.DependencyTracking, Message = "Client Telemetry applied to contract: {0}", Level = EventLevel.Informational)]
- public void ClientTelemetryApplied(String contract, String appDomainName = "Invalid")
+ public void ClientTelemetryApplied(string contract, string appDomainName = "Invalid")
{
this.WriteEvent(1, contract, this.ApplicationName);
}
[Event(2, Keywords = Keywords.DependencyTracking, Message = "{0}", Level = EventLevel.Informational)]
- public void ClientDependencyTrackingInfo(String info, String appDomainName = "Invalid")
+ public void ClientDependencyTrackingInfo(string info, string appDomainName = "Invalid")
{
this.WriteEvent(2, info, this.ApplicationName);
}
[Event(3, Keywords = Keywords.DependencyTracking, Message = "ChannelFactory created for channel shape {0}", Level = EventLevel.Informational)]
- public void ChannelFactoryCreated(String channelShape, String appDomainName = "Invalid")
+ public void ChannelFactoryCreated(string channelShape, string appDomainName = "Invalid")
{
this.WriteEvent(3, channelShape, this.ApplicationName);
}
[Event(4, Keywords = Keywords.DependencyTracking, Message = "{0}.{1} callback called.", Level = EventLevel.Informational)]
- public void ChannelCalled(String channel, String method, String appDomainName = "Invalid")
+ public void ChannelCalled(string channel, string method, string appDomainName = "Invalid")
{
this.WriteEvent(4, channel, method, this.ApplicationName);
}
[Event(5, Keywords = Keywords.DependencyTracking, Message = "Exception while processing {0}: {1}", Level = EventLevel.Error)]
- public void ClientTelemetryError(String method, String exception, String appDomainName = "Invalid")
+ public void ClientTelemetryError(string method, string exception, string appDomainName = "Invalid")
{
this.WriteEvent(5, method, exception, this.ApplicationName);
}
@@ -61,15 +56,21 @@ public void NotExpectedCallback(long id, string callbackName, string reason, str
}
[NonEvent]
- private String GetApplicationName()
+ private string GetApplicationName()
{
try
{
return AppDomain.CurrentDomain.FriendlyName;
- } catch
+ }
+ catch
{
return "Undefined";
}
}
+
+ public sealed class Keywords
+ {
+ public const EventKeywords DependencyTracking = (EventKeywords)0x10;
+ }
}
}
diff --git a/WCF/Shared/Implementation/WcfEventSource.cs b/WCF/Shared/Implementation/WcfEventSource.cs
index 0041fbb..8f12394 100644
--- a/WCF/Shared/Implementation/WcfEventSource.cs
+++ b/WCF/Shared/Implementation/WcfEventSource.cs
@@ -1,120 +1,122 @@
-#if NET40
-using Microsoft.Diagnostics.Tracing;
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
+{
+ using System;
+#if NET40
+ using Microsoft.Diagnostics.Tracing;
#else
-using System.Diagnostics.Tracing;
+ using System.Diagnostics.Tracing;
#endif
-using System;
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
-{
[EventSource(Name = "Microsoft-ApplicationInsights-Wcf")]
internal sealed class WcfEventSource : EventSource
{
- // Keywords must be powers of 2 since they are used as bitmasks
- public sealed class Keywords
- {
- public const EventKeywords WcfModule = (EventKeywords)0x10;
- public const EventKeywords RequestTelemetry = (EventKeywords)0x20;
- public const EventKeywords ExceptionTelemetry = (EventKeywords)0x40;
- public const EventKeywords OperationContext = (EventKeywords)0x80;
- }
+ public const string InitializationFailureMessage = "ServiceTelemetry module failed to initialize with exception: {0}";
+ public const string TelemetryModuleExecutionStartedMessage = "WCF Telemetry Module {0} started stage {1}";
+ public const string TelemetryModuleExecutionStoppedMessage = "WCF Telemetry Module {0} stopped stage {1}";
+ public const string TelemetryModuleExecutionFailedMessage = "WCF Telemetry Module {0} failed stage {1} with exception: {2}";
+ public const string NoOperationContextFoundMessage = "No OperationContext found on thread";
+ public const string OperationIgnoredMessage = "Request ignored because operation is not marked with [OperationTelemetry]: {0}#{1} - {2}";
+ public const string WcfTelemetryInitializerLoadedMessage = "WCF TelemetryInitializer loaded: {0}";
+ public const string LocationIdSetMessage = "Location.Id set to: {0}";
+ public const string OperationContextCreatedMessage = "WcfOperationContext created. OpId={0}; OwnRequest={1}";
+ public const string RequestMessageClosedMessage = "Request message closed while attempting action '{0}' ({1})";
+ public const string ResponseMessageClosedMessage = "Response message closed while attempting action '{0}' ({1})";
public static readonly WcfEventSource Log = new WcfEventSource();
- public String ApplicationName { [NonEvent] get; [NonEvent] private set; }
-
public WcfEventSource()
{
- this.ApplicationName = GetApplicationName();
+ this.ApplicationName = this.GetApplicationName();
}
- public const String InitializationFailure_Message = "ServiceTelemetry module failed to initialize with exception: {0}";
- [Event(1, Keywords = Keywords.WcfModule, Message = InitializationFailure_Message, Level = EventLevel.Verbose)]
- public void InitializationFailure(String exception, String appDomainName = "Invalid")
+ public string ApplicationName { [NonEvent] get; [NonEvent] private set; }
+
+ [Event(1, Keywords = Keywords.WcfModule, Message = InitializationFailureMessage, Level = EventLevel.Verbose)]
+ public void InitializationFailure(string exception, string appDomainName = "Invalid")
{
- this.WriteEvent(1, exception, ApplicationName);
+ this.WriteEvent(1, exception, this.ApplicationName);
}
- public const String TelemetryModuleExecutionStarted_Message = "WCF Telemetry Module {0} started stage {1}";
- [Event(4, Keywords = Keywords.WcfModule, Message = TelemetryModuleExecutionStarted_Message, Level = EventLevel.Verbose)]
- public void TelemetryModuleExecutionStarted(String typeName, String stageName, String appDomainName = "Invalid")
+ [Event(4, Keywords = Keywords.WcfModule, Message = TelemetryModuleExecutionStartedMessage, Level = EventLevel.Verbose)]
+ public void TelemetryModuleExecutionStarted(string typeName, string stageName, string appDomainName = "Invalid")
{
- this.WriteEvent(4, typeName, stageName, ApplicationName);
+ this.WriteEvent(4, typeName, stageName, this.ApplicationName);
}
- public const String TelemetryModuleExecutionStopped_Message = "WCF Telemetry Module {0} stopped stage {1}";
- [Event(5, Keywords = Keywords.WcfModule, Message = TelemetryModuleExecutionStopped_Message, Level = EventLevel.Verbose)]
- public void TelemetryModuleExecutionStopped(String typeName, String stageName, String appDomainName = "Invalid")
+ [Event(5, Keywords = Keywords.WcfModule, Message = TelemetryModuleExecutionStoppedMessage, Level = EventLevel.Verbose)]
+ public void TelemetryModuleExecutionStopped(string typeName, string stageName, string appDomainName = "Invalid")
{
- this.WriteEvent(5, typeName, stageName, ApplicationName);
+ this.WriteEvent(5, typeName, stageName, this.ApplicationName);
}
- public const String TelemetryModuleExecutionFailed_Message = "WCF Telemetry Module {0} failed stage {1} with exception: {2}";
- [Event(6, Keywords = Keywords.WcfModule, Message = TelemetryModuleExecutionFailed_Message, Level = EventLevel.Error)]
- public void TelemetryModuleExecutionFailed(String typeName, String stageName, String exception, String appDomainName = "Invalid")
+ [Event(6, Keywords = Keywords.WcfModule, Message = TelemetryModuleExecutionFailedMessage, Level = EventLevel.Error)]
+ public void TelemetryModuleExecutionFailed(string typeName, string stageName, string exception, string appDomainName = "Invalid")
{
- this.WriteEvent(6, typeName, stageName, exception, ApplicationName);
+ this.WriteEvent(6, typeName, stageName, exception, this.ApplicationName);
}
- public const String NoOperationContextFound_Message = "No OperationContext found on thread";
- [Event(7, Keywords = Keywords.WcfModule, Message = NoOperationContextFound_Message, Level = EventLevel.Warning)]
- public void NoOperationContextFound(String appDomainName = "Invalid")
+ [Event(7, Keywords = Keywords.WcfModule, Message = NoOperationContextFoundMessage, Level = EventLevel.Warning)]
+ public void NoOperationContextFound(string appDomainName = "Invalid")
{
- this.WriteEvent(7, ApplicationName);
+ this.WriteEvent(7, this.ApplicationName);
}
- public const String OperationIgnored_Message = "Request ignored because operation is not marked with [OperationTelemetry]: {0}#{1} - {2}";
- [Event(8, Keywords = Keywords.WcfModule, Message = OperationIgnored_Message, Level = EventLevel.Verbose)]
- public void OperationIgnored(String contractName, String contractNamespace, String operationName, String appDomainName = "Invalid")
+ [Event(8, Keywords = Keywords.WcfModule, Message = OperationIgnoredMessage, Level = EventLevel.Verbose)]
+ public void OperationIgnored(string contractName, string contractNamespace, string operationName, string appDomainName = "Invalid")
{
- this.WriteEvent(8, contractName, contractNamespace, operationName, ApplicationName);
+ this.WriteEvent(8, contractName, contractNamespace, operationName, this.ApplicationName);
}
- public const String WcfTelemetryInitializerLoaded_Message = "WCF TelemetryInitializer loaded: {0}";
- [Event(9, Keywords = Keywords.RequestTelemetry, Message = WcfTelemetryInitializerLoaded_Message, Level = EventLevel.Verbose)]
- public void WcfTelemetryInitializerLoaded(String typeName, String appDomainName = "Invalid")
+ [Event(9, Keywords = Keywords.RequestTelemetry, Message = WcfTelemetryInitializerLoadedMessage, Level = EventLevel.Verbose)]
+ public void WcfTelemetryInitializerLoaded(string typeName, string appDomainName = "Invalid")
{
- this.WriteEvent(9, typeName, ApplicationName);
+ this.WriteEvent(9, typeName, this.ApplicationName);
}
- public const String LocationIdSet_Message = "Location.Id set to: {0}";
- [Event(15, Keywords = Keywords.WcfModule, Message = LocationIdSet_Message, Level = EventLevel.Verbose)]
- public void LocationIdSet(String ip, String appDomainName = "Invalid")
+ [Event(15, Keywords = Keywords.WcfModule, Message = LocationIdSetMessage, Level = EventLevel.Verbose)]
+ public void LocationIdSet(string ip, string appDomainName = "Invalid")
{
this.WriteEvent(15, ip ?? "NULL", this.ApplicationName);
}
- public const String OperationContextCreated_Message = "WcfOperationContext created. OpId={0}; OwnRequest={1}";
- [Event(30, Keywords = Keywords.OperationContext, Message = OperationContextCreated_Message, Level = EventLevel.Verbose)]
- public void OperationContextCreated(String operationId, bool ownsRequest, String appDomainName = "Invalid")
+ [Event(30, Keywords = Keywords.OperationContext, Message = OperationContextCreatedMessage, Level = EventLevel.Verbose)]
+ public void OperationContextCreated(string operationId, bool ownsRequest, string appDomainName = "Invalid")
{
this.WriteEvent(30, operationId ?? "NULL", ownsRequest, this.ApplicationName);
}
- public const String RequestMessageClosed_Message = "Request message closed while attempting action '{0}' ({1})";
- [Event(35, Keywords = Keywords.OperationContext, Message = RequestMessageClosed_Message, Level = EventLevel.Warning)]
- public void RequestMessageClosed(String action, String argument, String appDomainName = "Invalid")
+ [Event(35, Keywords = Keywords.OperationContext, Message = RequestMessageClosedMessage, Level = EventLevel.Warning)]
+ public void RequestMessageClosed(string action, string argument, string appDomainName = "Invalid")
{
this.WriteEvent(35, action, argument, this.ApplicationName);
}
- public const String ResponseMessageClosed_Message = "Response message closed while attempting action '{0}' ({1})";
- [Event(36, Keywords = Keywords.OperationContext, Message = ResponseMessageClosed_Message, Level = EventLevel.Warning)]
- public void ResponseMessageClosed(String action, String argument, String appDomainName = "Invalid")
+ [Event(36, Keywords = Keywords.OperationContext, Message = ResponseMessageClosedMessage, Level = EventLevel.Warning)]
+ public void ResponseMessageClosed(string action, string argument, string appDomainName = "Invalid")
{
this.WriteEvent(36, action, argument, this.ApplicationName);
}
[NonEvent]
- private String GetApplicationName()
+ private string GetApplicationName()
{
try
{
return AppDomain.CurrentDomain.FriendlyName;
- } catch
+ }
+ catch
{
return "Undefined";
}
}
+
+ // Keywords must be powers of 2 since they are used as bitmasks
+ public sealed class Keywords
+ {
+ public const EventKeywords WcfModule = (EventKeywords)0x10;
+ public const EventKeywords RequestTelemetry = (EventKeywords)0x20;
+ public const EventKeywords ExceptionTelemetry = (EventKeywords)0x40;
+ public const EventKeywords OperationContext = (EventKeywords)0x80;
+ }
}
}
diff --git a/WCF/Shared/Implementation/WcfExtensions.cs b/WCF/Shared/Implementation/WcfExtensions.cs
index 1c295a0..b0470f9 100644
--- a/WCF/Shared/Implementation/WcfExtensions.cs
+++ b/WCF/Shared/Implementation/WcfExtensions.cs
@@ -1,47 +1,53 @@
-using System;
-using System.ServiceModel.Channels;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.ServiceModel.Channels;
+
internal static class WcfExtensions
{
public static HttpRequestMessageProperty GetHttpRequestHeaders(this IOperationContext operation)
{
- if ( operation.HasIncomingMessageProperty(HttpRequestMessageProperty.Name) )
+ if (operation.HasIncomingMessageProperty(HttpRequestMessageProperty.Name))
{
return (HttpRequestMessageProperty)operation.GetIncomingMessageProperty(HttpRequestMessageProperty.Name);
}
+
return null;
}
+
public static HttpResponseMessageProperty GetHttpResponseHeaders(this IOperationContext operation)
{
- if ( operation.HasOutgoingMessageProperty(HttpResponseMessageProperty.Name) )
+ if (operation.HasOutgoingMessageProperty(HttpResponseMessageProperty.Name))
{
return (HttpResponseMessageProperty)operation.GetOutgoingMessageProperty(HttpResponseMessageProperty.Name);
}
+
return null;
}
public static HttpRequestMessageProperty GetHttpRequestHeaders(this Message message)
{
HttpRequestMessageProperty headers = null;
- if ( message.Properties.ContainsKey(HttpRequestMessageProperty.Name) )
+ if (message.Properties.ContainsKey(HttpRequestMessageProperty.Name))
{
headers = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
- } else
+ }
+ else
{
headers = new HttpRequestMessageProperty();
message.Properties.Add(HttpRequestMessageProperty.Name, headers);
}
+
return headers;
}
public static bool IsClosed(this Message message)
{
- if ( message == null )
+ if (message == null)
{
throw new ArgumentNullException(nameof(message));
}
+
return message.State == MessageState.Closed;
}
}
diff --git a/WCF/Shared/Implementation/WcfInterceptor.cs b/WCF/Shared/Implementation/WcfInterceptor.cs
index a9f18ff..2378f9a 100644
--- a/WCF/Shared/Implementation/WcfInterceptor.cs
+++ b/WCF/Shared/Implementation/WcfInterceptor.cs
@@ -1,14 +1,14 @@
-using TelemetryModules = Microsoft.ApplicationInsights.Extensibility.Implementation.TelemetryModules;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.ServiceModel;
-using System.ServiceModel.Channels;
-using System.ServiceModel.Dispatcher;
-using Microsoft.ApplicationInsights.Extensibility;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Dispatcher;
+ using Microsoft.ApplicationInsights.Extensibility;
+ using TelemetryModules = Microsoft.ApplicationInsights.Extensibility.Implementation.TelemetryModules;
+
internal class WcfInterceptor : IDispatchMessageInspector, IErrorHandler
{
private TelemetryConfiguration configuration;
@@ -18,11 +18,14 @@ public WcfInterceptor(TelemetryConfiguration configuration)
: this(configuration, null)
{
}
+
public WcfInterceptor(TelemetryConfiguration configuration, ContractFilter filter)
{
- if ( configuration == null )
+ if (configuration == null)
+ {
throw new ArgumentNullException("configuration");
-
+ }
+
this.configuration = configuration;
this.contractFilter = filter;
}
@@ -30,75 +33,81 @@ public WcfInterceptor(TelemetryConfiguration configuration, ContractFilter filte
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
IOperationContext context = WcfOperationContext.Current;
- if ( context != null )
+ if (context != null)
{
- if ( !LogTelemetryFor(context) )
+ if (!this.LogTelemetryFor(context))
{
WcfEventSource.Log.OperationIgnored(context.ContractName, context.ContractNamespace, context.OperationName);
return null;
}
- foreach ( var mod in GetModules() )
+
+ foreach (var mod in this.GetModules())
{
Executor.ExceptionSafe(
mod.GetType().Name,
"OnBeginRequest",
mod.OnBeginRequest,
- context
- );
+ context);
}
- foreach ( var mod in GetModules() )
+
+ foreach (var mod in this.GetModules())
{
var tracer = mod as IWcfMessageTrace;
- if ( tracer != null )
+ if (tracer != null)
{
Executor.ExceptionSafe(
mod.GetType().Name,
"OnTraceRequest",
tracer.OnTraceRequest,
- context, ref request
- );
+ context,
+ ref request);
}
}
- } else
+ }
+ else
{
WcfEventSource.Log.NoOperationContextFound();
}
+
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
var context = WcfOperationContext.Current;
- if ( context != null )
+ if (context != null)
{
// Do not run OnEndRequest for stuff we're not interested in!
- if ( !LogTelemetryFor(context) )
+ if (!this.LogTelemetryFor(context))
{
return;
}
- foreach ( var mod in GetModules() )
+
+ foreach (var mod in this.GetModules())
{
var tracer = mod as IWcfMessageTrace;
- if ( tracer != null )
+ if (tracer != null)
{
Executor.ExceptionSafe(
mod.GetType().Name,
"OnTraceResponse",
tracer.OnTraceResponse,
- context, ref reply
- );
+ context,
+ ref reply);
}
}
- foreach ( var mod in GetModules() )
+
+ foreach (var mod in this.GetModules())
{
Executor.ExceptionSafe(
mod.GetType().Name,
"OnEndRequest",
mod.OnEndRequest,
- context, reply
- );
+ context,
+ reply);
}
- } else
+ }
+ else
{
WcfEventSource.Log.NoOperationContextFound();
}
@@ -112,18 +121,19 @@ public bool HandleError(Exception error)
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
var context = WcfOperationContext.Current;
- if ( context != null )
+ if (context != null)
{
- foreach ( var mod in GetModules() )
+ foreach (var mod in this.GetModules())
{
Executor.ExceptionSafe(
mod.GetType().Name,
"OnError",
mod.OnError,
- context, error
- );
+ context,
+ error);
}
- } else
+ }
+ else
{
WcfEventSource.Log.NoOperationContextFound();
}
@@ -136,13 +146,15 @@ private IEnumerable GetModules()
private bool LogTelemetryFor(IOperationContext context)
{
- if ( contractFilter == null )
+ if (this.contractFilter == null)
+ {
return true;
- return contractFilter.ShouldProcess(
+ }
+
+ return this.contractFilter.ShouldProcess(
context.ContractName,
context.ContractNamespace,
- context.OperationName
- );
+ context.OperationName);
}
}
}
diff --git a/WCF/Shared/Implementation/WcfOperationContext.cs b/WCF/Shared/Implementation/WcfOperationContext.cs
index 7f7260f..e3c42cc 100644
--- a/WCF/Shared/Implementation/WcfOperationContext.cs
+++ b/WCF/Shared/Implementation/WcfOperationContext.cs
@@ -1,82 +1,126 @@
-using Microsoft.ApplicationInsights.DataContracts;
-using System;
-using System.Collections.Concurrent;
-using System.Runtime.Remoting;
-using System.Runtime.Remoting.Messaging;
-using System.ServiceModel;
-using System.ServiceModel.Dispatcher;
-
-namespace Microsoft.ApplicationInsights.Wcf.Implementation
+namespace Microsoft.ApplicationInsights.Wcf.Implementation
{
+ using System;
+ using System.Collections.Concurrent;
+ using System.Runtime.Remoting;
+ using System.Runtime.Remoting.Messaging;
+ using System.ServiceModel;
+ using System.ServiceModel.Dispatcher;
+ using Microsoft.ApplicationInsights.DataContracts;
+
internal class WcfOperationContext : IOperationContext, IExtension, IOperationContextState
{
+ private const string CallContextProperty = "AIWcfOperationContext";
private OperationContext context;
- private ConcurrentDictionary stateDicctionary;
+ private ConcurrentDictionary stateDicctionary;
+
+ private WcfOperationContext(OperationContext operationContext, RequestTelemetry httpCtxTelemetry)
+ {
+ this.context = operationContext;
+ this.stateDicctionary = new ConcurrentDictionary();
+ this.OperationName = this.DiscoverOperationName(operationContext);
+ if (httpCtxTelemetry != null)
+ {
+ this.Request = httpCtxTelemetry;
+ this.OwnsRequest = false;
+ }
+ else
+ {
+ this.Request = new RequestTelemetry();
+ this.Request.GenerateOperationId();
+ this.OwnsRequest = true;
+ }
+
+ WcfEventSource.Log.OperationContextCreated(this.Request.Id, this.OwnsRequest);
+ }
- const String CallContextProperty = "AIWcfOperationContext";
+ public static IOperationContext Current
+ {
+ get { return GetContext(); }
+ }
- public String OperationId
+ public string OperationId
{
- get { return Request.Id; }
+ get { return this.Request.Id; }
}
- public String OperationName { get; private set; }
+
+ public string OperationName { get; private set; }
+
public RequestTelemetry Request { get; private set; }
+
public bool OwnsRequest { get; private set; }
- public String ContractName
+ public string ContractName
{
- get { return context.EndpointDispatcher.ContractName; }
+ get { return this.context.EndpointDispatcher.ContractName; }
}
- public String ContractNamespace
+
+ public string ContractNamespace
{
- get { return context.EndpointDispatcher.ContractNamespace; }
+ get { return this.context.EndpointDispatcher.ContractNamespace; }
}
+
public Uri EndpointUri
{
- get { return context.EndpointDispatcher.EndpointAddress.Uri; }
+ get { return this.context.EndpointDispatcher.EndpointAddress.Uri; }
}
+
public Uri ToHeader
{
- get { return context.IncomingMessageHeaders.To; }
+ get { return this.context.IncomingMessageHeaders.To; }
}
+
public ServiceSecurityContext SecurityContext
{
- get { return GetSecurityContext(); }
+ get { return this.GetSecurityContext(); }
}
- public static IOperationContext Current
+ // In the normal case, we'll use the OperationContext
+ // found in the local thread. However, there are cases this won't work:
+ // - When async calls have been done and .NET < 4.6
+ // - Within a *client* side OperationContextScope
+ // To work around this, we store a copy of our context on the
+ // thread's LogicalCallContext, so that it gets moved from thread to thread
+ // Because this field is not serializable, we store an
+ // ObjectHandle instead.
+ public static WcfOperationContext FindContext(OperationContext owner)
{
- get { return GetContext(); }
- }
+ // don't retrieve a context for a client-side OperationContext
+ if (owner != null && owner.IsClientSideContext())
+ {
+ return null;
+ }
- private WcfOperationContext(OperationContext operationContext, RequestTelemetry httpCtxTelemetry)
- {
- context = operationContext;
- stateDicctionary = new ConcurrentDictionary();
- OperationName = DiscoverOperationName(operationContext);
- if ( httpCtxTelemetry != null )
+ WcfOperationContext context = null;
+ if (context == null && owner != null)
{
- Request = httpCtxTelemetry;
- OwnsRequest = false;
- } else
+ context = owner.Extensions.Find();
+ }
+
+ if (context == null)
{
- Request = new RequestTelemetry();
- Request.GenerateOperationId();
- OwnsRequest = true;
+ var handle = CallContext.LogicalGetData(CallContextProperty) as ObjectHandle;
+ if (handle != null)
+ {
+ context = handle.Unwrap() as WcfOperationContext;
+ }
}
- WcfEventSource.Log.OperationContextCreated(Request.Id, OwnsRequest);
+
+ return context;
}
public bool HasIncomingMessageProperty(string propertyName)
{
- if ( String.IsNullOrEmpty(propertyName) )
+ if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentNullException(nameof(propertyName));
}
+
try
{
- return context.IncomingMessageProperties.ContainsKey(propertyName);
- } catch ( ObjectDisposedException )
+ return this.context.IncomingMessageProperties.ContainsKey(propertyName);
+ }
+ catch (ObjectDisposedException)
{
// WCF message has been closed already
WcfEventSource.Log.RequestMessageClosed("reading property", propertyName);
@@ -86,14 +130,16 @@ public bool HasIncomingMessageProperty(string propertyName)
public object GetIncomingMessageProperty(string propertyName)
{
- if ( String.IsNullOrEmpty(propertyName) )
+ if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentNullException(nameof(propertyName));
}
+
try
{
- return context.IncomingMessageProperties[propertyName];
- } catch ( ObjectDisposedException )
+ return this.context.IncomingMessageProperties[propertyName];
+ }
+ catch (ObjectDisposedException)
{
// WCF message has been closed already
WcfEventSource.Log.RequestMessageClosed("reading property", propertyName);
@@ -101,16 +147,18 @@ public object GetIncomingMessageProperty(string propertyName)
}
}
- public bool HasOutgoingMessageProperty(String propertyName)
+ public bool HasOutgoingMessageProperty(string propertyName)
{
- if ( String.IsNullOrEmpty(propertyName) )
+ if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentNullException(nameof(propertyName));
}
+
try
{
- return context.OutgoingMessageProperties.ContainsKey(propertyName);
- } catch ( ObjectDisposedException )
+ return this.context.OutgoingMessageProperties.ContainsKey(propertyName);
+ }
+ catch (ObjectDisposedException)
{
// WCF message has been closed already
WcfEventSource.Log.ResponseMessageClosed("reading property", propertyName);
@@ -118,16 +166,18 @@ public bool HasOutgoingMessageProperty(String propertyName)
}
}
- public object GetOutgoingMessageProperty(String propertyName)
+ public object GetOutgoingMessageProperty(string propertyName)
{
- if ( String.IsNullOrEmpty(propertyName) )
+ if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentNullException(nameof(propertyName));
}
+
try
{
- return context.OutgoingMessageProperties[propertyName];
- } catch ( ObjectDisposedException )
+ return this.context.OutgoingMessageProperties[propertyName];
+ }
+ catch (ObjectDisposedException)
{
// WCF message has been closed already
WcfEventSource.Log.ResponseMessageClosed("reading property", propertyName);
@@ -135,161 +185,140 @@ public object GetOutgoingMessageProperty(String propertyName)
}
}
- public T GetIncomingMessageHeader(String name, String ns)
+ public T GetIncomingMessageHeader(string name, string ns)
{
- if ( String.IsNullOrEmpty(name) )
+ if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(name));
}
- if ( String.IsNullOrEmpty(ns) )
+
+ if (string.IsNullOrEmpty(ns))
{
throw new ArgumentNullException(nameof(ns));
}
+
try
{
- int index = context.IncomingMessageHeaders.FindHeader(name, ns);
- if ( index >= 0 )
+ var index = this.context.IncomingMessageHeaders.FindHeader(name, ns);
+ if (index >= 0)
{
- return context.IncomingMessageHeaders.GetHeader(index);
+ return this.context.IncomingMessageHeaders.GetHeader(index);
}
- } catch ( ObjectDisposedException )
+ }
+ catch (ObjectDisposedException)
{
// WCF message has been closed already
WcfEventSource.Log.RequestMessageClosed("reading header", ns + "#" + name);
}
+
return default(T);
}
- //
- // In the normal case, we'll use the OperationContext
- // found in the local thread. However, there are cases this won't work:
- // - When async calls have been done and .NET < 4.6
- // - Within a *client* side OperationContextScope
- // To work around this, we store a copy of our context on the
- // thread's LogicalCallContext, so that it gets moved from thread to thread
- // Because this field is not serializable, we store an
- // ObjectHandle instead.
- //
- public static WcfOperationContext FindContext(OperationContext owner)
+ void IExtension.Attach(OperationContext owner)
{
- // don't retrieve a context for a client-side OperationContext
- if ( owner != null && owner.IsClientSideContext() )
- {
- return null;
- }
+ }
- WcfOperationContext context = null;
- if ( context == null && owner != null )
- {
- context = owner.Extensions.Find();
- }
- if ( context == null )
- {
- var handle = CallContext.LogicalGetData(CallContextProperty) as ObjectHandle;
- if ( handle != null )
- {
- context = handle.Unwrap() as WcfOperationContext;
- }
- }
- return context;
+ void IExtension.Detach(OperationContext owner)
+ {
}
- private ServiceSecurityContext GetSecurityContext()
+ void IOperationContextState.SetState(string key, object value)
{
- try
- {
- return this.context.ServiceSecurityContext;
- } catch ( ObjectDisposedException )
+ this.stateDicctionary[key] = value;
+ }
+
+ bool IOperationContextState.TryGetState(string key, out T value)
+ {
+ value = default(T);
+ object storedValue = null;
+
+ if (this.stateDicctionary.TryGetValue(key, out storedValue))
{
- // WCF message has been closed already
- WcfEventSource.Log.RequestMessageClosed("reading", "ServiceSecurityContext");
- return null;
+ value = (T)storedValue;
+ return true;
}
+
+ return false;
}
private static IOperationContext GetContext()
{
var owner = OperationContext.Current;
- if ( owner != null && owner.IsClientSideContext() )
+ if (owner != null && owner.IsClientSideContext())
{
owner = null;
}
- WcfOperationContext context = FindContext(owner);
- if ( context == null )
+ var context = FindContext(owner);
+ if (context == null)
{
- if ( owner != null )
+ if (owner != null)
{
context = new WcfOperationContext(owner, PlatformContext.RequestFromHttpContext());
owner.Extensions.Add(context);
+
// backup in case we can't get to the server-side OperationContext later
CallContext.LogicalSetData(CallContextProperty, new ObjectHandle(context));
}
+
// no server-side OperationContext to attach to
}
- return context;
- }
-
- void IExtension