Пример #1
0
        public void Equals_Second_Null_Returns_False()
        {
            var options1 = new HealthCheckConfig();

            var equals = options1.Equals(null);

            Assert.False(equals);
        }
Пример #2
0
        public healthcheck()
        {
            var logManager = DependencyInjectionHelper.ResolveService <ILogManager>();

            var config = new HealthCheckConfig
            {
                MongoDbConnectionString = ConfigurationManager.ConnectionStrings["analytics"].ConnectionString,
            };

            _healthCheckService = new BasicHealthCheckService(logManager, config);
        }
        public healthcheck()
        {
            var logManager      = DependencyInjectionHelper.ResolveService <ILogManager>();
            var nomisApiService = DependencyInjectionHelper.ResolveService <INomisApiService>();

            var config = new HealthCheckConfig
            {
                MongoDbConnectionString = ConfigurationManager.ConnectionStrings["analytics"].ConnectionString,
                RedisDbConnectionString = ConfigurationManager.ConnectionStrings["redis.sessions"]?.ConnectionString,
                IdamHealthCheckUrl      = ConfigurationManager.AppSettings["HMPPS.Authentication.HealthCheckEndpoint"].ValueOrEmpty()
            };

            _extendedHealthCheckService = new ExtendedHealthCheckService(logManager, config, nomisApiService);
            _basicHealthCheckService    = new BasicHealthCheckService(logManager, config);
        }
Пример #4
0
        public static IHealthChecksBuilder ConfigureHealthChecks(this IServiceCollection services, IConfiguration configuration)
        {
            _config = configuration.GetSection("HealthCheckConfig").Get <HealthCheckConfig>();

            MemoryCheck.Threshold = _config.MemoryCheckConfig.MemoryUsageThresholdMb;

            var context = services
                          .AddHealthChecks();

            if (_config.MemoryCheckConfig.Enabled)
            {
                context = context.AddCheck <MemoryCheck>(nameof(MemoryCheck));
            }

            return(context);
        }
Пример #5
0
        public void Equals_Same_Value_Returns_True()
        {
            var options1 = new HealthCheckConfig
            {
                Active = new ActiveHealthCheckConfig
                {
                    Enabled  = true,
                    Interval = TimeSpan.FromSeconds(2),
                    Timeout  = TimeSpan.FromSeconds(1),
                    Policy   = "Any5xxResponse",
                    Path     = "/a",
                },
                Passive = new PassiveHealthCheckConfig
                {
                    Enabled            = true,
                    Policy             = "Passive",
                    ReactivationPeriod = TimeSpan.FromSeconds(5),
                }
            };

            var options2 = new HealthCheckConfig
            {
                Active = new ActiveHealthCheckConfig
                {
                    Enabled  = true,
                    Interval = TimeSpan.FromSeconds(2),
                    Timeout  = TimeSpan.FromSeconds(1),
                    Policy   = "any5xxResponse",
                    Path     = "/a",
                },
                Passive = new PassiveHealthCheckConfig
                {
                    Enabled            = true,
                    Policy             = "passive",
                    ReactivationPeriod = TimeSpan.FromSeconds(5),
                }
            };

            var equals = options1.Equals(options2);

            Assert.True(equals);
            Assert.Equal(options1.GetHashCode(), options2.GetHashCode());
        }
Пример #6
0
        public void Equals_Different_Value_Returns_False()
        {
            var options1 = new HealthCheckConfig
            {
                Active = new ActiveHealthCheckConfig
                {
                    Enabled  = true,
                    Interval = TimeSpan.FromSeconds(2),
                    Timeout  = TimeSpan.FromSeconds(1),
                    Policy   = "Any5xxResponse",
                    Path     = "/a",
                },
                Passive = new PassiveHealthCheckConfig
                {
                    Enabled            = true,
                    Policy             = "Passive",
                    ReactivationPeriod = TimeSpan.FromSeconds(5),
                }
            };

            var options2 = new HealthCheckConfig
            {
                Active = new ActiveHealthCheckConfig
                {
                    Enabled  = true,
                    Interval = TimeSpan.FromSeconds(2),
                    Timeout  = TimeSpan.FromSeconds(1),
                    Policy   = "Different",
                    Path     = "/a",
                },
                Passive = new PassiveHealthCheckConfig
                {
                    Enabled            = true,
                    Policy             = "Passive",
                    ReactivationPeriod = TimeSpan.FromSeconds(5),
                }
            };

            var equals = options1.Equals(options2);

            Assert.False(equals);
        }
