public void ShouldFailoverOnThriftConnectionsUsingSniff()
		{
			var uris = new []
			{
				new Uri("http://INVALID_HOST"),
				new Uri("http://INVALID_HOST2"),
				new Uri("http://localhost:9500"),
			};
			var connectionPool = new SniffingConnectionPool(uris, randomizeOnStartup: false);
			var settings = new ConnectionSettings(connectionPool, ElasticsearchConfiguration.DefaultIndex)
				.SniffOnStartup()
				.ExposeRawResponse()
				.SetTimeout(2000);
			var client = new ElasticClient(settings, new ThriftConnection(settings));

			var results = client.Search<dynamic>(s => s.MatchAll());
			results.IsValid.Should().BeTrue("{0}", results.ConnectionStatus.ToString());
			results.ConnectionStatus.NumberOfRetries.Should().Be(0);
			var u = new Uri(results.ConnectionStatus.RequestUrl);
			u.Port.Should().Be(9500);

			results = client.Search<dynamic>(s => s.MatchAll());
			results.IsValid.Should().BeTrue("{0}", results.ConnectionStatus.ToString());
			results.ConnectionStatus.NumberOfRetries.Should().Be(0);
			u = new Uri(results.ConnectionStatus.RequestUrl);
			u.Port.Should().Be(9501);
		}
Exemple #2
0
 private static ElasticClient CreateElasticClient(IClientSettings settings)
 {
     var uris = settings.ConnectionPool.Select(a => new Uri(a));
     var connectionPool = new SniffingConnectionPool(uris);
     var connectionSettings = new ConnectionSettings(connectionPool,settings.DefaultIndex);
     if(settings.Authorization != null) connectionSettings.SetBasicAuthentication(settings.Authorization.Username, settings.Authorization.Password);
     return new ElasticClient(connectionSettings);
 }
Exemple #3
0
        public static void GetClient()
        {
            const string elUri = "http://localhost:9200/";
            //const string elUri = "http://191.238.179.97:9200/";

            var _node = new Uri(elUri);
            var connectionPool = new SniffingConnectionPool(new[] { _node });
            var _settings = new ConnectionSettings(_node).SetBasicAuthentication("aotuo", "123456");
            _client = new ElasticClient(_settings);
        }
 private void GetESclient()
 {
     const string elUri = "http://localhost:9200/";
     //const string elUri = "http://191.238.179.97:9200/";
     //var uri = ConfigurationManager.AppSettings["Local"];
     _node = new Uri(elUri);
     _connectionPool = new SniffingConnectionPool(new[] { _node });
     _settings = new ConnectionSettings(_connectionPool).SetBasicAuthentication("aotuo", "123456");
     _client = new ElasticClient(_settings);
 }
Exemple #5
0
 /// <summary>
 /// 获取Eastic连接
 /// </summary>
 /// <returns></returns>
 public static ElasticClient GetSearchClient()
 {
     var connectString = ConfigurationManager.AppSettings["ESPath"].ToString();
     var nodesStr = connectString.Split('|');
     var nodes = nodesStr.Select(s => new Uri(s)).ToList();
     var connectionPool = new SniffingConnectionPool(nodes);
     var settings = new ConnectionSettings(connectionPool);
     var client = new ElasticClient(settings);
     return client;
 }
