public async Task RequestDepthExcluded_ExistingRequestWithoutDepth_HeaderWithRequestId()
        {
            var existingRequestId = new RequestIdBuilder()
                                    .WithNoDepth()
                                    .Build();

            var options = new RequestChainOptions
            {
                IncludeRequestDepth = false
            };

            Guid requestIdGuid;

            using (var server = new RequestIdTestServer(options))
                using (var client = server.CreateClient())
                {
                    client.ApplyRequestChain(existingRequestId);

                    var result = await client.MakeRequestAndGetRequestHeader();

                    result.Should()
                    .NotBeNullOrWhiteSpace();
                    result.Should()
                    .NotContain(":", "the header only contains the request, not the depth");
                    Guid.TryParse(result, out requestIdGuid)
                    .Should()
                    .BeTrue();
                }
        }
        public async Task RequestDepth_FromCustomRequestHeader_RequestId()
        {
            var customRequestHeader = "custom-rc-header";

            var originalDepth = 4;
            var expectedDepth = 5;

            var existingRequestId = new RequestIdBuilder()
                                    .WithDepth(originalDepth)
                                    .WithHeader(customRequestHeader)
                                    .Build();

            var options = new RequestChainOptions
            {
                RequestIdHeaderKey = customRequestHeader
            };

            using (var server = new RequestIdTestServer(options))
                using (var client = server.CreateClient())
                {
                    client.ApplyRequestChain(existingRequestId);

                    var result = await client.MakeRequestAndGetRequestDepth();

                    result.Should()
                    .Be(expectedDepth, "the original depth should increment when ApplyRequestChain is called on client");
                }
        }
        public async Task RequestId_FromCustomRequestHeader_RequestId()
        {
            var customRequestHeader = "custom-rc-header";
            var expectedId          = Guid.NewGuid();

            var existingRequestId = new RequestIdBuilder()
                                    .WithRequetId(expectedId)
                                    .WithHeader(customRequestHeader)
                                    .Build();

            var options = new RequestChainOptions
            {
                RequestIdHeaderKey = customRequestHeader
            };

            using (var server = new RequestIdTestServer(options))
                using (var client = server.CreateClient())
                {
                    client.ApplyRequestChain(existingRequestId);

                    var result = await client.MakeRequestAndGetRequestId();

                    result.Should()
                    .Be(expectedId, "the requestId comes from the existing request");
                }
        }
Exemple #4
0
        private int?GetRequestDepth(string requestIdString, RequestChainOptions options, IHeaderDictionary headers)
        {
            if (!options.IncludeRequestDepth)
            {
                requestIdString = RemoveDepthFromHeaderIfExists(requestIdString, options, headers);
                return(null);
            }

            var requestDepthStr = requestIdString
                                  .Split(SplitCharacter)
                                  .Skip(1)
                                  .FirstOrDefault();

            int requestDepth;

            if (string.IsNullOrEmpty(requestDepthStr) || !int.TryParse(requestDepthStr, out requestDepth) || requestDepth <= 0)
            {
                var msg = $"Request Depth for known RequestId {_requestId} was not found or malformed";

                if (options.ThrowOnMalformedRequestHeaders)
                {
                    throw new InvalidOperationException(msg);
                }
                else
                {
                    _logger?.Log(options.RequestIdHeaderMalformedLogLevel, msg);
                    return(null);
                }
            }

            return(requestDepth);
        }
        public RequestIdTestServer(RequestChainOptions options = null)
        {
            var webHostBuilder = new WebHostBuilder()
                                 .ConfigureServices(services => ConfigureServices(services, options))
                                 .Configure(ConfigureApplication);

            _server = new TestServer(webHostBuilder);
        }
Exemple #6
0
        internal RequestId(RequestChainOptions options)
        {
            if (options == default(RequestChainOptions))
            {
                throw new ArgumentNullException(nameof(options));
            }

            _options = options;
        }