Пример #7
0
    public void GetAvailableDestinations_HealthChecksDisabled_ReturnAll(HealthCheckConfig config)
    {
        var cluster = new ClusterConfig()
        {
            ClusterId = "cluster1", HealthCheck = config
        };
        var allDestinations = new[]
        {
            new DestinationState("d1")
            {
                Health = { Active = DestinationHealth.Healthy }
            },
            new DestinationState("d2")
            {
                Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Healthy }
            },
            new DestinationState("d3")
            {
                Health = { Passive = DestinationHealth.Healthy }
            },
            new DestinationState("d4"),
            new DestinationState("d5")
            {
                Health = { Active = DestinationHealth.Healthy, Passive = DestinationHealth.Unhealthy }
            },
            new DestinationState("d6")
            {
                Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Unhealthy }
            }
        };
        var policy = new HealthyAndUnknownDestinationsPolicy();

        var availableDestinations = policy.GetAvailalableDestinations(cluster, allDestinations);

        Assert.Equal(6, availableDestinations.Count);
        Assert.Same(allDestinations[0], availableDestinations[0]);
        Assert.Same(allDestinations[1], availableDestinations[1]);
        Assert.Same(allDestinations[2], availableDestinations[2]);
        Assert.Same(allDestinations[3], availableDestinations[3]);
        Assert.Same(allDestinations[4], availableDestinations[4]);
        Assert.Same(allDestinations[5], availableDestinations[5]);
    }
Пример #8
0
    public async Task PassiveHealthChecksEnabled_MultipleDestinationFailures_ProxyReturnsServiceUnavailable()
    {
        var destinationReached = false;

        var test = new TestEnvironment(
            context =>
        {
            destinationReached = true;
            throw new InvalidOperationException();
        },
            proxyBuilder => proxyBuilder.Services.AddSingleton <IForwarderHttpClientFactory>(new MockHttpClientFactory((_, _) => throw new IOException())),
            proxyApp => { },
            configTransformer: (c, r) =>
        {
            c = c with
            {
                HealthCheck = new HealthCheckConfig
                {
                    Passive = new PassiveHealthCheckConfig
                    {
                        Enabled = true
                    }
                }
            };

            return(c, r);
        });

        await test.Invoke(async uri =>
        {
            using var client = new HttpClient();
            for (var i = 0; i < 42; i++)
            {
                using var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, uri));

                Assert.Equal(i < 10 ? HttpStatusCode.BadGateway : HttpStatusCode.ServiceUnavailable, response.StatusCode);
            }
        });

        Assert.False(destinationReached);
    }
Пример #9
0
        public ValueTask <ClusterConfig> ConfigureClusterAsync(ClusterConfig cluster, CancellationToken cancel)
        {
            // How to use custom metadata to configure clusters
            if (cluster.Metadata?.TryGetValue("CustomHealth", out var customHealth) ?? false &&
                string.Equals(customHealth, "true", StringComparison.OrdinalIgnoreCase))
            {
                cluster = cluster with
                {
                    HealthCheck = new HealthCheckConfig
                    {
                        Active = new ActiveHealthCheckConfig
                        {
                            Enabled = true,
                            Policy  = HealthCheckConstants.ActivePolicy.ConsecutiveFailures,
                        },
                        Passive = cluster.HealthCheck?.Passive,
                    }
                };
            }

            // Or wrap the meatadata in config sugar
            var config = new ConfigurationBuilder().AddInMemoryCollection(cluster.Metadata).Build();

            if (config.GetValue <bool>("CustomHealth"))
            {
                cluster = cluster with
                {
                    HealthCheck = new HealthCheckConfig
                    {
                        Active = new ActiveHealthCheckConfig
                        {
                            Enabled = true,
                            Policy  = HealthCheckConstants.ActivePolicy.ConsecutiveFailures,
                        },
                        Passive = cluster.HealthCheck?.Passive,
                    }
                };
            }

            return(new ValueTask <ClusterConfig>(cluster));
        }