Exemple #6
0
 /// <summary>
 /// 获取ES链接,nodeip可为多个,用'|'分割
 /// </summary>
 /// <param name="nodeip"></param>
 /// <returns></returns>
 public static ElasticClient Client(string nodeip)
 {
     var connectString = nodeip.ToString();
     var nodesStr = connectString.Split('|');
     var nodes = nodesStr.Select(s => new Uri(s)).ToList();
     var connectionPool = new SniffingConnectionPool(nodes);
     var settings = new ConnectionSettings(connectionPool);
     var client = new ElasticClient(settings);
     return client;
 }
		public void SniffingConnectionPoolPingThrowsException()
		{
			//ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, errors) => true;
			var nodes = new Uri[] { new Uri("https://localhost:9200") };
			var pool = new SniffingConnectionPool(nodes);
			var settings = new ConnectionSettings(pool)
				.SetBasicAuthentication("netuser", "admin")
				.SniffOnStartup();

			Assert.DoesNotThrow(() => new ElasticClient(settings));
		}
        public ConnectionSettings Get()
        {
            var pool = new SniffingConnectionPool(Url);

            var settings = new ConnectionSettings(pool);
            settings.ThrowOnElasticsearchServerExceptions();

            if (EnableTrace)
                settings.EnableTrace();

            return settings;
        }
		public void SniffCalledOnceAndEachEnpointPingedOnce()
		{
			using (var fake = new AutoFake(callsDoNothing: true))
			{
				//It's recommended to only have on instance of your connection pool
				//Be sure to register it as Singleton in your IOC
				var uris = new[] { new Uri("http://localhost:9200"), new Uri("http://localhost:9201") };
				var connectionPool = new SniffingConnectionPool(uris);
				var config = new ConnectionConfiguration(connectionPool)
					.SniffOnStartup();
				fake.Provide<IConnectionConfigurationValues>(config);

				var pingCall = FakeCalls.PingAtConnectionLevel(fake);
				pingCall.Returns(FakeResponse.Ok(config));
				var sniffCall = FakeCalls.Sniff(fake, config, uris);
				var getCall = FakeCalls.GetSyncCall(fake);
				getCall.Returns(FakeResponse.Ok(config));

				var transport1 = FakeCalls.ProvideRealTranportInstance(fake);
				var transport2 = FakeCalls.ProvideRealTranportInstance(fake);
				var transport3 = FakeCalls.ProvideRealTranportInstance(fake);
				var transport4 = FakeCalls.ProvideRealTranportInstance(fake);

				transport1.Should().NotBe(transport2);

				var client1 = new ElasticsearchClient(config, transport: transport1);
				client1.Info();
				client1.Info();
				client1.Info();
				client1.Info();
				var client2 = new ElasticsearchClient(config, transport: transport2); 
				client2.Info();
				client2.Info();
				client2.Info();
				client2.Info();
				var client3 = new ElasticsearchClient(config, transport: transport3); 
				client3.Info();
				client3.Info();
				client3.Info();
				client3.Info();
				var client4 = new ElasticsearchClient(config, transport: transport4); 
				client4.Info();
				client4.Info();
				client4.Info();
				client4.Info();

				sniffCall.MustHaveHappened(Repeated.Exactly.Once);
				//sniff validates first node, one new node should be pinged before usage.
				pingCall.MustHaveHappened(Repeated.Exactly.Once);
			}
		}