Exemple #7
0
        private string RemoveDepthFromHeaderIfExists(string requestIdString, RequestChainOptions options, IHeaderDictionary headers)
        {
            requestIdString = requestIdString
                              .Split(SplitCharacter)
                              .First();

            headers[options.RequestIdHeaderKey] = requestIdString;

            return(requestIdString);
        }
        private void ConfigureServices(IServiceCollection services, RequestChainOptions options)
        {
            if (options == null)
            {
                options = new RequestChainOptions
                {
                    IncludeRequestDepth = true
                };
            }

            services.AddRequestChain(options);
        }
        public async Task RequestDepthExcluded_OriginalRequest_ValidRequestId()
        {
            var options = new RequestChainOptions
            {
                IncludeRequestDepth = false
            };

            using (var server = new RequestIdTestServer(options))
                using (var client = server.CreateClient())
                {
                    var result = await client.MakeRequestAndGetRequestId();

                    result.Should()
                    .NotBe(default(Guid), "it should be created by the server");
                }
        }
        public async Task RequestDepthExcluded_OriginalRequest_DepthNull()
        {
            var options = new RequestChainOptions
            {
                IncludeRequestDepth = false
            };

            using (var server = new RequestIdTestServer(options))
                using (var client = server.CreateClient())
                {
                    var result = await client.MakeRequestAndGetRequestDepth();

                    result.Should()
                    .Be(null, "the request depth is disabled in options");
                }
        }
Exemple #11
0
        private void CreateNewRequestId(HttpRequest request, RequestChainOptions options)
        {
            // Sets value in object
            _requestId = Guid.NewGuid();
            string requestHeaderValue;

            if (options.IncludeRequestDepth)
            {
                _requestDepth      = 0;
                requestHeaderValue = $"{_requestId}:0";
            }
            else
            {
                _requestDepth      = null;
                requestHeaderValue = _requestId.ToString();
            }

            // Add it to the request header which is important if request sent through reverse proxy
            request.Headers.Add(options.RequestIdHeaderKey, requestHeaderValue);
        }
Exemple #12
0
        /// <summary>
        /// Sets the Request Id by either pulling it out of the header or creating a new one.
        /// </summary>
        /// <param name="request">Current request</param>
        /// <param name="options">RequestChainOptions</param>
        /// <returns>True if the value previously existing, false if it was newly assigned</returns>
        internal bool SetRequestId(HttpRequest request, RequestChainOptions options)
        {
            KeyValuePair <string, StringValues> existingRequestIdHeader = request.Headers
                                                                          .FirstOrDefault(a => string.Equals(a.Key, options.RequestIdHeaderKey, StringComparison.OrdinalIgnoreCase));

            if (Equals(existingRequestIdHeader, default(KeyValuePair <string, StringValues>)))
            {
                // No request id set... creating a new one.
                CreateNewRequestId(request, options);
                _logger?.Log(options.RequestIdCreatedLogLevel, "RequestId created: {0}", _requestId);

                return(false);
            }

            string requestIdStr = existingRequestIdHeader.Value.FirstOrDefault();

            if (!Guid.TryParse(requestIdStr.Split(SplitCharacter)[0], out _requestId))
            {
                if (options.ThrowOnMalformedRequestHeaders)
                {
                    throw new InvalidOperationException($"RequestId in header was not in correct format: \"{requestIdStr}\"");
                }
                else
                {
                    CreateNewRequestId(request, options);

                    _logger?.Log(options.RequestIdHeaderMalformedLogLevel,
                                 "RequestId in header was not in correct format \"{0}\". Replacing with new RequestId: {1}",
                                 requestIdStr, _requestId);

                    return(false);
                }
            }
            else
            {
                _requestDepth = GetRequestDepth(requestIdStr, options, request.Headers);
            }

            return(true);
        }
        public async Task RequestDepthExcluded_ExistingRequestWithoutDepth_DepthNull()
        {
            var existingRequestId = new RequestIdBuilder()
                                    .WithNoDepth()
                                    .Build();

            var options = new RequestChainOptions
            {
                IncludeRequestDepth = false
            };

            using (var server = new RequestIdTestServer(options))
                using (var client = server.CreateClient())
                {
                    client.ApplyRequestChain(existingRequestId);

                    var result = await client.MakeRequestAndGetRequestDepth();

                    result.Should()
                    .Be(null, "the request depth is disabled in options");
                }
        }