public async Task <StatusResultServiceModel> StatusAsync()
        {
            var isHealthy = false;
            var message   = "Diagnostics check failed";
            var request   = new HttpRequest();

            try
            {
                request.SetUriFromString($"{this.serviceUrl}/status");
                string tenantId = this.httpContextAccessor.HttpContext.Request.GetTenant();
                request.Headers.Add(TenantHeader, tenantId);
                var response = await this.httpClient.GetAsync(request);

                if (response.IsError)
                {
                    message = "Status code: " + response.StatusCode + "; Response: " + response.Content;
                }
                else
                {
                    var data = JsonConvert.DeserializeObject <Dictionary <string, object> >(response.Content);
                    message   = data["Message"].ToString();
                    isHealthy = Convert.ToBoolean(data["IsHealthy"]);
                }
            }
            catch (Exception e)
            {
                this.logger.LogError(e, message);
            }

            return(new StatusResultServiceModel(isHealthy, message));
        }
        private async Task PostHttpRequestWithRetryAsync(HttpRequest request)
        {
            int  retries          = 0;
            bool requestSucceeded = false;

            while (!requestSucceeded && retries < this.maxRetries)
            {
                try
                {
                    IHttpResponse response = await this.httpClient.PostAsync(request);

                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        retries++;
                        this.LogAndSleepOnFailure(retries, response.Content);
                    }
                    else
                    {
                        requestSucceeded = true;
                    }
                }
                catch (Exception e)
                {
                    retries++;
                    this.LogAndSleepOnFailure(retries, e.Message);
                }
            }
        }
        private IHttpRequest CreateRequest(string url, string tenantId = null, NameValueCollection headers = null)
        {
            var request = new HttpRequest();

            request.SetUriFromString(url);

            if (string.IsNullOrEmpty(tenantId))
            {
                try
                {
                    tenantId = this.httpContextAccessor.HttpContext.Request.GetTenant();
                }
                catch (Exception e)
                {
                    throw new ArgumentException("The tenantId for the External Request was not provided and could not be retrieved from the HttpContextAccessor Request.", e);
                }
            }

            request.AddHeader(TenantHeader, tenantId);

            if (headers != null)
            {
                foreach (string item in headers.AllKeys)
                {
                    request.AddHeader(item, headers[item]);
                }
            }

            if (url.ToLowerInvariant().StartsWith("https:"))
            {
                request.Options.AllowInsecureSSLServer = true;
            }

            if (this.httpContextAccessor.HttpContext != null && this.httpContextAccessor.HttpContext.Request.Headers.ContainsKey(AzdsRouteKey))
            {
                try
                {
                    var azdsRouteAs = this.httpContextAccessor.HttpContext.Request.Headers.First(p => string.Equals(p.Key, AzdsRouteKey, StringComparison.OrdinalIgnoreCase));
                    request.Headers.Add(AzdsRouteKey, azdsRouteAs.Value.First());  // azdsRouteAs.Value returns an iterable of strings, take the first
                }
                catch (Exception e)
                {
                    throw new Exception($"Unable to attach the {AzdsRouteKey} header to the IdentityGatewayClient Request.", e);
                }
            }

            return(request);
        }
        /**
         * Logs event with given event name and event properties
         * to diagnostics event endpoint.
         */
        public async Task LogEventAsync(string eventName, Dictionary <string, object> eventProperties)
        {
            var request = new HttpRequest();

            try
            {
                request.SetUriFromString($"{this.serviceUrl}/diagnosticsevents");

                string tenantId = this.httpContextAccessor.HttpContext.Request.GetTenant();
                request.Headers.Add(TenantHeader, tenantId);
                DiagnosticsRequestModel model = new DiagnosticsRequestModel
                {
                    EventType       = eventName,
                    EventProperties = eventProperties,
                };
                request.SetContent(JsonConvert.SerializeObject(model));
                await this.PostHttpRequestWithRetryAsync(request);
            }
            catch (Exception e)
            {
                this.logger.LogWarning(e, "Cannot log to diagnostics service, diagnostics url not provided");
            }
        }