Exemple #10
0
		public static IElasticClient CreateInstance()
		{
			var nodes = new Uri []
			{
				new Uri("http://localhost:9200"),
				new Uri("http://localhost:9201"),
				new Uri("http://localhost:9202")
			};

			var connectionPool = new SniffingConnectionPool(nodes);

			var settings = new ConnectionSettings(connectionPool)
				.MapDefaultTypeNames(m => m.Add(typeof(Session), "session"))
				.MapDefaultTypeIndices(m => m.Add(typeof(Session), "codecampnyc"));

			return new ElasticClient(settings);
		}
		public void SniffIsCalledAfterItHasGoneOutOfDate()
		{
			using (var fake = new AutoFake())
			{
				var dateTimeProvider = fake.Resolve<IDateTimeProvider>();
				var nowCall = A.CallTo(()=>dateTimeProvider.Now());
				nowCall.ReturnsNextFromSequence(
					DateTime.UtcNow, //initial sniff time (set even if not sniff_on_startup
					DateTime.UtcNow, //info call 1
					DateTime.UtcNow, //info call 2
					DateTime.UtcNow.AddMinutes(10), //info call 3
					DateTime.UtcNow.AddMinutes(10), //set now after sniff 3
					DateTime.UtcNow.AddMinutes(20), //info call 4
					DateTime.UtcNow.AddMinutes(20), //set now after sniff 4
					DateTime.UtcNow.AddMinutes(22) //info call 5
				);
				var uris = new[] { new Uri("http://localhost:9200") };
				var connectionPool = new SniffingConnectionPool(uris);
				var config = new ConnectionConfiguration(connectionPool)
					.SniffLifeSpan(TimeSpan.FromMinutes(4));
				fake.Provide<IConnectionConfigurationValues>(config);
				var transport = FakeCalls.ProvideDefaultTransport(fake, dateTimeProvider);
				var connection = fake.Resolve<IConnection>();
				var sniffCall = FakeCalls.Sniff(fake, config, uris);
				
				var pingCall = FakeCalls.PingAtConnectionLevel(fake);
				pingCall.Returns(FakeResponse.Ok(config));

				var getCall = FakeCalls.GetSyncCall(fake);
				getCall.Returns(FakeResponse.Ok(config));

				var client1 = fake.Resolve<ElasticsearchClient>();
				var result = client1.Info(); //info call 1
				result = client1.Info(); //info call 2
				result = client1.Info(); //info call 3
				result = client1.Info(); //info call 4
				result = client1.Info(); //info call 5

				sniffCall.MustHaveHappened(Repeated.Exactly.Twice);
				nowCall.MustHaveHappened(Repeated.Exactly.Times(8));
			}
		}
 public IHttpActionResult CheckId(string id, string pass)
 {
     try
     {
         const string elUri = "http://localhost:9200/";
         //var uri = ConfigurationManager.AppSettings["Local"];
         _node = new Uri(elUri);
         var connectionPool = new SniffingConnectionPool(new[] { _node });
         _settings = new ConnectionSettings(_node).SetBasicAuthentication(id, pass);
         _client = new ElasticClient(_settings);
         //if (_client.RootNodeInfo().Status != 200) return BadRequest("error identity");
         if (id != "aotuo" || pass != "123456") return BadRequest("error identity"); //temporary check
         var res = EsCipher.Encrypt("binggo", "Elastic");
         return Ok(res);
     }
     catch (Exception e)
     {
         return BadRequest("Error " + e.Message);
     }
     // System.Web.Http.Results
 }
		public void SniffOnStartupCallsSniffOnlyOnce()
		{
			using (var fake = new AutoFake(callsDoNothing: true))
			{
				//It's recommended to only have on instance of your connection pool
				//Be sure to register it as Singleton in your IOC
				var uris = new[] { new Uri("http://localhost:9200") };
				var connectionPool = new SniffingConnectionPool(uris);
				var config = new ConnectionConfiguration(connectionPool)
					.DisablePing()
					.SniffOnStartup();
				fake.Provide<IConnectionConfigurationValues>(config);
				var sniffCall = FakeCalls.Sniff(fake, config, uris);
				var transport = FakeCalls.ProvideDefaultTransport(fake);
				var client1 = new ElasticsearchClient(config, transport: transport); 
				var client2 = new ElasticsearchClient(config, transport: transport); 
				var client3 = new ElasticsearchClient(config, transport: transport); 
				var client4 = new ElasticsearchClient(config, transport: transport); 

				sniffCall.MustHaveHappened(Repeated.Exactly.Once);
			}
		}
		public void ShouldNotThrowAndNotRetrySniffOnConnectionFault403()
		{
			using (var fake = new AutoFake(callsDoNothing: true))
			{
				var uris = new[]
				{
					new Uri("http://localhost:9200"),
					new Uri("http://localhost:9201"),
					new Uri("http://localhost:9202")
				};
				var connectionPool = new SniffingConnectionPool(uris, randomizeOnStartup: false);
				var config = new ConnectionConfiguration(connectionPool)
					.SniffOnConnectionFault();

				fake.Provide<IConnectionConfigurationValues>(config);
				FakeCalls.ProvideDefaultTransport(fake);

				var pingCall = FakeCalls.PingAtConnectionLevel(fake);
				pingCall.Returns(FakeResponse.Ok(config));

				var sniffCall = FakeCalls.Sniff(fake);
				var seenPorts = new List<int>();
				sniffCall.ReturnsLazily((Uri u, IRequestConfiguration c) =>
				{
					seenPorts.Add(u.Port);
					return FakeResponse.Any(config, 403);
				});

				var getCall = FakeCalls.GetSyncCall(fake);
				getCall.Returns(FakeResponse.Bad(config));

				var client = fake.Resolve<ElasticsearchClient>();

				Assert.DoesNotThrow(() => client.Info());
				sniffCall.MustHaveHappened(Repeated.Exactly.Once);
				getCall.MustHaveHappened(Repeated.Exactly.Once);
			}
		}
		public void ShouldThrowAndNotRetrySniffOnStartup403()
		{
			using (var fake = new AutoFake(callsDoNothing: true))
			{
				var uris = new[]
				{
					new Uri("http://localhost:9200"),
					new Uri("http://localhost:9201"),
					new Uri("http://localhost:9202")
				};
				var connectionPool = new SniffingConnectionPool(uris, randomizeOnStartup: false);
				var config = new ConnectionConfiguration(connectionPool)
					.SniffOnStartup();

				var pingCall = FakeCalls.PingAtConnectionLevel(fake);
				pingCall.Returns(FakeResponse.Ok(config));

				var sniffCall = FakeCalls.Sniff(fake);
				var seenPorts = new List<int>();
				sniffCall.ReturnsLazily((Uri u, IRequestConfiguration c) =>
				{
					seenPorts.Add(u.Port);
					return FakeResponse.Any(config, 403);
				});

				var getCall = FakeCalls.GetSyncCall(fake);
				getCall.Returns(FakeResponse.Bad(config));

				fake.Provide<IConnectionConfigurationValues>(config);

				var e = Assert.Throws<ElasticsearchAuthorizationException>(() => FakeCalls.ProvideRealTranportInstance(fake));

				sniffCall.MustHaveHappened(Repeated.Exactly.Once);
				getCall.MustNotHaveHappened();
			}
		}
        public void SniffOnConnectionFaultCausesSniffOn503()
        {
            using (var fake = new AutoFake())
            {
                var dateTimeProvider = fake.Resolve<IDateTimeProvider>();
                var nowCall = A.CallTo(()=>dateTimeProvider.Now());
                nowCall.Returns(DateTime.UtcNow);

                var connectionPool = new SniffingConnectionPool(new[] { new Uri("http://localhost:9200") });
                var config = new ConnectionConfiguration(connectionPool)
                    .SniffOnConnectionFault();
                fake.Provide<IConnectionConfigurationValues>(config);
                fake.Provide<ITransport>(fake.Resolve<Transport>());
                var connection = fake.Resolve<IConnection>();
                var sniffCall = A.CallTo(() => connection.Sniff(A<Uri>._));
                var getCall = A.CallTo(() => connection.GetSync(A<Uri>._));
                getCall.ReturnsNextFromSequence(
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 1
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 2
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 3
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 4
                    ElasticsearchResponse.Create(config, 503, "GET", "/", null, null) //info 5
                );

                var client1 = fake.Resolve<ElasticsearchClient>();
                client1.Info(); //info call 1
                client1.Info(); //info call 2
                client1.Info(); //info call 3
                client1.Info(); //info call 4
                Assert.Throws<OutOfNodesException>(()=>client1.Info()); //info call 5

                sniffCall.MustHaveHappened(Repeated.Exactly.Once);
                nowCall.MustHaveHappened(Repeated.Exactly.Times(7));

                //var nowCall = A.CallTo(() => fake.Resolve<IDateTimeProvider>().Sniff(A<Uri>._, A<int>._));
            }
        }