Пример #10
0
        void CopyOrReset(HealthCheckConfig oldConfig, HealthCheckConfig newConfig, UpdateHealthCheckRequest delta)
        {
            var hcType = typeof(HealthCheckConfig);
            var upType = typeof(UpdateHealthCheckRequest);
            var bFlags = BindingFlags.Public | BindingFlags.Instance;

            foreach (var hcProp in hcType.GetProperties(bFlags))
            {
                var oldValue = hcProp.GetValue(oldConfig);
                var newValue = hcProp.GetValue(newConfig);
                // Cheap way to compare values, even for complex objects
                var oldValueJson = JsonSerializer.Serialize(oldValue);
                var newValueJson = JsonSerializer.Serialize(newValue);
                if (oldValueJson != newValueJson)
                {
                    var upProp = upType.GetProperty(hcProp.Name, bFlags);
                    if (upProp == null)
                    {
                        _logger.LogWarning($"Detected Health Check config change for property [{hcProp.Name}]"
                                           + " but value CANNOT be updated on existing Health Check");
                    }
                    else
                    {
                        if (newValueJson == null && ResettableHealthCheckElements.Contains(hcProp.Name))
                        {
                            if (delta.ResetElements == null)
                            {
                                delta.ResetElements = new List <string>();
                            }
                            delta.ResetElements.Add(hcProp.Name);
                        }
                        else
                        {
                            upProp.SetValue(delta, newValue);
                        }
                    }
                }
            }
        }
Пример #11
0
        public void convert_HealthCheckConfig_to_json()
        {
            var hcc = new HealthCheckConfig
            {
                AlarmIdentifier = new AlarmIdentifier
                {
                    Name   = "AlarmId",
                    Region = CloudWatchRegion.ApNortheast1,
                },
                ChildHealthChecks = new List <string> {
                    "Child1", "Child2",
                },
                Disabled                     = true,
                EnableSNI                    = true,
                FailureThreshold             = 99,
                FullyQualifiedDomainName     = "FQDN1",
                HealthThreshold              = 88,
                InsufficientDataHealthStatus = InsufficientDataHealthStatus.LastKnownStatus,
                Inverted                     = true,
                IPAddress                    = "1.2.3.4",
                MeasureLatency               = true,
                Port    = 7654,
                Regions = new List <string> {
                    "reg1", "reg2", "reg3",
                },
                RequestInterval = 55,
                ResourcePath    = "ResPath1",
                SearchString    = "Search1",
                Type            = HealthCheckType.CLOUDWATCH_METRIC,
            };

            var json = JsonSerializer.Serialize(hcc, SerOptions);
            var orig = JsonSerializer.Deserialize <HealthCheckConfig>(json, SerOptions);

            orig.Should().BeEquivalentTo(hcc);
        }
