public async Task Invoke(HttpContext context)
        {
            PathString subpath;

            if (!context.Request.Path.StartsWithSegments(_options.Path, out subpath))
            {
                await _next(context);

                return;
            }

            var policyName = subpath.ToUriComponent().Trim('/');

            if (policyName.Length == 0)
            {
                policyName = Constants.DefaultPolicy;
            }

            if (_options.AuthorizationPolicy != null)
            {
                var principal = await SecurityHelper.GetUserPrincipal(context, _options.AuthorizationPolicy);

                if (!await _authorizationService.AuthorizeAsync(principal, context, _options.AuthorizationPolicy))
                {
                    _logger.AuthorizationFailed();
                    await _next(context);

                    return;
                }
            }

            HealthCheckPolicy policy = _policyProvider.GetPolicy(policyName);

            if (policy == null)
            {
                _logger.InvalidPolicy(policyName);
                await _next(context);

                return;
            }

            var response            = context.Response;
            var healthCheckResponse = await _healthService.CheckHealthAsync(policy);

            if (healthCheckResponse.HasErrors)
            {
                _logger.HealthCheckFailed(healthCheckResponse.Errors);
                if (healthCheckResponse.HasCriticalErrors)
                {
                    response.StatusCode = StatusCodes.Status503ServiceUnavailable;
                    response.WriteRetryAfterHeader(healthCheckResponse.RetryAfter);
                }
            }
            else
            {
                _logger.HealthCheckSucceeded();
                response.StatusCode = StatusCodes.Status200OK;
            }

            if (_options.SendResults && !HttpMethods.IsHead(context.Request.Method))
            {
                response.ContentType = ApplicationJson;
                using (var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8, 1024, _bytePool, _charPool))
                {
                    using (var jsonWriter = new JsonTextWriter(writer))
                    {
                        jsonWriter.ArrayPool   = _jsonCharPool;
                        jsonWriter.CloseOutput = false;

                        _jsonSerializer.Serialize(jsonWriter, healthCheckResponse.Results);
                    }
                }
            }
        }
Beispiel #2
0
        public CanaryMiddleware(
            RequestDelegate next,
            IOptions <CanaryOptions> options,
            ILoggerFactory loggerFactory,
            IHealthCheckService healthService,
            IHealthCheckPolicyProvider policyProvider,
            IServerSwitch serverSwitch,
            IAuthorizationService authorizationService)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            if (healthService == null)
            {
                throw new ArgumentNullException(nameof(healthService));
            }

            if (policyProvider == null)
            {
                throw new ArgumentNullException(nameof(policyProvider));
            }

            if (authorizationService == null)
            {
                throw new ArgumentNullException(nameof(authorizationService));
            }

            if (authorizationService == null)
            {
                throw new ArgumentNullException(nameof(authorizationService));
            }

            _next                 = next;
            _options              = options.Value;
            _logger               = loggerFactory.CreateLogger <CanaryMiddleware>();
            _healthService        = healthService;
            _serverSwitch         = serverSwitch;
            _authorizationService = authorizationService;

            if (_options.EnableHealthCheck)
            {
                var defaultPolicy = policyProvider.GetPolicy(_options.PolicyName);
                if (defaultPolicy == null)
                {
                    throw new ArgumentException($"{nameof(_options.PolicyName)} '{_options.PolicyName}' is not a valid policy.", nameof(_options));
                }

                _defaultPolicy = defaultPolicy;
            }
        }