Exemple #17
0
        private static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=sarasa;User Id=sa;Password=1234;Connect Timeout=120"))
            {
                SqlCommand cmd = new SqlCommand(@"
                    SELECT * FROM notes WHERE note.language = 'es'"
                    , conn);

                List<SyncArrayConfiguration> arrayConfig = new List<SyncArrayConfiguration>()
                {
                    new SyncArrayConfiguration
                    {
                        SqlCommand = new SqlCommand(@"
                            SELECT id_object AS '_id', id, description, languageId
                            FROM dbo.Tags
                            WHERE languageId = 'es'"
                            , conn),
                        AttributeName = "tags",
                        ParentIdColumn = "_id"
                    },
                    new SyncArrayConfiguration
                    {
                        SqlCommand = new SqlCommand(@"
                            SELECT id_object AS '_id', id, description, xmlData, languageId
                            FROM dbo.Categories
                            WHERE languageId = 'es'"
                            , conn),
                        AttributeName = "categories",
                        ParentIdColumn = "_id",
                        XmlFields = new string[] { "xmlData" }
                    }
                };

                SyncDeleteConfiguration deleteCmd = new SyncDeleteConfiguration
                {
                    SqlCommand = new SqlCommand(@"
                        SELECT id_object AS '_id', createdOn
                        FROM dbo.DeleteLog
                        WHERE id_language = 'es'"
                        , conn),
                    ColumnsToCompareWithLastSyncDate = new string[] { "[createdOn]" },
                };

                var nodes =
                    new Uri[] {
                        new Uri("http://localhost:9200"),
                        new Uri("http://localhost:9201")
                    };
                var connectionPool = new SniffingConnectionPool(nodes);
                var esConfig = new ConnectionConfiguration(connectionPool).UsePrettyResponses();

                var syncConfig = new SyncConfiguration()
                {
                    SqlConnection = conn,
                    SqlCommand = cmd,
                    ArraysConfiguration = arrayConfig,
                    FilterArrayByParentsIds = true,
                    ColumnsToCompareWithLastSyncDate = new string[] { "[lastupdate]" },
                    DeleteConfiguration = deleteCmd,
                    ElasticSearchConfiguration = esConfig,
                    BulkSize = 500,
                    _Index = "sarasa",
                    _Type = "notes"
                };

                var sync = new Sync(syncConfig);

                try
                {
                    var response = sync.Exec();
                    if (response.BulkResponses.Any())
                    {
                        foreach (var bulkResponse in response.BulkResponses)
                        {
                            Console.WriteLine("success: " + bulkResponse.Success);
                            Console.WriteLine("http status code: " + bulkResponse.HttpStatusCode);
                            Console.WriteLine("affected documents: " + bulkResponse.AffectedDocuments);
                            Console.WriteLine("started on: " + bulkResponse.StartedOn);
                            Console.WriteLine("bulk duration: " + bulkResponse.Duration + "ms");
                            if (!response.Success)
                                Console.WriteLine("es original exception: " + bulkResponse.ESexception);
                            Console.WriteLine("\n");
                        }
                        Console.WriteLine("\nbulk avg duration: " + response.BulkResponses.Average(x => x.Duration) + "ms");
                        Console.WriteLine("\n");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("an error has occurred: " + ex.Message);
                }
                finally
                {
                    Console.WriteLine("Execution has completed. Press any key to continue...");
                    Console.ReadKey();
                }
            }
        }
        public void SniffOnConnectionFaultCausesSniffOn503()
        {
            using (var fake = new AutoFake())
            {
                var dateTimeProvider = fake.Resolve<IDateTimeProvider>();
                var nowCall = A.CallTo(()=>dateTimeProvider.Now());
                nowCall.Returns(DateTime.UtcNow);
                var nodes = new[] { new Uri("http://localhost:9200") };
                var connectionPool = new SniffingConnectionPool(nodes);
                var config = new ConnectionConfiguration(connectionPool)
                    .SniffOnConnectionFault();
                fake.Provide<IConnectionConfigurationValues>(config);
                var transport = FakeCalls.ProvideDefaultTransport(fake, dateTimeProvider);
                var connection = fake.Resolve<IConnection>();
                var sniffCall = FakeCalls.Sniff(fake, config, nodes);
                var getCall = FakeCalls.GetSyncCall(fake);
                getCall.ReturnsNextFromSequence(

                    FakeResponse.Ok(config), //info 1
                    FakeResponse.Ok(config), //info 2
                    FakeResponse.Ok(config), //info 3
                    FakeResponse.Ok(config), //info 4
                    FakeResponse.Bad(config) //info 5
                );

                var client1 = fake.Resolve<ElasticsearchClient>();
                client1.Info(); //info call 1
                client1.Info(); //info call 2
                client1.Info(); //info call 3
                client1.Info(); //info call 4
                Assert.Throws<MaxRetryException>(()=>client1.Info()); //info call 5

                sniffCall.MustHaveHappened(Repeated.Exactly.Once);
                nowCall.MustHaveHappened(Repeated.Exactly.Times(7));

            }
        }
        public void HostsReturnedBySniffAreVisited()
        {
            using (var fake = new AutoFake())
            {
                var dateTimeProvider = fake.Resolve<IDateTimeProvider>();
                var nowCall = A.CallTo(()=>dateTimeProvider.Now());
                nowCall.Returns(DateTime.UtcNow);

                var connectionPool = new SniffingConnectionPool(new[]
                {
                    new Uri("http://localhost:9200"),
                    new Uri("http://localhost:9201")
                }, randomizeOnStartup: false);
                var config = new ConnectionConfiguration(connectionPool)
                    .SniffOnConnectionFault();
                fake.Provide<IConnectionConfigurationValues>(config);
                FakeCalls.ProvideDefaultTransport(fake);
                FakeCalls.PingAtConnectionLevel(fake)
                    .Returns(FakeResponse.Ok(config));

                var sniffCall = FakeCalls.Sniff(fake, config, new List<Uri>()
                {
                    new Uri("http://localhost:9204"),
                    new Uri("http://localhost:9203"),
                    new Uri("http://localhost:9202"),
                    new Uri("http://localhost:9201")
                });

                var connection = fake.Resolve<IConnection>();
                var seenNodes = new List<Uri>();
                //var getCall =  FakeResponse.GetSyncCall(fake);
                var getCall = A.CallTo(() => connection.GetSync(
                    A<Uri>.That.Not.Matches(u=>u.AbsolutePath.StartsWith("/_nodes")),
                    A<IRequestConfiguration>._));
                getCall.ReturnsNextFromSequence(
                    FakeResponse.Ok(config), //info 1
                    FakeResponse.Bad(config), //info 2
                    FakeResponse.Ok(config), //info 2 retry
                    FakeResponse.Ok(config), //info 3
                    FakeResponse.Ok(config), //info 4
                    FakeResponse.Ok(config), //info 5
                    FakeResponse.Ok(config), //info 6
                    FakeResponse.Ok(config), //info 7
                    FakeResponse.Ok(config), //info 8
                    FakeResponse.Ok(config) //info 9
                );
                getCall.Invokes((Uri u, IRequestConnectionConfiguration o) => seenNodes.Add(u));

                var client1 = fake.Resolve<ElasticsearchClient>();
                client1.Info(); //info call 1
                client1.Info(); //info call 2
                client1.Info(); //info call 3
                client1.Info(); //info call 4
                client1.Info(); //info call 5
                client1.Info(); //info call 6
                client1.Info(); //info call 7
                client1.Info(); //info call 8
                client1.Info(); //info call 9

                sniffCall.MustHaveHappened(Repeated.Exactly.Once);
                seenNodes.Should().NotBeEmpty().And.HaveCount(10);
                seenNodes[0].Port.Should().Be(9200);
                seenNodes[1].Port.Should().Be(9201);
                //after sniff
                seenNodes[2].Port.Should().Be(9202, string.Join(",", seenNodes.Select(n=>n.Port)));
                seenNodes[3].Port.Should().Be(9204);
                seenNodes[4].Port.Should().Be(9203);
                seenNodes[5].Port.Should().Be(9202);
                seenNodes[6].Port.Should().Be(9201);
            }
        }
        public void HostsReturnedBySniffAreVisited()
        {
            using (var fake = new AutoFake())
            {
                var dateTimeProvider = fake.Resolve<IDateTimeProvider>();
                var nowCall = A.CallTo(()=>dateTimeProvider.Now());
                nowCall.Returns(DateTime.UtcNow);

                var connectionPool = new SniffingConnectionPool(new[]
                {
                    new Uri("http://localhost:9200"),
                    new Uri("http://localhost:9201")
                }, randomizeOnStartup: false);
                var config = new ConnectionConfiguration(connectionPool)
                    .SniffOnConnectionFault();
                fake.Provide<IConnectionConfigurationValues>(config);
                fake.Provide<ITransport>(fake.Resolve<Transport>());
                var connection = fake.Resolve<IConnection>();
                var sniffCall = A.CallTo(() => connection.Sniff(A<Uri>._));
                sniffCall.Returns(new List<Uri>()
                {
                    new Uri("http://localhost:9204"),
                    new Uri("http://localhost:9203"),
                    new Uri("http://localhost:9202"),
                    new Uri("http://localhost:9201")
                });

                var seenNodes = new List<Uri>();
                var getCall = A.CallTo(() => connection.GetSync(A<Uri>._));
                getCall.ReturnsNextFromSequence(
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 1
                    ElasticsearchResponse.Create(config, 503, "GET", "/", null, null), //info 2
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 2 retry
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 3
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 4
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 5
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 6
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 7
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null), //info 8
                    ElasticsearchResponse.Create(config, 200, "GET", "/", null, null) //info 9
                );
                getCall.Invokes((Uri u) => seenNodes.Add(u));

                var client1 = fake.Resolve<ElasticsearchClient>();
                client1.Info(); //info call 1
                client1.Info(); //info call 2
                client1.Info(); //info call 3
                client1.Info(); //info call 4
                client1.Info(); //info call 5
                client1.Info(); //info call 6
                client1.Info(); //info call 7
                client1.Info(); //info call 8
                client1.Info(); //info call 9

                sniffCall.MustHaveHappened(Repeated.Exactly.Once);
                seenNodes.Should().NotBeEmpty().And.HaveCount(10);
                seenNodes[0].Port.Should().Be(9200);
                seenNodes[1].Port.Should().Be(9201);
                //after sniff
                seenNodes[2].Port.Should().Be(9202);
                seenNodes[3].Port.Should().Be(9204, string.Join(",", seenNodes.Select(n=>n.Port)));
                seenNodes[4].Port.Should().Be(9203);
                seenNodes[5].Port.Should().Be(9202);
                seenNodes[6].Port.Should().Be(9201);

                //var nowCall = A.CallTo(() => fake.Resolve<IDateTimeProvider>().Sniff(A<Uri>._, A<int>._));
            }
        }
        public void SniffIsCalledAfterItHasGoneOutOfDate_NotWhenItSeesA503()
        {
            using (var fake = new AutoFake())
            {
                var dateTimeProvider = fake.Resolve<IDateTimeProvider>();
                var nowCall = A.CallTo(()=>dateTimeProvider.Now());
                nowCall.ReturnsNextFromSequence(
                    DateTime.UtcNow, //initial sniff time (set even if not sniff_on_startup
                    DateTime.UtcNow, //info call 1
                    DateTime.UtcNow, //info call 2
                    DateTime.UtcNow.AddMinutes(10), //info call 3
                    DateTime.UtcNow.AddMinutes(10), //set now after sniff 3
                    DateTime.UtcNow.AddMinutes(10), //info call 4
                    DateTime.UtcNow.AddMinutes(12) //info call 5
                );
                var uris = new[] { new Uri("http://localhost:9200") };
                var connectionPool = new SniffingConnectionPool(uris);
                var config = new ConnectionConfiguration(connectionPool)
                    .SniffLifeSpan(TimeSpan.FromMinutes(4))
                    .ExposeRawResponse();
                fake.Provide<IConnectionConfigurationValues>(config);
                var transport = FakeCalls.ProvideDefaultTransport(fake, dateTimeProvider);
                var sniffCall = FakeCalls.Sniff(fake, config, uris);
                var getCall = FakeCalls.GetSyncCall(fake);
                getCall.ReturnsNextFromSequence(
                    FakeResponse.Ok(config), //info 1
                    FakeResponse.Ok(config), //info 2
                    FakeResponse.Ok(config), //info 3
                    FakeResponse.Ok(config), //sniff
                    FakeResponse.Ok(config), //info 4
                    FakeResponse.Bad(config) //info 5
                );

                var client1 = fake.Resolve<ElasticsearchClient>();
                client1.Info(); //info call 1
                client1.Info(); //info call 2
                client1.Info(); //info call 3
                client1.Info(); //info call 4
                client1.Info(); //info call 5

                sniffCall.MustHaveHappened(Repeated.Exactly.Once);
                nowCall.MustHaveHappened(Repeated.Exactly.Times(7));

                //var nowCall = A.CallTo(() => fake.Resolve<IDateTimeProvider>().Sniff(A<Uri>._, A<int>._));
            }
        }
        public void SniffIsCalledAfterItHasGoneOutOfDate()
        {
            using (var fake = new AutoFake())
            {
                var dateTimeProvider = fake.Resolve<IDateTimeProvider>();
                var nowCall = A.CallTo(()=>dateTimeProvider.Now());
                nowCall.ReturnsNextFromSequence(
                    DateTime.UtcNow, //initial sniff time (set even if not sniff_on_startup
                    DateTime.UtcNow, //info call 1
                    DateTime.UtcNow, //info call 2
                    DateTime.UtcNow.AddMinutes(10), //info call 3
                    DateTime.UtcNow.AddMinutes(10), //set now after sniff 3
                    DateTime.UtcNow.AddMinutes(20), //info call 4
                    DateTime.UtcNow.AddMinutes(20), //set now after sniff 4
                    DateTime.UtcNow.AddMinutes(22) //info call 5
                );
                var connectionPool = new SniffingConnectionPool(new[] { new Uri("http://localhost:9200") });
                var config = new ConnectionConfiguration(connectionPool)
                    .SniffLifeSpan(TimeSpan.FromMinutes(4));
                fake.Provide<IConnectionConfigurationValues>(config);
                fake.Provide<ITransport>(fake.Resolve<Transport>());
                var connection = fake.Resolve<IConnection>();
                var sniffCall = A.CallTo(() => connection.Sniff(A<Uri>._));
                var getCall = A.CallTo(() => connection.GetSync(A<Uri>._));
                getCall.Returns(ElasticsearchResponse.Create(config, 200, "GET", "/", null, null));

                var client1 = fake.Resolve<ElasticsearchClient>();
                client1.Info(); //info call 1
                client1.Info(); //info call 2
                client1.Info(); //info call 3
                client1.Info(); //info call 4
                client1.Info(); //info call 5

                sniffCall.MustHaveHappened(Repeated.Exactly.Twice);
                nowCall.MustHaveHappened(Repeated.Exactly.Times(8));

                //var nowCall = A.CallTo(() => fake.Resolve<IDateTimeProvider>().Sniff(A<Uri>._, A<int>._));
            }
        }
		public void ShouldRetryOnSniffConnectionException_Async()
		{
			using (var fake = new AutoFake(callsDoNothing: true))
			{	
				var uris = new[]
				{
					new Uri("http://localhost:9200"),
					new Uri("http://localhost:9201"),
					new Uri("http://localhost:9202")
				};
				var connectionPool = new SniffingConnectionPool(uris, randomizeOnStartup: false);
				var config = new ConnectionConfiguration(connectionPool)
					.SniffOnConnectionFault();
				
				fake.Provide<IConnectionConfigurationValues>(config);

				var pingAsyncCall = FakeCalls.PingAtConnectionLevelAsync(fake);
				pingAsyncCall.Returns(FakeResponse.OkAsync(config));

				//sniffing is always synchronous and in turn will issue synchronous pings
				var pingCall = FakeCalls.PingAtConnectionLevel(fake);
				pingCall.Returns(FakeResponse.Ok(config));

				var sniffCall = FakeCalls.Sniff(fake);
				var seenPorts = new List<int>();
				sniffCall.ReturnsLazily((Uri u, IRequestConfiguration c) =>
				{
					seenPorts.Add(u.Port);
					throw new Exception("Something bad happened");
				});

				var getCall = FakeCalls.GetCall(fake);
				getCall.Returns(FakeResponse.BadAsync(config));

				FakeCalls.ProvideDefaultTransport(fake);
				
				var client = fake.Resolve<ElasticsearchClient>();

				var e = Assert.Throws<MaxRetryException>(async () => await client.NodesHotThreadsAsync("nodex"));

				//all nodes must be tried to sniff for more information
				sniffCall.MustHaveHappened(Repeated.Exactly.Times(uris.Count()));
				//make sure we only saw one call to hot threads (the one that failed initially)
				getCall.MustHaveHappened(Repeated.Exactly.Once);
				
				//make sure the sniffs actually happened on all the individual nodes
				seenPorts.ShouldAllBeEquivalentTo(uris.Select(u=>u.Port));
				e.InnerException.Message.Should().Contain("Sniffing known nodes");
			}
		}
		public void ShouldRetryOnSniffConnectionException()
		{
			using (var fake = new AutoFake(callsDoNothing: true))
			{	
				var uris = new[]
				{
					new Uri("http://localhost:9200"),
					new Uri("http://localhost:9201")
				};
				var connectionPool = new SniffingConnectionPool(uris, randomizeOnStartup: false);
				var config = new ConnectionConfiguration(connectionPool)
					.SniffOnConnectionFault();
				
				fake.Provide<IConnectionConfigurationValues>(config);
				FakeCalls.ProvideDefaultTransport(fake);

				var pingCall = FakeCalls.PingAtConnectionLevel(fake);
				pingCall.Returns(FakeResponse.Ok(config));

				var sniffCall = FakeCalls.Sniff(fake);
				var seenPorts = new List<int>();
				sniffCall.ReturnsLazily((Uri u, IRequestConfiguration c) =>
				{
					seenPorts.Add(u.Port);
					throw new Exception("Something bad happened");
				});

				var getCall = FakeCalls.GetSyncCall(fake);
				getCall.Returns(FakeResponse.Bad(config));

				var client = fake.Resolve<ElasticsearchClient>();

				var e = Assert.Throws<MaxRetryException>(() => client.Info());
				sniffCall.MustHaveHappened(Repeated.Exactly.Times(uris.Count()));
				getCall.MustHaveHappened(Repeated.Exactly.Once);
				
				//make sure that if a ping throws an exception it wont
				//keep retrying to ping the same node but failover to the next
				seenPorts.ShouldAllBeEquivalentTo(uris.Select(u=>u.Port));

				var sniffException = e.InnerException as SniffException;
				sniffException.Should().NotBeNull();
			}
		}
        public void SniffOnStartupCallsSniffOnlyOnce()
        {
            using (var fake = new AutoFake(callsDoNothing: true))
            {
                //It's recommended to only have on instance of your connection pool
                //Be sure to register it as Singleton in your IOC
                var connectionPool = new SniffingConnectionPool(new[] { new Uri("http://localhost:9200") });
                var config = new ConnectionConfiguration(connectionPool)
                    .SniffOnStartup();
                fake.Provide<IConnectionConfigurationValues>(config);
                var param = new TypedParameter(typeof(IDateTimeProvider), null);
                fake.Provide<ITransport, Transport>(param);
                var connection = fake.Resolve<IConnection>();
                var sniffCall = A.CallTo(() => connection.Sniff(A<Uri>._));
                var client1 = fake.Resolve<ElasticsearchClient>();
                var client2 = fake.Resolve<ElasticsearchClient>();
                var client3 = fake.Resolve<ElasticsearchClient>();
                var client4 = fake.Resolve<ElasticsearchClient>();

                sniffCall.MustHaveHappened(Repeated.Exactly.Once);
            }
        }
		public void ShouldThrowAndNotRetrySniffInformationIsTooOld403_Async()
		{
			using (var fake = new AutoFake(callsDoNothing: true))
			{
				var uris = new[]
				{
					new Uri("http://localhost:9200"),
					new Uri("http://localhost:9201"),
					new Uri("http://localhost:9202")
				};
				var connectionPool = new SniffingConnectionPool(uris, randomizeOnStartup: false);
				var config = new ConnectionConfiguration(connectionPool)
					.SniffLifeSpan(new TimeSpan(1))
					.ThrowOnElasticsearchServerExceptions();

				fake.Provide<IConnectionConfigurationValues>(config);
				FakeCalls.ProvideDefaultTransport(fake);

				var pingAsyncCall = FakeCalls.PingAtConnectionLevelAsync(fake);
				pingAsyncCall.Returns(FakeResponse.OkAsync(config));

				var pingCall = FakeCalls.PingAtConnectionLevel(fake);
				pingCall.Returns(FakeResponse.Ok(config));

				var sniffCall = FakeCalls.Sniff(fake);
				var seenPorts = new List<int>();
				sniffCall.ReturnsLazily((Uri u, IRequestConfiguration c) =>
				{
					seenPorts.Add(u.Port);
					return FakeResponse.Any(config, 403);
				});

				var getCall = FakeCalls.GetCall(fake);
				getCall.Returns(FakeResponse.BadAsync(config));

				var client = fake.Resolve<ElasticsearchClient>();

				var e = Assert.Throws<ElasticsearchServerException>(async () => await client.InfoAsync());
				sniffCall.MustHaveHappened(Repeated.Exactly.Once);
				getCall.MustNotHaveHappened();
			}
		}