public static Metadata ProcessHeaders(Metadata headers) { if (headers == null) { throw new ArgumentNullException(nameof(headers)); } Metadata.Entry trackingEntry = headers.FirstOrDefault(x => string.CompareOrdinal(x.Key, s_TrackingContextKeyName) == 0); // Retrieve the tracking context from the message header, if it exists. if (trackingEntry != null) { // If an tracking context exists in the message header, always use it to replace the ambient context. TrackingContext tc = TrackingContext.DeSerialize(trackingEntry.ValueBytes); tc.SetAsCurrent(); } else { // If no tracking context exists then create one. TrackingContext.NewCurrentIfEmpty(); Debug.Assert(TrackingContext.Current != null); // Copy the tracking context to the message header. byte[] byteArray = TrackingContext.Serialize(TrackingContext.Current); headers.Add(s_TrackingContextKeyName, byteArray); } return(headers); }
public async Task Startup_GivenTrackingContextWithMergeAndOverwriteMiddleware_WhenNoTrackingContextSent_ThenTrackingContextReturned() { var textWriterSink = new StringWriter(); var hostBuilder = new HostBuilder() .ConfigureWebHost(webHost => { webHost.UseTestServer(); webHost.UseStartup <StartupWithMergeAndOverwrite>(); webHost.ConfigureServices((services) => StartupBase.ConfigureServicesWithLogSink( services, textWriterSink, $"{{{StartupBase.CountryOfOriginName}}}{textWriterSink.NewLine}")); }); var host = await hostBuilder.StartAsync(); var client = host.GetTestClient(); TrackingContext.Current.Should().BeNull(); var response = await client.GetAsync(@"/api/values"); response.EnsureSuccessStatusCode(); response.Headers.TryGetValues(TrackingContextHelper.TrackingContextKeyName, out IEnumerable <string> values).Should().BeTrue(); string tcBase64 = values.First(); TrackingContext tc = TrackingContext.DeSerialize(tcBase64.Base64StringToByteArray()); tc.CallChainId.Should().NotBeEmpty(); tc.OriginatorUtcTimestamp.Should().BeCloseTo(DateTime.UtcNow, 10000); tc.ExtraHeaders.Count.Should().Be(3); tc.ExtraHeaders[StartupBase.TraceIdentifierName].Should().NotBeNullOrWhiteSpace(); tc.ExtraHeaders[StartupBase.CountryOfOriginName].Should().Be(@"France"); tc.ExtraHeaders[StartupBase.RandomStringGeneratedWitEachCallName].Should().NotBeNullOrWhiteSpace(); TrackingContext.Current.Should().BeNull(); IList <string> countriesOfOrigin = textWriterSink .ToString() .Split(textWriterSink.NewLine, StringSplitOptions.RemoveEmptyEntries) .ToList(); countriesOfOrigin.Count().Should().Be(10); countriesOfOrigin.All(x => x.Equals(tc.ExtraHeaders[StartupBase.CountryOfOriginName])).Should().BeTrue(); }
public void TrackingContext_SerializeAndDeserialize_Success() { var extraHeaders = new Dictionary <string, string>() { { "AAA", "AAA" }, { "BBB", "BBB" }, }; var tc1 = new TrackingContext( Guid.NewGuid(), DateTime.UtcNow, extraHeaders); byte[] bytes = TrackingContext.Serialize(tc1); TrackingContext tc2 = TrackingContext.DeSerialize(bytes); Assert.AreNotEqual(0, bytes.Length); Assert.AreEqual(tc1.CallChainId, tc2.CallChainId); Assert.AreEqual(tc1.OriginatorUtcTimestamp, tc2.OriginatorUtcTimestamp); CollectionAssert.AreEquivalent(tc1.ExtraHeaders.ToList(), tc2.ExtraHeaders.ToList()); }
public void TrackingContext_GivenSerializeAndDeserialize_ThenSuccess() { var extraHeaders = new Dictionary <string, string>() { { "AAA", "AAA" }, { "BBB", "BBB" }, }; var tc1 = new TrackingContext( Guid.NewGuid(), DateTime.UtcNow, extraHeaders); byte[] bytes = TrackingContext.Serialize(tc1); TrackingContext tc2 = TrackingContext.DeSerialize(bytes); bytes.Should().NotBeEmpty(); tc2.CallChainId.Should().Be(tc1.CallChainId); tc2.OriginatorUtcTimestamp.Should().Be(tc1.OriginatorUtcTimestamp); tc2.ExtraHeaders.ToList().Should().BeEquivalentTo(tc1.ExtraHeaders.ToList()); }
private static void CreateTrackingContextFromHeaderValues(IEnumerable <string> values) { if (values == null) { throw new ArgumentNullException(nameof(values)); } if (values.Count() > 1) { throw new InvalidOperationException(Properties.Resources.CannotHaveMoreThanOneSerializedTrackingContextInHTTPHeaders); } string tcBase64 = values.FirstOrDefault(); if (string.IsNullOrWhiteSpace(tcBase64)) { TrackingContext.NewCurrentIfEmpty(); } else { // If an tracking context exists in the message header then use it to replace the current context. TrackingContext tc = TrackingContext.DeSerialize(tcBase64.Base64StringToByteArray()); tc.SetAsCurrent(); } }
public async Task Startup_GivenTrackingContextWithMergeMiddleware_WhenTrackingContextSent_ThenTrackingContextReturned() { var textWriterSink = new StringWriter(); var hostBuilder = new HostBuilder() .ConfigureWebHost(webHost => { webHost.UseTestServer(); webHost.UseStartup <StartupWithMerge>(); webHost.ConfigureServices((services) => StartupBase.ConfigureServicesWithLogSink( services, textWriterSink, $"{{{nameof(TrackingContext.CallChainId)}}}{textWriterSink.NewLine}")); }); var host = await hostBuilder.StartAsync(); var client = host.GetTestClient(); string headerKey = Guid.NewGuid().ToFlatString(); string headerValue = Guid.NewGuid().ToFlatString(); TrackingContext.NewCurrentIfEmpty(new Dictionary <string, string>() { { headerKey, headerValue }, { StartupBase.CountryOfOriginName, @"Germany" } }); TrackingContext currentContext = TrackingContext.Current; currentContext.Should().NotBeNull(); var requestMessage = new HttpRequestMessage(HttpMethod.Get, @"/api/values"); string tcHeader = TrackingContext.Serialize(currentContext).ByteArrayToBase64String(); requestMessage.Headers.Add(TrackingContextHelper.TrackingContextKeyName, tcHeader); var response = await client.SendAsync(requestMessage); response.EnsureSuccessStatusCode(); response.Headers.TryGetValues(TrackingContextHelper.TrackingContextKeyName, out IEnumerable <string> values).Should().BeTrue(); string tcBase64 = values.First(); TrackingContext tc = TrackingContext.DeSerialize(tcBase64.Base64StringToByteArray()); tc.CallChainId.Should().NotBeEmpty(); tc.OriginatorUtcTimestamp.Should().BeCloseTo(DateTime.UtcNow, 10000); tc.ExtraHeaders.Count.Should().Be(4); tc.ExtraHeaders[headerKey].Should().Be(headerValue); tc.ExtraHeaders[StartupBase.TraceIdentifierName].Should().NotBeNullOrWhiteSpace(); tc.ExtraHeaders[StartupBase.CountryOfOriginName].Should().Be(@"Germany"); tc.ExtraHeaders[StartupBase.RandomStringGeneratedWitEachCallName].Should().NotBeNullOrWhiteSpace(); TrackingContext.Current.Should().NotBeNull(); TrackingContext.Current.Should().BeEquivalentTo(currentContext); IList <string> callChainIds = textWriterSink .ToString() .Split(textWriterSink.NewLine, StringSplitOptions.RemoveEmptyEntries) .ToList(); callChainIds.Count().Should().Be(10); callChainIds.All(x => x.Equals(tc.CallChainId.ToDashedString())).Should().BeTrue(); }