コード例 #1
0
        /// <summary>
        /// Пытается получить из заголовков запроса TraceId и конвертировать в <see cref="Guid"/>?.
        /// </summary>
        /// <param name="context">HTTP контекст.</param>
        /// <param name="settings">Настройки TraceId.</param>
        /// <returns>TraceId.</returns>
        private static Guid?GetActualTraceId(HttpContext context, TraceIdSettings settings)
        {
            if (string.IsNullOrWhiteSpace(settings.Header))
            {
                return(null);
            }

            Guid?traceId = null;

            if (context.Response.Headers.TryGetValue(settings.Header, out var traceIdString) &&
                Guid.TryParse(traceIdString, out var traceGuid))
            {
                traceId = traceGuid;
            }

            return(traceId);
        }
コード例 #2
0
        /// <summary>
        /// Мок HTTP контекста.
        /// </summary>
        /// <param name="traceIdSettings">Настройки TraceId.</param>
        /// <returns>Мок HTTP контекста.</returns>
        private static DefaultHttpContext GetMockedContextFor(
            TraceIdSettings traceIdSettings,
            out MockResponseFeature feature
            )
        {
            feature = new MockResponseFeature();
            var context = new DefaultHttpContext();

            context.Features.Set <IHttpResponseFeature>(feature);
            if (!string.IsNullOrWhiteSpace(traceIdSettings.Header))
            {
                context.Request.Headers.Add(traceIdSettings.Header, TraceContext.Current.TraceId?.ToString());
            }

            if (!string.IsNullOrWhiteSpace(traceIdSettings.TraceIdSourceHeader))
            {
                context.Request.Headers.Add(traceIdSettings.TraceIdSourceHeader, TraceContext.Current.TraceIdSource);
            }

            return(context);
        }
コード例 #3
0
 /// <summary>
 /// Конструктор по-умолчанию.
 /// </summary>
 /// <param name="next">Следующая Middleware в конвейере.</param>
 /// <param name="settings">Настройки TraceId.</param>
 public TraceIdMiddleware(RequestDelegate next, IOptions <TraceIdSettings> settings)
 {
     _next     = next ?? throw new ArgumentNullException(nameof(next));
     _settings = settings?.Value ?? throw new ArgumentNullException(nameof(settings));
 }
コード例 #4
0
 /// <summary>
 /// Конструктор по-умолчанию.
 /// </summary>
 /// <param name="settings">Настройки сквозного идентификатора.</param>
 public TraceIdDelegatingHandler(IOptions <TraceIdSettings> settings)
 {
     _settings = settings.Value;
 }
コード例 #5
0
 public TraceIdMiddleware(RequestDelegate next, IOptions <TraceIdSettings> options, IAppContextAccessor contextAccessor)
 {
     _next            = next ?? throw new ArgumentNullException(nameof(next));
     _contextAccessor = contextAccessor ?? throw new ArgumentNullException(nameof(contextAccessor));
     _settings        = options.Value;
 }
コード例 #6
0
        public async Task CorrectHandleSettingsAsync(
            int caseNumber,
            HttpStatusCode expectedStatusCode,
            string initialTraceString,
            bool generateIfNotPresent,
            bool throwBadRequestIfNotPresent,
            bool initialAndFinalTraceIdMustBeEqual
            )
        {
            #region Arrange

            var initialTraceId  = Guid.Parse(initialTraceString);
            var traceIdSettings = new TraceIdSettings
            {
                GenerateIfNotPresent        = generateIfNotPresent,
                ThrowBadRequestIfNotPresent = throwBadRequestIfNotPresent
            };
            var traceContext1 = TraceContext.Create(initialTraceId);

            var context           = GetMockedContextFor(traceIdSettings, out var feature);
            var traceIdMiddleware =
                new TraceIdMiddleware(_ => feature.CompleteAsync(), Options.Create(traceIdSettings));

            #endregion Arrange

            #region Act

            await traceIdMiddleware.Invoke(context, NullLogger <TraceIdMiddleware> .Instance);

            #endregion Act

            #region Assert

            var traceContext2 = TraceContext.Current;

            var actualTraceId = GetActualTraceId(context, traceIdSettings);

            Assert.Multiple(() =>
            {
                Assert.AreEqual((int)expectedStatusCode, context.Response.StatusCode,
                                "status code должен быть ожидаемым.");

                if (initialAndFinalTraceIdMustBeEqual)
                {
                    Assert.AreEqual(initialTraceId, actualTraceId ?? Guid.Empty, "traceId до и после выполнения должны быть одинаковыми.");
                }

                if (traceIdSettings.GenerateIfNotPresent)
                {
                    Assert.IsTrue(ReferenceEquals(traceContext1, traceContext2), "Инстансы должны быть одним и тем же.");
                    Assert.AreNotEqual(Guid.Empty, TraceContext.Current.TraceId,
                                       "Если требуется генерировать при отсутствии TraceId, то TraceId не должен быть пустым.");

                    if (actualTraceId.HasValue)
                    {
                        Assert.IsTrue(actualTraceId != Guid.Empty);
                    }
                }
                else
                {
                    if (initialTraceId == Guid.Empty)
                    {
                        Assert.IsNull(actualTraceId);
                    }
                    else
                    {
                        Assert.AreEqual(initialTraceId, actualTraceId);
                    }
                }
            });

            #endregion Assert
        }