Пример #12
0
        public void Equals_Different_Value_Returns_False()
        {
            var config1 = new ClusterConfig
            {
                ClusterId    = "cluster1",
                Destinations = new Dictionary <string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
                {
                    {
                        "destinationA",
                        new DestinationConfig
                        {
                            Address  = "https://localhost:10000/destA",
                            Health   = "https://localhost:20000/destA",
                            Metadata = new Dictionary <string, string> {
                                { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" }
                            }
                        }
                    },
                    {
                        "destinationB",
                        new DestinationConfig
                        {
                            Address  = "https://localhost:10000/destB",
                            Health   = "https://localhost:20000/destB",
                            Metadata = new Dictionary <string, string> {
                                { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" }
                            }
                        }
                    }
                },
                HealthCheck = new HealthCheckConfig
                {
                    Passive = new PassiveHealthCheckConfig
                    {
                        Enabled            = true,
                        Policy             = "FailureRate",
                        ReactivationPeriod = TimeSpan.FromMinutes(5)
                    },
                    Active = new ActiveHealthCheckConfig
                    {
                        Enabled  = true,
                        Interval = TimeSpan.FromSeconds(4),
                        Timeout  = TimeSpan.FromSeconds(6),
                        Policy   = "Any5xxResponse",
                        Path     = "healthCheckPath"
                    }
                },
                LoadBalancingPolicy = LoadBalancingPolicies.Random,
                SessionAffinity     = new SessionAffinityConfig
                {
                    Enabled         = true,
                    FailurePolicy   = "Return503Error",
                    Policy          = "Cookie",
                    AffinityKeyName = "Key1",
                    Cookie          = new SessionAffinityCookieConfig
                    {
                        Domain       = "localhost",
                        Expiration   = TimeSpan.FromHours(3),
                        HttpOnly     = true,
                        IsEssential  = true,
                        MaxAge       = TimeSpan.FromDays(1),
                        Path         = "mypath",
                        SameSite     = Microsoft.AspNetCore.Http.SameSiteMode.Strict,
                        SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest
                    }
                },
                HttpClient = new HttpClientConfig
                {
                    SslProtocols                        = SslProtocols.Tls11 | SslProtocols.Tls12,
                    MaxConnectionsPerServer             = 10,
                    DangerousAcceptAnyServerCertificate = true,
                    ActivityContextHeaders              = ActivityContextHeaders.CorrelationContext,
                },
                HttpRequest = new ForwarderRequestConfig
                {
                    Timeout = TimeSpan.FromSeconds(60),
                    Version = Version.Parse("1.0"),
#if NET
                    VersionPolicy = HttpVersionPolicy.RequestVersionExact,
#endif
                },
                Metadata = new Dictionary <string, string> {
                    { "cluster1-K1", "cluster1-V1" }, {
                        "cluster1-K2", "cluster1-V2"
                    }
                }
            };

            Assert.False(config1.Equals(config1 with {
                ClusterId = "different"
            }));
            Assert.False(config1.Equals(config1 with {
                Destinations = new Dictionary <string, DestinationConfig>()
            }));
            Assert.False(config1.Equals(config1 with {
                HealthCheck = new HealthCheckConfig()
            }));
            Assert.False(config1.Equals(config1 with {
                LoadBalancingPolicy = "different"
            }));
            Assert.False(config1.Equals(config1 with
            {
                SessionAffinity = new SessionAffinityConfig
                {
                    Enabled         = true,
                    FailurePolicy   = "Return503Error",
                    Policy          = "Cookie",
                    AffinityKeyName = "Key1",
                    Cookie          = new SessionAffinityCookieConfig
                    {
                        Domain       = "localhost",
                        Expiration   = TimeSpan.FromHours(3),
                        HttpOnly     = true,
                        IsEssential  = true,
                        MaxAge       = TimeSpan.FromDays(1),
                        Path         = "newpath",
                        SameSite     = Microsoft.AspNetCore.Http.SameSiteMode.Strict,
                        SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest
                    }
                }
            }));
            Assert.False(config1.Equals(config1 with
            {
                HttpClient = new HttpClientConfig
                {
                    SslProtocols                        = SslProtocols.Tls12,
                    MaxConnectionsPerServer             = 10,
                    DangerousAcceptAnyServerCertificate = true,
                    ActivityContextHeaders              = ActivityContextHeaders.CorrelationContext,
                }
            }));
            Assert.False(config1.Equals(config1 with {
                HttpRequest = new ForwarderRequestConfig()
                {
                }
            }));
            Assert.False(config1.Equals(config1 with {
                Metadata = null
            }));
        }
        public IRequest Marshall(CreateHealthCheckRequest createHealthCheckRequest)
        {
            IRequest request = new DefaultRequest(createHealthCheckRequest, "AmazonRoute53");



            request.HttpMethod = "POST";

            string uriResourcePath = "/2012-12-12/healthcheck";

            if (uriResourcePath.Contains("?"))
            {
                string queryString = uriResourcePath.Substring(uriResourcePath.IndexOf("?") + 1);
                uriResourcePath = uriResourcePath.Substring(0, uriResourcePath.IndexOf("?"));

                foreach (string s in queryString.Split('&', ';'))
                {
                    string[] nameValuePair = s.Split('=');
                    if (nameValuePair.Length == 2 && nameValuePair[1].Length > 0)
                    {
                        request.Parameters.Add(nameValuePair[0], nameValuePair[1]);
                    }
                    else
                    {
                        request.Parameters.Add(nameValuePair[0], null);
                    }
                }
            }

            request.ResourcePath = uriResourcePath;


            StringWriter  stringWriter = new StringWriter();
            XmlTextWriter xmlWriter    = new XmlTextWriter(stringWriter);

            xmlWriter.Namespaces = true;


            xmlWriter.WriteStartElement("CreateHealthCheckRequest", "https://route53.amazonaws.com/doc/2012-12-12/");
            if (createHealthCheckRequest.IsSetCallerReference())
            {
                xmlWriter.WriteElementString("CallerReference", "https://route53.amazonaws.com/doc/2012-12-12/", createHealthCheckRequest.CallerReference.ToString());
            }
            if (createHealthCheckRequest != null)
            {
                HealthCheckConfig healthCheckConfigHealthCheckConfig = createHealthCheckRequest.HealthCheckConfig;
                if (healthCheckConfigHealthCheckConfig != null)
                {
                    xmlWriter.WriteStartElement("HealthCheckConfig", "https://route53.amazonaws.com/doc/2012-12-12/");
                    if (healthCheckConfigHealthCheckConfig.IsSetIPAddress())
                    {
                        xmlWriter.WriteElementString("IPAddress", "https://route53.amazonaws.com/doc/2012-12-12/", healthCheckConfigHealthCheckConfig.IPAddress.ToString());
                    }
                    if (healthCheckConfigHealthCheckConfig.IsSetPort())
                    {
                        xmlWriter.WriteElementString("Port", "https://route53.amazonaws.com/doc/2012-12-12/", healthCheckConfigHealthCheckConfig.Port.ToString());
                    }
                    if (healthCheckConfigHealthCheckConfig.IsSetType())
                    {
                        xmlWriter.WriteElementString("Type", "https://route53.amazonaws.com/doc/2012-12-12/", healthCheckConfigHealthCheckConfig.Type.ToString());
                    }
                    if (healthCheckConfigHealthCheckConfig.IsSetResourcePath())
                    {
                        xmlWriter.WriteElementString("ResourcePath", "https://route53.amazonaws.com/doc/2012-12-12/", healthCheckConfigHealthCheckConfig.ResourcePath.ToString());
                    }
                    if (healthCheckConfigHealthCheckConfig.IsSetFullyQualifiedDomainName())
                    {
                        xmlWriter.WriteElementString("FullyQualifiedDomainName", "https://route53.amazonaws.com/doc/2012-12-12/", healthCheckConfigHealthCheckConfig.FullyQualifiedDomainName.ToString());
                    }
                    xmlWriter.WriteEndElement();
                }
            }

            xmlWriter.WriteEndElement();


            try
            {
                request.Content = System.Text.Encoding.UTF8.GetBytes(stringWriter.ToString());
                request.Headers.Add("Content-Type", "application/xml");
            }
            catch (EncoderFallbackException e)
            {
                throw new AmazonServiceException("Unable to marshall request to XML", e);
            }


            return(request);
        }
 public BasicHealthCheckService(ILogManager logManager, HealthCheckConfig config)
     : base(logManager)
 {
     _config = config;
 }
Пример #15
0
        /// Inline form:
        ///   <hc-type> ';' <threshold> ';' <ip-addr> ';' <port> ';' <fqdn> ';' <res-path> ';' <search>
        Task <HealthCheckConfig> ParseInlineHealthCheck(string specTag)
        {
            var specParts = specTag.Split(";", 7);

            if (specParts.Length < 2)
            {
                throw new Exception("invalid INLINE R53 Health Check spec");
            }

            _logger.LogInformation($"Defining R53 Health Check per resolved INLINE spec: {specTag}");

            var hcTypeStr = specParts[0];
            var hcType    = HealthCheckType.FindValue(hcTypeStr);

            if (hcType == null)
            {
                throw new Exception("unknown Health Check type");
            }
            if (!HealthCheckInlineAllowedTypes.Contains(hcType))
            {
                throw new Exception("Health Check type is unsupported for INLINE spec");
            }

            var config = new HealthCheckConfig
            {
                Type = hcType,
                // RequestInterval = 30,
                // InsufficientDataHealthStatus = InsufficientDataHealthStatus.LastKnownStatus,
            };
            uint numVal;

            if (specParts.Length > 1 && !string.IsNullOrWhiteSpace(specParts[1]))
            {
                if (!uint.TryParse(specParts[1], out numVal))
                {
                    throw new Exception("invalid threshold value");
                }
                config.FailureThreshold = (int)numVal;
            }

            if (specParts.Length > 2 && !string.IsNullOrWhiteSpace(specParts[2]))
            {
                config.IPAddress = specParts[2].Trim();
            }

            if (specParts.Length > 3 && !string.IsNullOrWhiteSpace(specParts[3]))
            {
                if (!uint.TryParse(specParts[3], out numVal))
                {
                    throw new Exception("invalid port value");
                }
                config.Port = (int)numVal;
            }

            if (specParts.Length > 4 && !string.IsNullOrWhiteSpace(specParts[4]))
            {
                config.FullyQualifiedDomainName = specParts[4].Trim();
            }

            if (specParts.Length > 5 && !string.IsNullOrWhiteSpace(specParts[5]))
            {
                config.ResourcePath = specParts[5];
            }

            if (specParts.Length > 6 && !string.IsNullOrWhiteSpace(specParts[6]))
            {
                config.SearchString = specParts[6];
            }

            return(Task.FromResult(config));
        }
Пример #16
0
    public async Task PassiveHealthChecksEnabled_IncompleteClientRequests_ProxyHealthIsUnaffected()
    {
        var destinationReached = false;

        var shouldThrow       = true;
        var requestStartedTcs = new TaskCompletionSource <byte>(TaskCreationOptions.RunContinuationsAsynchronously);

        var proxySendAsync = async(HttpRequestMessage request, CancellationToken ct) =>
        {
            requestStartedTcs.SetResult(0);

            if (shouldThrow)
            {
                await Task.Delay(-1, ct);

                throw new OperationCanceledException(ct);
            }
            else
            {
                return(new HttpResponseMessage((HttpStatusCode)418)
                {
                    Content = new StringContent("Hello world")
                });
            }
        };

        var test = new TestEnvironment(
            context =>
        {
            destinationReached = true;
            throw new InvalidOperationException();
        },
            proxyBuilder => proxyBuilder.Services.AddSingleton <IForwarderHttpClientFactory>(new MockHttpClientFactory(proxySendAsync)),
            proxyApp => { },
            configTransformer: (c, r) =>
        {
            c = c with
            {
                HealthCheck = new HealthCheckConfig
                {
                    Passive = new PassiveHealthCheckConfig
                    {
                        Enabled = true
                    }
                }
            };

            return(c, r);
        });

        await test.Invoke(async uri =>
        {
            using var client = new HttpClient();
            for (var i = 0; i < 42; i++)
            {
                using var cts = new CancellationTokenSource();
                _             = requestStartedTcs.Task.ContinueWith(_ => cts.Cancel());

                try
                {
                    await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, uri), cts.Token);
                    Assert.True(false);
                }
                catch { }

                requestStartedTcs = new TaskCompletionSource <byte>(TaskCreationOptions.RunContinuationsAsynchronously);
            }

            shouldThrow = false;

            using var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, uri));

            Assert.Equal(418, (int)response.StatusCode);
            Assert.Equal("Hello world", await response.Content.ReadAsStringAsync());
        });

        Assert.False(destinationReached);
    }
Пример #17
0
        public IRequest Marshall(CreateHealthCheckRequest createHealthCheckRequest)
        {
            IRequest request = new DefaultRequest(createHealthCheckRequest, "AmazonRoute53");



            request.HttpMethod = "POST";
            string uriResourcePath = "/2013-04-01/healthcheck";

            if (uriResourcePath.Contains("?"))
            {
                int    queryIndex  = uriResourcePath.IndexOf("?", StringComparison.OrdinalIgnoreCase);
                string queryString = uriResourcePath.Substring(queryIndex + 1);

                uriResourcePath = uriResourcePath.Substring(0, queryIndex);


                foreach (string s in queryString.Split('&', ';'))
                {
                    string[] nameValuePair = s.Split('=');
                    if (nameValuePair.Length == 2 && nameValuePair[1].Length > 0)
                    {
                        request.Parameters.Add(nameValuePair[0], nameValuePair[1]);
                    }
                    else
                    {
                        request.Parameters.Add(nameValuePair[0], null);
                    }
                }
            }

            request.ResourcePath = uriResourcePath;


            StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);

            using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings()
            {
                Encoding = System.Text.Encoding.UTF8, OmitXmlDeclaration = true
            }))
            {
                xmlWriter.WriteStartElement("CreateHealthCheckRequest", "https://route53.amazonaws.com/doc/2013-04-01/");
                if (createHealthCheckRequest.IsSetCallerReference())
                {
                    xmlWriter.WriteElementString("CallerReference", "https://route53.amazonaws.com/doc/2013-04-01/", createHealthCheckRequest.CallerReference.ToString(CultureInfo.InvariantCulture));
                }
                if (createHealthCheckRequest != null)
                {
                    HealthCheckConfig healthCheckConfigHealthCheckConfig = createHealthCheckRequest.HealthCheckConfig;
                    if (healthCheckConfigHealthCheckConfig != null)
                    {
                        xmlWriter.WriteStartElement("HealthCheckConfig", "https://route53.amazonaws.com/doc/2013-04-01/");
                        if (healthCheckConfigHealthCheckConfig.IsSetIPAddress())
                        {
                            xmlWriter.WriteElementString("IPAddress", "https://route53.amazonaws.com/doc/2013-04-01/", healthCheckConfigHealthCheckConfig.IPAddress.ToString(CultureInfo.InvariantCulture));
                        }
                        if (healthCheckConfigHealthCheckConfig.IsSetPort())
                        {
                            xmlWriter.WriteElementString("Port", "https://route53.amazonaws.com/doc/2013-04-01/", healthCheckConfigHealthCheckConfig.Port.ToString(CultureInfo.InvariantCulture));
                        }
                        if (healthCheckConfigHealthCheckConfig.IsSetType())
                        {
                            xmlWriter.WriteElementString("Type", "https://route53.amazonaws.com/doc/2013-04-01/", healthCheckConfigHealthCheckConfig.Type.ToString(CultureInfo.InvariantCulture));
                        }
                        if (healthCheckConfigHealthCheckConfig.IsSetResourcePath())
                        {
                            xmlWriter.WriteElementString("ResourcePath", "https://route53.amazonaws.com/doc/2013-04-01/", healthCheckConfigHealthCheckConfig.ResourcePath.ToString(CultureInfo.InvariantCulture));
                        }
                        if (healthCheckConfigHealthCheckConfig.IsSetFullyQualifiedDomainName())
                        {
                            xmlWriter.WriteElementString("FullyQualifiedDomainName", "https://route53.amazonaws.com/doc/2013-04-01/", healthCheckConfigHealthCheckConfig.FullyQualifiedDomainName.ToString(CultureInfo.InvariantCulture));
                        }
                        if (healthCheckConfigHealthCheckConfig.IsSetSearchString())
                        {
                            xmlWriter.WriteElementString("SearchString", "https://route53.amazonaws.com/doc/2013-04-01/", healthCheckConfigHealthCheckConfig.SearchString.ToString(CultureInfo.InvariantCulture));
                        }
                        xmlWriter.WriteEndElement();
                    }
                }

                xmlWriter.WriteEndElement();
            }
            try
            {
                string content = stringWriter.ToString();
                request.Content = System.Text.Encoding.UTF8.GetBytes(content);
                request.Headers["Content-Type"] = "application/xml";
            }
            catch (EncoderFallbackException e)
            {
                throw new AmazonServiceException("Unable to marshall request to XML", e);
            }


            return(request);
        }
 public ExtendedHealthCheckService(ILogManager logManager, HealthCheckConfig config, INomisApiService nomisApiService)
     : base(logManager)
 {
     _nomisApiService = nomisApiService;
     _config          = config;
 }