예제 #1
0
        public void Client_DefaultConfig_env()
        {
            const string addr = "1.2.3.4:5678";
            const string token = "abcd1234";
            const string auth = "username:password";
            Environment.SetEnvironmentVariable("CONSUL_HTTP_ADDR", addr);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_TOKEN", token);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_AUTH", auth);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_SSL", "1");
            Environment.SetEnvironmentVariable("CONSUL_HTTP_SSL_VERIFY", "0");

            var config = new ConsulClientConfiguration();

            Assert.Equal(addr, string.Format("{0}:{1}", config.Address.Host, config.Address.Port));
            Assert.Equal(token, config.Token);
            Assert.NotNull(config.HttpAuth);
            Assert.Equal("username", config.HttpAuth.UserName);
            Assert.Equal("password", config.HttpAuth.Password);
            Assert.Equal("https", config.Address.Scheme);
            Assert.True((config.Handler as WebRequestHandler).ServerCertificateValidationCallback(null, null, null,
                SslPolicyErrors.RemoteCertificateChainErrors));

            Environment.SetEnvironmentVariable("CONSUL_HTTP_ADDR", string.Empty);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_TOKEN", string.Empty);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_AUTH", string.Empty);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_SSL", string.Empty);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_SSL_VERIFY", string.Empty);
            ServicePointManager.ServerCertificateValidationCallback = null;

            var client = new ConsulClient(config);

            Assert.NotNull(client);
        }
예제 #2
0
 public async Task Client_SetQueryOptions()
 {
     var client = new ConsulClient();
     var opts = new QueryOptions()
     {
         Datacenter = "foo",
         Consistency = ConsistencyMode.Consistent,
         WaitIndex = 1000,
         WaitTime = new TimeSpan(0, 0, 100),
         Token = "12345"
     };
     var request = client.Get<KVPair>("/v1/kv/foo", opts);
     try
     {
         await request.Execute();
     }
     catch (Exception)
     {
         // ignored
     }
     Assert.Equal("foo", request.Params["dc"]);
     Assert.True(request.Params.ContainsKey("consistent"));
     Assert.Equal("1000", request.Params["index"]);
     Assert.Equal("1m40s", request.Params["wait"]);
     Assert.Equal("12345", request.Params["token"]);
 }
예제 #3
0
        public async Task Agent_Services_CheckPassing()
        {
            var client = new ConsulClient();
            var registration = new AgentServiceRegistration()
            {
                Name = "foo",
                Tags = new[] { "bar", "baz" },
                Port = 8000,
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15),
                    Status = CheckStatus.Passing
                }
            };

            await client.Agent.ServiceRegister(registration);

            var services = await client.Agent.Services();
            Assert.True(services.Response.ContainsKey("foo"));

            var checks = await client.Agent.Checks();
            Assert.True(checks.Response.ContainsKey("service:foo"));

            Assert.Equal(CheckStatus.Passing, checks.Response["service:foo"].Status);

            await client.Agent.ServiceDeregister("foo");
        }
예제 #4
0
        public async Task ACL_CreateDestroy()
        {
            Skip.If(string.IsNullOrEmpty(ConsulRoot));

            var client = new ConsulClient(new ConsulClientConfiguration() { Token = ConsulRoot });
            var aclEntry = new ACLEntry()
            {
                Name = "API Test",
                Type = ACLType.Client,
                Rules = "key \"\" { policy = \"deny\" }"
            };
            var res = await client.ACL.Create(aclEntry);
            var id = res.Response;

            Assert.NotEqual(0, res.RequestTime.TotalMilliseconds);
            Assert.False(string.IsNullOrEmpty(res.Response));

            var aclEntry2 = await client.ACL.Info(id);

            Assert.NotNull(aclEntry2.Response);
            Assert.Equal(aclEntry2.Response.Name, aclEntry.Name);
            Assert.Equal(aclEntry2.Response.Type, aclEntry.Type);
            Assert.Equal(aclEntry2.Response.Rules, aclEntry.Rules);

            Assert.True((await client.ACL.Destroy(id)).Response);
        }
예제 #5
0
        public async Task Catalog_Datacenters()
        {
            var client = new ConsulClient();
            var datacenterList = await client.Catalog.Datacenters();

            Assert.NotEqual(0, datacenterList.Response.Length);
        }
예제 #6
0
        public async Task Health_Checks()
        {
            var client = new ConsulClient();

            var registration = new AgentServiceRegistration()
            {
                Name = "foo",
                Tags = new[] { "bar", "baz" },
                Port = 8000,
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };
            try
            {
                await client.Agent.ServiceRegister(registration);
                var checks = await client.Health.Checks("foo");
                Assert.NotEqual((ulong)0, checks.LastIndex);
                Assert.NotEqual(0, checks.Response.Length);
            }
            finally
            {
                await client.Agent.ServiceDeregister("foo");
            }
        }
예제 #7
0
        public async Task Session_CreateRenewDestroyRenew()
        {
            var client = new ConsulClient();
            var sessionRequest = await client.Session.Create(new SessionEntry() { TTL = TimeSpan.FromSeconds(10) });

            var id = sessionRequest.Response;
            Assert.NotEqual(TimeSpan.Zero, sessionRequest.RequestTime);
            Assert.False(string.IsNullOrEmpty(sessionRequest.Response));

            var renewRequest = await client.Session.Renew(id);
            Assert.NotEqual(TimeSpan.Zero, renewRequest.RequestTime);
            Assert.NotNull(renewRequest.Response.ID);
            Assert.Equal(sessionRequest.Response, renewRequest.Response.ID);
            Assert.Equal(renewRequest.Response.TTL.Value.TotalSeconds, TimeSpan.FromSeconds(10).TotalSeconds);

            var destroyRequest = await client.Session.Destroy(id);
            Assert.True(destroyRequest.Response);

            try
            {
                renewRequest = await client.Session.Renew(id);
                Assert.True(false, "Session still exists");
            }
            catch (SessionExpiredException ex)
            {
                Assert.IsType<SessionExpiredException>(ex);
            }
        }
예제 #8
0
        public async Task Health_Service()
        {
            var client = new ConsulClient();

            var checks = await client.Health.Service("consul", "", true);
            Assert.NotEqual((ulong)0, checks.LastIndex);
            Assert.NotEqual(0, checks.Response.Length);
        }
예제 #9
0
        public async Task Health_State()
        {
            var client = new ConsulClient();

            var checks = await client.Health.State(CheckStatus.Any);
            Assert.NotEqual((ulong)0, checks.LastIndex);
            Assert.NotEqual(0, checks.Response.Length);
        }
예제 #10
0
        public async Task Catalog_Service()
        {
            var client = new ConsulClient();
            var serviceList = await client.Catalog.Service("consul");

            Assert.NotEqual((ulong)0, serviceList.LastIndex);
            Assert.NotEqual(0, serviceList.Response.Length);
        }
예제 #11
0
        public async Task Agent_Members()
        {
            var client = new ConsulClient();

            var members = await client.Agent.Members(false);

            Assert.NotNull(members);
            Assert.Equal(1, members.Response.Length);
        }
예제 #12
0
        public async Task Catalog_Node()
        {
            var client = new ConsulClient();

            var node = await client.Catalog.Node(client.Agent.NodeName);

            Assert.NotEqual((ulong)0, node.LastIndex);
            Assert.NotNull(node.Response.Services);
        }
예제 #13
0
        public void Lock_OneShot()
        {
            var client = new ConsulClient();
            const string keyName = "test/lock/oneshot";
            var lockOptions = new LockOptions(keyName)
            {
                LockTryOnce = true
            };

            Assert.Equal(Lock.DefaultLockWaitTime, lockOptions.LockWaitTime);

            lockOptions.LockWaitTime = TimeSpan.FromMilliseconds(1000);

            var lockKey = client.CreateLock(lockOptions);

            lockKey.Acquire(CancellationToken.None);

            var contender = client.CreateLock(new LockOptions(keyName)
            {
                LockTryOnce = true,
                LockWaitTime = TimeSpan.FromMilliseconds(1000)
            });

            var stopwatch = Stopwatch.StartNew();

            Exception didExcept = null;

            Task.WaitAny(
                Task.Run(() =>
                {
                    // Needed because async asserts don't work in sync methods!
                    try
                    {
                        contender.Acquire();
                    }
                    catch (Exception e)
                    {
                        didExcept = e;
                    }
                }),
                Task.Delay((int)(2 * lockOptions.LockWaitTime.TotalMilliseconds)).ContinueWith((t) => Assert.True(false, "Took too long"))
                );


            Assert.False(stopwatch.ElapsedMilliseconds < lockOptions.LockWaitTime.TotalMilliseconds);
            Assert.False(contender.IsHeld, "Contender should have failed to acquire");
            Assert.IsType<LockMaxAttemptsReachedException>(didExcept);

            lockKey.Release();

            contender.Acquire();
            Assert.True(contender.IsHeld);

            contender.Release();
            contender.Destroy();
        }
예제 #14
0
        public async Task Agent_Self()
        {
            var client = new ConsulClient();

            var info = await client.Agent.Self();

            Assert.NotNull(info);
            Assert.False(string.IsNullOrEmpty(info.Response["Config"]["NodeName"]));
            Assert.False(string.IsNullOrEmpty(info.Response["Member"]["Tags"]["bootstrap"].ToString()));
        }
예제 #15
0
        public async Task Health_Node()
        {
            var client = new ConsulClient();

            var info = await client.Agent.Self();
            var checks = await client.Health.Node((string)info.Response["Config"]["NodeName"]);

            Assert.NotEqual((ulong)0, checks.LastIndex);
            Assert.NotEqual(0, checks.Response.Length);
        }
예제 #16
0
        public async Task Session_CreateDestroy()
        {
            var client = new ConsulClient();
            var sessionRequest = await client.Session.Create();
            var id = sessionRequest.Response;
            Assert.NotEqual(TimeSpan.Zero, sessionRequest.RequestTime);
            Assert.False(string.IsNullOrEmpty(sessionRequest.Response));

            var destroyRequest = await client.Session.Destroy(id);
            Assert.True(destroyRequest.Response);
        }
예제 #17
0
        public async Task KV_Put_Get_Delete()
        {
            var client = new ConsulClient();
            var kv = client.KV;

            var key = GenerateTestKeyName();

            var value = Encoding.UTF8.GetBytes("test");

            var getRequest = await kv.Get(key);
            Assert.Equal(System.Net.HttpStatusCode.NotFound, getRequest.StatusCode);
            Assert.Null(getRequest.Response);

            var pair = new KVPair(key)
            {
                Flags = 42,
                Value = value
            };

            var putRequest = await kv.Put(pair);
            Assert.Equal(System.Net.HttpStatusCode.OK, putRequest.StatusCode);
            Assert.True(putRequest.Response);

            try
            {
                // Put a key that begins with a '/'
                var invalidKey = new KVPair("/test")
                {
                    Flags = 42,
                    Value = value
                };
                await kv.Put(invalidKey);
                Assert.True(false, "Invalid key not detected");
            }
            catch (InvalidKeyPairException ex)
            {
                Assert.IsType<InvalidKeyPairException>(ex);
            }

            getRequest = await kv.Get(key);
            Assert.Equal(System.Net.HttpStatusCode.OK, getRequest.StatusCode);
            var res = getRequest.Response;

            Assert.NotNull(res);
            Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(value, res.Value));
            Assert.Equal(pair.Flags, res.Flags);
            Assert.True(getRequest.LastIndex > 0);

            var del = await kv.Delete(key);
            Assert.True(del.Response);

            getRequest = await kv.Get(key);
            Assert.Null(getRequest.Response);
        }
예제 #18
0
        public async Task Catalog_Nodes()
        {
            var client = new ConsulClient();
            var nodeList = await client.Catalog.Nodes();

            Assert.NotEqual((ulong)0, nodeList.LastIndex);
            Assert.NotEqual(0, nodeList.Response.Length);
            // make sure deserialization is working right
            Assert.NotNull(nodeList.Response[0].Address);
            Assert.NotNull(nodeList.Response[0].Name);
        }
예제 #19
0
        public async Task Session_CreateDestroy()
        {
            var client = new ConsulClient();
            var sessionRequest = await client.Session.Create();
            var id = sessionRequest.Response;
            Assert.True(sessionRequest.RequestTime.TotalMilliseconds > 0);
            Assert.False(string.IsNullOrEmpty(sessionRequest.Response));

            var destroyRequest = await client.Session.Destroy(id);
            Assert.True(destroyRequest.Response);
        }
예제 #20
0
 public async Task Lock_EphemeralAcquireRelease()
 {
     var client = new ConsulClient();
     const string keyName = "test/lock/ephemerallock";
     var sessionId = await client.Session.Create(new SessionEntry { Behavior = SessionBehavior.Delete });
     using (var l = client.AcquireLock(new LockOptions(keyName) { Session = sessionId.Response }, CancellationToken.None))
     {
         Assert.True(l.IsHeld);
         await client.Session.Destroy(sessionId.Response);
     }
     Assert.Null((await client.KV.Get(keyName)).Response);
 }
예제 #21
0
        public async Task Coordinate_Datacenters()
        {
            var client = new ConsulClient();

            var info = await client.Agent.Self();

            Skip.IfNot(info.Response.ContainsKey("Coord"), "This version of Consul does not support the coordinate API");

            var datacenters = await client.Coordinate.Datacenters();

            Assert.NotNull(datacenters.Response);
            Assert.True(datacenters.Response.Length > 0);
        }
예제 #22
0
        public async Task ACL_Info()
        {
            Skip.If(string.IsNullOrEmpty(ConsulRoot));

            var client = new ConsulClient(new ConsulClientConfiguration() { Token = ConsulRoot });

            var aclEntry = await client.ACL.Info(ConsulRoot);

            Assert.NotNull(aclEntry.Response);
            Assert.NotEqual(aclEntry.RequestTime.TotalMilliseconds, 0);
            Assert.Equal(aclEntry.Response.ID, ConsulRoot);
            Assert.Equal(aclEntry.Response.Type, ACLType.Management);
        }
예제 #23
0
        public async Task Coordinate_Nodes()
        {
            var client = new ConsulClient();

            var info = await client.Agent.Self();

            Skip.If(!info.Response.ContainsKey("Coord"), "This version of Consul does not support the coordinate API");

            var nodes = await client.Coordinate.Nodes();

            // There's not a good way to populate coordinates without
            // waiting for them to calculate and update, so the best
            // we can do is call the endpoint and make sure we don't
            // get an error. - from offical API.
            Assert.NotNull(nodes);
        }
예제 #24
0
        public async Task Client_SetClientOptions()
        {
            var config = new ConsulClientConfiguration()
            {
                Datacenter = "foo",
                WaitTime = new TimeSpan(0, 0, 100),
                Token = "12345"
            };
            var client = new ConsulClient(config);
            var request = client.Get<KVPair>("/v1/kv/foo");

            await Assert.ThrowsAsync<ConsulRequestException>(async () => await request.Execute());

            Assert.Equal("foo", request.Params["dc"]);
            Assert.Equal("1m40s", request.Params["wait"]);
            Assert.Equal("12345", request.Params["token"]);
        }
예제 #25
0
        public void Semaphore_AcquireRelease()
        {
            var client = new ConsulClient();

            const string keyName = "test/semaphore/acquirerelease";

            var semaphore = client.Semaphore(keyName, 2);

            try
            {
                semaphore.Release();
            }
            catch (SemaphoreNotHeldException ex)
            {
                Assert.IsType<SemaphoreNotHeldException>(ex);
            }

            semaphore.Acquire(CancellationToken.None);

            Assert.True(semaphore.IsHeld);

            try
            {
                semaphore.Acquire(CancellationToken.None);
            }
            catch (SemaphoreHeldException ex)
            {
                Assert.IsType<SemaphoreHeldException>(ex);
            }

            Assert.True(semaphore.IsHeld);

            semaphore.Release();

            try
            {
                semaphore.Release();
            }
            catch (SemaphoreNotHeldException ex)
            {
                Assert.IsType<SemaphoreNotHeldException>(ex);
            }

            Assert.False(semaphore.IsHeld);
        }
예제 #26
0
        public async Task Session_CreateRenewDestroy()
        {
            var client = new ConsulClient();
            var sessionRequest = await client.Session.Create(new SessionEntry() { TTL = TimeSpan.FromSeconds(10) });

            var id = sessionRequest.Response;
            Assert.NotEqual(TimeSpan.Zero, sessionRequest.RequestTime);
            Assert.False(string.IsNullOrEmpty(sessionRequest.Response));

            var renewRequest = await client.Session.Renew(id);
            Assert.NotEqual(TimeSpan.Zero, renewRequest.RequestTime);
            Assert.NotNull(renewRequest.Response.ID);
            Assert.Equal(sessionRequest.Response, renewRequest.Response.ID);
            Assert.True(renewRequest.Response.TTL.HasValue);
            Assert.Equal(renewRequest.Response.TTL.Value.TotalSeconds, TimeSpan.FromSeconds(10).TotalSeconds);

            var destroyRequest = await client.Session.Destroy(id);
            Assert.True(destroyRequest.Response);
        }
예제 #27
0
        public void Semaphore_BadLimit()
        {
            var client = new ConsulClient();

            const string keyName = "test/semaphore/badlimit";

            try
            {
                client.Semaphore(keyName, 0);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Assert.IsType<ArgumentOutOfRangeException>(ex);
            }

            var semaphore1 = client.Semaphore(keyName, 1);
            semaphore1.Acquire(CancellationToken.None);

            try
            {
                var semaphore2 = client.Semaphore(keyName, 2);
                semaphore2.Acquire(CancellationToken.None);
            }
            catch (SemaphoreLimitConflictException ex)
            {
                Assert.IsType<SemaphoreLimitConflictException>(ex);
                Assert.Equal(1, ex.RemoteLimit);
                Assert.Equal(2, ex.LocalLimit);
            }

            try
            {
                semaphore1.Release();
                semaphore1.Destroy();
            }
            catch (SemaphoreNotHeldException ex)
            {
                Assert.IsType<SemaphoreNotHeldException>(ex);
            }

            Assert.False(semaphore1.IsHeld);
        }
예제 #28
0
        public void Lock_AcquireRelease()
        {
            var client = new ConsulClient();
            const string keyName = "test/lock/acquirerelease";
            var lockKey = client.CreateLock(keyName);

            try
            {
                lockKey.Release();
            }
            catch (LockNotHeldException ex)
            {
                Assert.IsType<LockNotHeldException>(ex);
            }

            lockKey.Acquire(CancellationToken.None);

            try
            {
                lockKey.Acquire(CancellationToken.None);
            }
            catch (LockHeldException ex)
            {
                Assert.IsType<LockHeldException>(ex);
            }

            Assert.True(lockKey.IsHeld);

            lockKey.Release();

            try
            {
                lockKey.Release();
            }
            catch (LockNotHeldException ex)
            {
                Assert.IsType<LockNotHeldException>(ex);
            }

            Assert.False(lockKey.IsHeld);
        }
예제 #29
0
        public async Task Event_FireList()
        {
            var client = new ConsulClient();

            var userevent = new UserEvent()
            {
                Name = "foo"
            };

            var res = await client.Event.Fire(userevent);

            await Task.Delay(100);

            Assert.NotEqual(TimeSpan.Zero, res.RequestTime);
            Assert.False(string.IsNullOrEmpty(res.Response));

            var events = await client.Event.List();
            Assert.NotEqual(0, events.Response.Length);
            Assert.Equal(res.Response, events.Response[events.Response.Length - 1].ID);
            Assert.Equal(client.Event.IDToIndex(res.Response), events.LastIndex);
        }
예제 #30
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            string ip = "127.0.0.1";    //获取本接口所在服务器的ip
            //获取本接口所在服务器的ip的端口
            int    port        = 4001;
            string serviceName = "PostService";
            //服务的id,不可重复。
            string serviceId = serviceName + Guid.NewGuid();

            //创建一个consul客户端
            using (var client = new ConsulClient(ConsulConfig))
            {
                //将本接口注册到consul
                client.Agent
                .ServiceRegister(new AgentServiceRegistration()
                {
                    Address = ip,
                    ID      = serviceId,
                    Name    = serviceName,
                    Port    = port,
                    Check   = new AgentServiceCheck()
                    {
                        //服务停止多久后反注册(注销)
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                        //健康检查时间间隔,或者称为心跳间隔
                        Interval = TimeSpan.FromSeconds(10),
                        //健康检查地址,Healthy:用于健康检查的接口
                        HTTP = $"http://{ip}:{port}/api/Healthy",
                        //设置超时时间
                        Timeout = TimeSpan.FromSeconds(5)
                    }
                }).Wait();
            }
        }
예제 #31
0
        public ConsulKvCache(IConfiguration <ConsulClientConfiguration> configuration)
        {
            Consul = new ConsulClient((_config) =>
            {
                var value = configuration.Value;

                _config.Address    = value.Address;
                _config.Datacenter = value.Datacenter;
                _config.Token      = value.Token;
                _config.WaitTime   = value.WaitTime;
            });

            Source           = new CancellationTokenSource();
            RefreshCacheTask = Task.Factory.StartNew(async() =>
            {
                while (!Source.Token.IsCancellationRequested)
                {
                    try
                    {
                        var query = await Consul.KV.List("", Source.Token);

                        if (query.StatusCode == HttpStatusCode.OK)
                        {
                            lock (_locked)
                                KvPairs = query.Response.ToList();
                        }
                        else
                        {
                            lock (_locked)
                                KvPairs = new List <KVPair>();
                        }

                        await Task.Delay(1500);
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }, Source.Token);
        }
예제 #32
0
        public async void RegisterDiscoveryService()
        {
            try
            {
                using (var consul = new ConsulClient())
                {
                    var name = ServiceConfigs.ServiceName;
                    var port = ServiceConfigs.ServicePort;
                    var id   = $"{name}:{port}";

                    var tags = new[] { "debug" };
                    var deregisterCriticalServiceAfter = TimeSpan.FromSeconds(5);

                    var result = await consul.Agent.ServiceRegister(
                        new AgentServiceRegistration
                    {
                        ID      = id,
                        Name    = name,
                        Port    = port,
                        Address = "127.0.0.1",
                        Tags    = tags,
                        Check   = new AgentServiceCheck
                        {
                            DeregisterCriticalServiceAfter = deregisterCriticalServiceAfter,
                            Interval = TimeSpan.FromSeconds(5),
                            HTTP     = $"http://localhost:{port}/ping"
                        },
                    });

                    if (result.StatusCode == HttpStatusCode.OK)
                    {
                        Logger.Information("Сервис {service} зарегистрирован в Consul.", name);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "ошибка при регистрации в Consul");
            }
        }
예제 #33
0
        public void Lock_ContendWait()
        {
            var client = new ConsulClient();

            const string keyName       = "test/lock/contendwait";
            const int    contenderPool = 3;

            var acquired = new System.Collections.Concurrent.ConcurrentDictionary <int, bool>();

            using (var cts = new CancellationTokenSource())
            {
                cts.CancelAfter(contenderPool * (int)Lock.DefaultLockWaitTime.TotalMilliseconds);

                Parallel.For(0, contenderPool, new ParallelOptions {
                    MaxDegreeOfParallelism = contenderPool, CancellationToken = cts.Token
                }, (v) =>
                {
                    var lockKey = client.CreateLock(keyName);
                    lockKey.Acquire(CancellationToken.None);
                    Assert.True(acquired.TryAdd(v, lockKey.IsHeld));
                    if (lockKey.IsHeld)
                    {
                        Task.Delay(1000).Wait();
                        lockKey.Release();
                    }
                });
            }

            for (var i = 0; i < contenderPool; i++)
            {
                if (acquired[i])
                {
                    Assert.True(acquired[i]);
                }
                else
                {
                    Assert.True(false, "Contender " + i.ToString() + " did not acquire the lock");
                }
            }
        }
예제 #34
0
        /// <summary>
        /// 获取所有键值对
        /// </summary>
        /// <param name="consulAddress">Consul地址</param>
        /// <param name="consulDataCenter">Consul数据中心</param>
        /// <returns></returns>
        public static async Task <T> GetKeyValueObject <T>(string consulAddress,
                                                           string consulDataCenter) where T : new()
        {
            using (var client = new ConsulClient(configuration =>
            {
                configuration.Address = new Uri(consulAddress);
                configuration.Datacenter = consulDataCenter;
            }))
            {
                T @object = new T();

                string   prefix     = string.Empty;
                object[] attributes = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (attributes.Length != 0)
                {
                    DescriptionAttribute descriptionAttribute = (DescriptionAttribute)attributes[0];
                    prefix = descriptionAttribute.Description;
                    if (!prefix.EndsWith("/"))
                    {
                        prefix += "/";
                    }
                }

                QueryResult <KVPair[]> kvPairList = await client.KV.List(prefix);

                if (kvPairList.Response == null)
                {
                    return(default(T));
                }
                Dictionary <string, string> dictionaries = kvPairList.Response.ToDictionary(o => o.Key,
                                                                                            o => o.Value == null ? null : Encoding.UTF8.GetString(o.Value, 0, o.Value.Length));
                PropertyInfo[] propertyInfos = @object.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (var propertyInfo in propertyInfos)
                {
                    SetValue(@object, propertyInfo, dictionaries, prefix);
                }

                return(@object);
            }
        }
예제 #35
0
        public async Task KV_WatchList()
        {
            var client = new ConsulClient();

            var prefix = GenerateTestKeyName();

            var value = Encoding.UTF8.GetBytes("test");

            var pairs = await client.KV.List(prefix);

            Assert.Null(pairs.Response);

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            Task.Run(async() =>
            {
                Thread.Sleep(100);
                var p = new KVPair(prefix)
                {
                    Flags = 42, Value = value
                };
                var putRes = await client.KV.Put(p);
                Assert.True(putRes.Response);
            });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed

            var pairs2 = await client.KV.List(prefix, new QueryOptions()
            {
                WaitIndex = pairs.LastIndex
            });

            Assert.NotNull(pairs2.Response);
            Assert.Equal(pairs2.Response.Length, 1);
            Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(value, pairs2.Response[0].Value));
            Assert.Equal(pairs2.Response[0].Flags, (ulong)42);
            Assert.True(pairs2.LastIndex > pairs.LastIndex);

            var deleteTree = await client.KV.DeleteTree(prefix);

            Assert.True(deleteTree.Response);
        }
예제 #36
0
        public async Task Operator_KeyringInstallListPutRemove()
        {
            const string oldKey = "d8wu8CSUrqgtjVsvcBPmhQ==";
            const string newKey = "qxycTi/SsePj/TZzCBmNXw==";

            using (var c = new ConsulClient())
            {
                await c.Operator.KeyringInstall(oldKey);

                await c.Operator.KeyringUse(oldKey);

                await c.Operator.KeyringInstall(newKey);

                var listResponses = await c.Operator.KeyringList();

                Assert.Equal(2, listResponses.Response.Length);

                foreach (var response in listResponses.Response)
                {
                    Assert.Equal(2, response.Keys.Count);
                    Assert.True(response.Keys.ContainsKey(oldKey));
                    Assert.True(response.Keys.ContainsKey(newKey));
                }

                await c.Operator.KeyringUse(newKey);

                await c.Operator.KeyringRemove(oldKey);

                listResponses = await c.Operator.KeyringList();

                Assert.Equal(2, listResponses.Response.Length);

                foreach (var response in listResponses.Response)
                {
                    Assert.Equal(1, response.Keys.Count);
                    Assert.False(response.Keys.ContainsKey(oldKey));
                    Assert.True(response.Keys.ContainsKey(newKey));
                }
            }
        }
예제 #37
0
        public static void UseConsulByWebApi(this IApplicationBuilder app)
        {
            var appSettings = Singleton <AppSettings> .Instance;
            var config      = appSettings[nameof(ConsulConfig)] as ConsulConfig;

            if (config.CurrentServerModel == ServerModel.WebApi)
            {
                var lifetime     = EngineContext.Current.Resolve <IHostApplicationLifetime>();
                var consulClient =
                    new ConsulClient(configuration => configuration.Address = new Uri(config.ConsulAddress));

                config.ServerName = string.IsNullOrEmpty(config.ServerName)
                    ? AppDomain.CurrentDomain.FriendlyName.Replace(".", "_")
                    : config.ServerName;

                var uri = new Uri(config.HealthAddress);

                var registration = new AgentServiceRegistration
                {
                    ID      = Guid.NewGuid().ToString(),
                    Tags    = new string[] { ".net Core WebApiService" },
                    Name    = config.ServerName,
                    Address = $"{uri.Host}",
                    Port    = uri.Port,
                    Check   = new AgentServiceCheck()
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(config.DeregisterCriticalServiceAfter),
                        Interval = TimeSpan.FromSeconds(config.Interval),
                        HTTP     = config.HealthAddress,
                        Timeout  = TimeSpan.FromSeconds(config.Timeout)
                    }
                };

                consulClient.Agent.ServiceRegister(registration).Wait();
                lifetime.ApplicationStopping.Register(() =>
                {
                    consulClient.Agent.ServiceDeregister(registration.ID).Wait();
                });
            }
        }
예제 #38
0
        public static void UseApskServiceRegistration(this IApplicationBuilder app, IConfiguration config, IHostApplicationLifetime applicationLifetime)
        {
            var serviceDiscovery = new ServiceDiscoverySetting();

            config.GetSection(nameof(ServiceDiscoverySetting)).Bind(serviceDiscovery);

            var serviceName = Assembly.GetEntryAssembly().GetName().Name.Replace(".", string.Empty);

            var features  = app.Properties["server.Features"] as FeatureCollection;
            var addresses = features.Get <IServerAddressesFeature>()
                            .Addresses
                            .Select(p => new Uri(p));

            var consul = new ConsulClient(config =>
            {
                config.Datacenter = "dc1";
                config.Address    = new Uri(serviceDiscovery.HttpEndpoint);
            });

            foreach (var address in addresses)
            {
                var serviceId = $"{serviceName}_{address.Host}:{address.Port}";

                var registration = new AgentServiceRegistration()
                {
                    Address = address.Host,
                    Port    = address.Port,
                    Check   = new AgentServiceCheck()
                    {
                        HTTP     = $"{address.OriginalString}/healthCheck",
                        Interval = TimeSpan.FromSeconds(30),
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5)
                    },
                    ID   = serviceId,
                    Name = serviceName
                };
                applicationLifetime.ApplicationStarted.Register(() => consul.Agent.ServiceRegister(registration).Wait());
                applicationLifetime.ApplicationStopping.Register(() => consul.Agent.ServiceDeregister(registration.ID).Wait());
            }
        }
예제 #39
0
        public void Lock_ForceInvalidate()
        {
            var client = new ConsulClient();

            const string keyName = "test/lock/forceinvalidate";

            var lockKey = (Lock)client.CreateLock(keyName);

            try
            {
                lockKey.Acquire(CancellationToken.None);

                Assert.True(lockKey.IsHeld);

                var checker = Task.Run(() =>
                {
                    while (lockKey.IsHeld)
                    {
                        Task.Delay(10).Wait();
                    }
                    Assert.False(lockKey.IsHeld);
                });

                Task.Run(() => { client.Session.Destroy(lockKey.LockSession); });

                Task.WaitAny(new[] { checker }, 1000);
            }
            finally
            {
                try
                {
                    lockKey.Release();
                    lockKey.Destroy();
                }
                catch (LockNotHeldException ex)
                {
                    Assert.IsType <LockNotHeldException>(ex);
                }
            }
        }
예제 #40
0
        private void TestConsul()
        {
            var client = new ConsulClient();

            client.Config.Address = new Uri("http://127.0.0.1:8500");



            var service = new AgentServiceRegistration()
            {
                ID                = $"atlantis-{Guid.NewGuid().ToString()}",
                Name              = "atlantis",
                Tags              = new string[] { "atlantis-tags" },
                Port              = 4006,
                Address           = "127.0.0.1",
                EnableTagOverride = false,
            };

            var check = new AgentCheckRegistration()
            {
                // ServiceID=service.ID,
                DeregisterCriticalServiceAfter = TimeSpan.FromMilliseconds(10),
                Status = HealthStatus.Critical,
                TTL    = TimeSpan.FromMilliseconds(10)
            };

            service.Check = check;
            var result = client.Agent.ServiceRegister(service).Result;

            var checkResult = client.Agent.CheckRegister(check).Result;

            Task.Run(() =>
            {
                while (true)
                {
                    client.Agent.PassTTL(check.ID, "pass");
                    System.Threading.Thread.Sleep(8);
                }
            });
        }
예제 #41
0
        public override void ApplicationInitialization(ApplicationContext context)
        {
            var applicationBuilder            = context.GetApplicationBuilder();
            ConsulServiceEntity serviceEntity = new ConsulServiceEntity
            {
                IP          = NetworkHelper.LocalIPAddress,
                Port        = _Prot,//如果使用的是docker 进行部署这个需要和dockerfile中的端口保证一致
                ServiceName = _serviceName,
                ConsulIP    = _consulIp,
                ConsulPort  = _consulPort
            };
            var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{serviceEntity.ConsulIP}:{serviceEntity.ConsulPort}"));//请求注册的 Consul 地址
            var httpCheck    = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),                //服务启动多久后注册
                Interval = TimeSpan.FromSeconds(10),                                     //健康检查时间间隔,或者称为心跳间隔
                HTTP     = $"http://{serviceEntity.IP}:{serviceEntity.Port}/api/health", //健康检查地址
                Timeout  = TimeSpan.FromSeconds(1)
            };

            Console.WriteLine($"我是服务IP和端口:{serviceEntity.IP}:{serviceEntity.Port}");
            // Register service with consul
            var registration = new AgentServiceRegistration()
            {
                Checks  = new[] { httpCheck },
                ID      = Guid.NewGuid().ToString(),
                Name    = serviceEntity.ServiceName,
                Address = serviceEntity.IP,
                Port    = serviceEntity.Port,
                Tags    = new[] { $"urlprefix-/{serviceEntity.ServiceName}" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
            };

            consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)
            var lifetime = applicationBuilder.ApplicationServices.GetRequiredService <IHostApplicationLifetime>();

            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册
            });
        }
예제 #42
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();

            string ip          = Configuration["ip"];
            string port        = Configuration["port"];
            string serviceName = "ProductService";
            string serviceId   = serviceName + Guid.NewGuid();

            using (var consulClient = new ConsulClient(ConsulConifg))
            {
                consulClient.Agent.ServiceRegister(new AgentServiceRegistration
                {
                    Address = ip,
                    Port    = Convert.ToInt32(port),
                    ID      = serviceId,
                    Name    = serviceName,
                    Check   = new AgentServiceCheck
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                        HTTP     = $"http://{ip}:{port}/api/Health",
                        Interval = TimeSpan.FromSeconds(10),
                        Timeout  = TimeSpan.FromSeconds(5)
                    }
                }).Wait();
            }
            applicationLifetime.ApplicationStopped.Register(() =>
            {
                using (var consulClient = new ConsulClient(ConsulConifg))
                {
                    Console.WriteLine("应用退出,开始从consul注销");
                    consulClient.Agent.ServiceDeregister(serviceId).Wait();
                }
            });
        }
예제 #43
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env,
                              IApplicationLifetime appLifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseAuthentication();
            app.UseMvc();

            string ip          = Configuration["ip"];
            string port        = Configuration["port"];
            string serviceName = "ProductService";
            string serviceId   = serviceName + Guid.NewGuid();//唯一

            using (var consulClient = new ConsulClient(consulConfig))
            //using (var consulClient = new ConsulClient(c=> { c.Address = new Uri("http://127.0.0.1:8500");c.Datacenter = "dc1"; }))
            {
                AgentServiceRegistration asr = new AgentServiceRegistration();
                asr.Address = ip;
                asr.Port    = Convert.ToInt32(port);
                asr.ID      = serviceId;
                asr.Name    = serviceName;
                asr.Check   = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                    HTTP     = $"http://{ip}:{port}/api/Health",
                    Interval = TimeSpan.FromSeconds(10),
                    Timeout  = TimeSpan.FromSeconds(5)
                };
                consulClient.Agent.ServiceRegister(asr).Wait();
            };
            appLifetime.ApplicationStopped.Register(() => {
                using (var consulClient = new ConsulClient(consulConfig))
                {
                    Console.WriteLine("应用退出,开始从consul注销");
                    consulClient.Agent.ServiceDeregister(serviceId).Wait();
                }
            });
        }
예제 #44
0
        public void Lock_DeleteKey()
        {
            var client = new ConsulClient();

            const string keyName = "test/lock/deletekey";

            var lockKey = (Lock)client.CreateLock(keyName);

            try
            {
                lockKey.Acquire(CancellationToken.None);

                Assert.True(lockKey.IsHeld);

                var checker = Task.Run(() =>
                {
                    while (lockKey.IsHeld)
                    {
                        Thread.Sleep(10);
                    }
                    Assert.False(lockKey.IsHeld);
                });

                Task.WaitAny(new[] { checker }, 1000);

                client.KV.Delete(lockKey.Opts.Key);
            }
            finally
            {
                try
                {
                    lockKey.Release();
                    lockKey.Destroy();
                }
                catch (LockNotHeldException ex)
                {
                    Assert.IsType <LockNotHeldException>(ex);
                }
            }
        }
예제 #45
0
        public void Lock_Contend_LockDelay()
        {
            var client = new ConsulClient();

            const string keyName = "test/lock/contendlockdelay";

            const int contenderPool = 3;

            var acquired = new System.Collections.Concurrent.ConcurrentDictionary <int, bool>();

            using (var cts = new CancellationTokenSource())
            {
                cts.CancelAfter((contenderPool + 1) * (int)Lock.DefaultLockWaitTime.TotalMilliseconds);

                Parallel.For(0, contenderPool, new ParallelOptions {
                    MaxDegreeOfParallelism = contenderPool, CancellationToken = cts.Token
                }, (v) =>
                {
                    var lockKey = (Lock)client.CreateLock(keyName);
                    lockKey.Acquire(CancellationToken.None);
                    if (lockKey.IsHeld)
                    {
                        Assert.True(acquired.TryAdd(v, lockKey.IsHeld));
                        client.Session.Destroy(lockKey.LockSession);
                    }
                });
            }
            for (var i = 0; i < contenderPool; i++)
            {
                bool didContend = false;
                if (acquired.TryGetValue(i, out didContend))
                {
                    Assert.True(didContend);
                }
                else
                {
                    Assert.True(false, "Contender " + i.ToString() + " did not acquire the lock");
                }
            }
        }
예제 #46
0
파일: ClientTest.cs 프로젝트: zxiaol/consul
        public void Client_DefaultConfig_env()
        {
            const string addr  = "1.2.3.4:5678";
            const string token = "abcd1234";
            const string auth  = "username:password";

            Environment.SetEnvironmentVariable("CONSUL_HTTP_ADDR", addr);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_TOKEN", token);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_AUTH", auth);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_SSL", "1");
            Environment.SetEnvironmentVariable("CONSUL_HTTP_SSL_VERIFY", "0");

            var client = new ConsulClient();
            var config = client.Config;

            Assert.Equal(addr, string.Format("{0}:{1}", config.Address.Host, config.Address.Port));
            Assert.Equal(token, config.Token);
            Assert.NotNull(config.HttpAuth);
            Assert.Equal("username", config.HttpAuth.UserName);
            Assert.Equal("password", config.HttpAuth.Password);
            Assert.Equal("https", config.Address.Scheme);

            Environment.SetEnvironmentVariable("CONSUL_HTTP_ADDR", string.Empty);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_TOKEN", string.Empty);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_AUTH", string.Empty);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_SSL", string.Empty);
            Environment.SetEnvironmentVariable("CONSUL_HTTP_SSL_VERIFY", string.Empty);


#if !CORECLR
            Assert.True((client.HttpHandler as WebRequestHandler).ServerCertificateValidationCallback(null, null, null,
                                                                                                      SslPolicyErrors.RemoteCertificateChainErrors));
            ServicePointManager.ServerCertificateValidationCallback = null;
#else
            Assert.True((client.HttpHandler as HttpClientHandler).ServerCertificateCustomValidationCallback(null, null, null,
                                                                                                            SslPolicyErrors.RemoteCertificateChainErrors));
#endif

            Assert.NotNull(client);
        }
        /// <summary>
        /// 注册服务
        /// </summary>
        public void Register()
        {
            // 1、创建consul客户端连接
            var consulClient = new ConsulClient(configuration =>
            {
                //1.1 建立客户端和服务端连接
                configuration.Address = new Uri(serviceRegistryOptions.RegistryAddress);
            });

            // 2、获取
            var uri = new Uri(serviceRegistryOptions.ServiceAddress);

            // 3、创建consul服务注册对象
            var registration = new AgentServiceRegistration()
            {
                ID      = string.IsNullOrEmpty(serviceRegistryOptions.ServiceId) ? Guid.NewGuid().ToString() : serviceRegistryOptions.ServiceId,
                Name    = serviceRegistryOptions.ServiceName,
                Address = uri.Host,
                Port    = uri.Port,
                Tags    = serviceRegistryOptions.ServiceTags,
                Check   = new AgentServiceCheck
                {
                    // 3.1、consul健康检查超时间
                    Timeout = TimeSpan.FromSeconds(10),
                    // 3.2、服务停止5秒后注销服务
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                    // 3.3、consul健康检查地址
                    HTTP = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceRegistryOptions.HealthCheckAddress}",
                    // 3.4 consul健康检查间隔时间
                    Interval = TimeSpan.FromSeconds(10),
                }
            };

            // 4、注册服务
            consulClient.Agent.ServiceRegister(registration).Wait();

            Console.WriteLine($"服务注册成功:{serviceRegistryOptions.ServiceAddress}");
            // 5、关闭连接
            consulClient.Dispose();
        }
예제 #48
0
        // 服务注册
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime)
        {
            //请求注册的 Consul 地址
            var consulClient = new ConsulClient(x => x.Address = new Uri("http://192.168.200.233:8500"));
            var httpCheck    = new AgentServiceCheck()
            {
                //服务启动多久后注册
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                //健康检查时间间隔,或者称为心跳间隔
                Interval = TimeSpan.FromSeconds(10),
                //健康检查地址
                HTTP    = "http://192.168.20.133:5000/api/health?format=json",
                Timeout = TimeSpan.FromSeconds(5)
            };

            // Register service with consul
            var registration = new AgentServiceRegistration()
            {
                Checks  = new[] { httpCheck },
                ID      = "NetCoreApi.ServiceStack" + "_" + "5000",
                Name    = "NetCoreApi.ServiceStack",
                Address = "192.168.20.133",
                Port    = 5000,

                // 添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
                Tags = new[] { "urlprefix-/NetCoreApi.ServiceStack" }
            };

            // 服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)
            consulClient.Agent.ServiceRegister(registration).Wait();

            lifetime.ApplicationStopping.Register(() =>
            {
                // 服务停止时取消注册
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            });

            return(app);
        }
예제 #49
0
        /// <summary>
        /// 注册Consul
        /// </summary>
        /// <returns></returns>
        public async Task RegisterConsulAsync()
        {
            if (!_consulConfig.Enable)
            {
                return;
            }
            OnMessage?.Invoke("开始注册Consul");
            try
            {
                consulClient = new ConsulClient(options => options.Address = new Uri(_consulConfig.ConsulAddress));
                consulID     = $"{_serviceConfig.ServiceName}_{_serviceConfig.ServiceUrl}";
                var agentServiceRegistration = new AgentServiceRegistration
                {
                    ID      = consulID,
                    Name    = _serviceConfig.ServiceName,
                    Address = _serviceConfig.ServiceAddress,
                    Port    = _serviceConfig.ServicePort,
                    Tags    = new string[] { },
                    Checks  = new[]
                    {
                        new AgentServiceCheck
                        {
                            DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                            HTTP     = _serviceConfig.ServiceHealthUrl,
                            Interval = TimeSpan.FromSeconds(10),
                            Timeout  = TimeSpan.FromSeconds(5),
                        }
                    },
                };
                await consulClient.Agent.ServiceRegister(agentServiceRegistration);

                OnMessage?.Invoke("Consul注册完毕");
            }
            catch (Exception exception)
            {
                exception = new MateralProjectException("Consul注册失败", exception);
                OnException?.Invoke(exception);
            }
        }
예제 #50
0
        public async Task Session_List()
        {
            var client         = new ConsulClient();
            var sessionRequest = await client.Session.Create();

            var id = sessionRequest.Response;

            try
            {
                var listRequest = await client.Session.List();

                Assert.Contains(sessionRequest.Response, listRequest.Response.Select(s => s.ID));
                Assert.NotEqual((ulong)0, listRequest.LastIndex);
                Assert.True(listRequest.KnownLeader);
            }
            finally
            {
                var destroyRequest = await client.Session.Destroy(id);

                Assert.True(destroyRequest.Response);
            }
        }
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IHostApplicationLifetime lifetime, AppConfig config)
        {
            var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{config.ConsulConfig.Server.IP}:{config.ConsulConfig.Server.Port}"));//请求注册的 Consul 地址
            var httpCheck    = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),                                      //服务启动多久后注册

                Interval = TimeSpan.FromSeconds(10),                                                           //健康检查时间间隔,或者称为心跳间隔

                HTTP = $"http://{config.ConsulConfig.Client.IP}:{config.ConsulConfig.Client.Port}/api/health", //健康检查地址

                Timeout = TimeSpan.FromSeconds(5)
            };

            var registration = new AgentServiceRegistration()
            {
                Checks = new[] { httpCheck },

                ID = $"icxlBasicServer-{config.ConsulConfig.Client.IP}:{config.ConsulConfig.Client.Port}",

                Name = "icxlBasicServer",

                Address = $"{config.ConsulConfig.Client.IP}",

                Port = Convert.ToInt32(config.ConsulConfig.Client.Port),

                Tags = new[] { $"urlprefix-/icxlBasicServer" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
            };

            consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)

            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册
            });

            return(app);
        }
예제 #52
0
        public IEnumerable <KeyValuePair <string, string> > QuerySettings()
        {
            var result = default(KVPair[]);
            var prefix = _connectionConfiguration["consul.prefix"];

            using (var client = new ConsulClient(ConfigureClient))
            {
                result = client.KV.List(prefix).Result.Response;
            }
            if (result == default(KVPair[]))
            {
                yield break;
            }
            foreach (var kvPair in result)
            {
                var key   = kvPair.Key.Substring(kvPair.Key.IndexOf('/', prefix.Length) + 1);
                var value = kvPair.Value == null || kvPair.Value.Length == 0
                    ? string.Empty
                    : Encoding.UTF8.GetString(kvPair.Value);
                yield return(new KeyValuePair <string, string>(key, value));
            }
        }
예제 #53
0
        public ArticleService(HttpClient httpClient, IOptions <ServiceDisvoveryOptions> serviceDisvoveryOptions, IDnsQuery dnsQuery)
        {
            _httpClient = httpClient;

            // FIX:Host is NULL
            //var address = dnsQuery.ResolveService("service.consul", serviceDisvoveryOptions.Value.ServiceBName);
            //var addressList = address.First().AddressList;
            //var host = addressList.Any() ? addressList.First().ToString() : address.First().HostName;
            //var port = address.First().Port;
            //_articleService = $"http://{host}:{port}";

            using (var consulClient = new ConsulClient(a => a.Address = new Uri(serviceDisvoveryOptions.Value.Consul.HttpEndpoint)))
            {
                var services = consulClient.Catalog.Service(serviceDisvoveryOptions.Value.ServiceBName).Result.Response;
                if (services != null && services.Any())
                {
                    // XXX: 取第一个,生产环境可选择负载均衡处理
                    var catalogService = services.ElementAt(0);
                    _articleService = $"http://{catalogService.ServiceAddress}:{catalogService.ServicePort}";
                }
            }
        }
예제 #54
0
        public void Register(IApplicationLifetime lifetime, OptionsServiceInfo serviceInfo, OptionsHealth health)
        {
            if (!serviceInfo.Enable)
            {
                return;
            }
            var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{serviceInfo.RegisterIP}:{serviceInfo.RegisterPort}"));//请求注册的 Consul 地址
            var httpCheck    = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),                              //服务启动多久后注册
                Interval = TimeSpan.FromSeconds(serviceInfo.Interval),                                 //健康检查时间间隔,或者称为心跳间隔
                HTTP     = $"http://{serviceInfo.ServiceIP}:{serviceInfo.ServicePort}{health.Router}", //健康检查地址
                Timeout  = TimeSpan.FromSeconds(5)
            };

            // Register service with consul
            var registration = new AgentServiceRegistration()
            {
                Checks  = new[] { httpCheck },
                ID      = Guid.NewGuid().ToString(),
                Name    = serviceInfo.ServiceName,
                Address = serviceInfo.ServiceIP,
                Port    = serviceInfo.ServicePort,
                Tags    = new[] { $"urlprefix-/{serviceInfo.ServiceName}" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
            };

            try
            {
                consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)
                lifetime.ApplicationStopping.Register(() =>
                {
                    consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册
                });
            }
            catch (Exception ex)
            {
                log.InfoAsync("注册到Consul异常:" + ex.Message);
            }
        }
예제 #55
0
        public async Task Event_FireList()
        {
            var client = new ConsulClient();

            var userevent = new UserEvent()
            {
                Name = "foo"
            };

            var res = await client.Event.Fire(userevent);

            await Task.Delay(100);

            Assert.NotEqual(TimeSpan.Zero, res.RequestTime);
            Assert.False(string.IsNullOrEmpty(res.Response));

            var events = await client.Event.List();

            Assert.NotEqual(0, events.Response.Length);
            Assert.Equal(res.Response, events.Response[events.Response.Length - 1].ID);
            Assert.Equal(client.Event.IDToIndex(res.Response), events.LastIndex);
        }
예제 #56
0
        /// <summary>
        /// 获取所有的服务
        /// </summary>
        /// <returns></returns>
        public List <ServiceModel> GetServices()
        {
            List <ServiceModel> result = new List <ServiceModel>();

            using (var consulClient = new ConsulClient(c => c.Address = new Uri(_consulUri)))
            {
                var services = consulClient.Agent.Services().Result.Response;
                foreach (var service in services.Values)
                {
                    ServiceModel serviceModel = new ServiceModel()
                    {
                        ServiceIP   = service.Address,
                        ServiceName = service.Service,
                        ServicePort = service.Port
                    };

                    result.Add(serviceModel);
                }
            }

            return(result);
        }
예제 #57
0
        public async Task Lock_ContendWait()
        {
            var client = new ConsulClient();

            const string keyName       = "test/lock/contendwait";
            const int    contenderPool = 3;

            var acquired = new System.Collections.Concurrent.ConcurrentDictionary <int, bool>();

            using (var cts = new CancellationTokenSource())
            {
                cts.CancelAfter(contenderPool * (int)Lock.DefaultLockWaitTime.TotalMilliseconds);

                var tasks = new List <Task>();
                for (var i = 0; i < contenderPool; i++)
                {
                    var v = i;
                    acquired[v] = false;
                    tasks.Add(Task.Run(async() =>
                    {
                        var lockKey = client.CreateLock(keyName);
                        await lockKey.Acquire(CancellationToken.None);
                        acquired[v] = lockKey.IsHeld;
                        if (lockKey.IsHeld)
                        {
                            await Task.Delay(1000);
                            await lockKey.Release();
                        }
                    }));
                }

                await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(Timeout.Infinite, cts.Token));
            }

            for (var i = 0; i < contenderPool; i++)
            {
                Assert.True(acquired[i], "Contender " + i.ToString() + " did not acquire the lock");
            }
        }
예제 #58
0
        private static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            using (ConsulClient consulClient = new ConsulClient(c => c.Address = new Uri("http://127.0.0.1:8500")))
            {
                //consulClient.Agent.Services()获取consul中注册的所有的服务
                Dictionary <String, AgentService> services = consulClient.Agent.Services().Result.Response;
                foreach (KeyValuePair <String, AgentService> kv in services)
                {
                    Console.WriteLine($"key={kv.Key},{kv.Value.Address},{kv.Value.ID},{kv.Value.Service},{kv.Value.Port}");
                }

                //获取所有服务名字是"apiservice1"所有的服务
                var agentServices = services.Where(s => s.Value.Service.Equals("apiservice1", StringComparison.CurrentCultureIgnoreCase))
                                    .Select(s => s.Value);
                //根据当前TickCount对服务器个数取模,“随机”取一个机器出来,避免“轮询”的负载均衡策略需要计数加锁问题
                var agentService = agentServices.ElementAt(Environment.TickCount % agentServices.Count());
                Console.WriteLine($"{agentService.Address},{agentService.ID},{agentService.Service},{agentService.Port}");
            }

            Console.ReadKey();
        }
예제 #59
0
 /// <summary>
 /// 服务注册
 /// </summary>
 public async Task RegistConsul()
 {
     using (ConsulClient consul = new ConsulClient(RegistConsulConfig))
     {
         AgentServiceRegistration res = new AgentServiceRegistration()
         {
             Address = root["IP"].ToString(),
             Port    = Convert.ToInt32(root["Port"].ToString()),
             Name    = root["ServiceName"].ToString(),
             ID      = root["ServiceName"].ToString() + Guid.NewGuid(),
             Check   = new AgentServiceCheck()
             {
                 HTTP     = $"http://{root["IP"].ToString()}:{root["Port"].ToString()}/api/Health",
                 Interval = TimeSpan.FromSeconds(3),
                 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                 Timeout = TimeSpan.FromSeconds(3)
             }
         };
         ServiceID = res.ID;
         await consul.Agent.ServiceRegister(res);
     }
 }
예제 #60
0
        public void Lock_OneShot()
        {
            var client = new ConsulClient();
            const string keyName = "test/lock/oneshot";
            var lockOptions = new LockOptions(keyName)
            {
                LockTryOnce = true
            };

            Assert.Equal(Lock.DefaultLockWaitTime, lockOptions.LockWaitTime);

            lockOptions.LockWaitTime = TimeSpan.FromMilliseconds(250);

            var lockKey = client.CreateLock(lockOptions);

            lockKey.Acquire(CancellationToken.None);

            var contender = client.CreateLock(new LockOptions(keyName)
            {
                LockTryOnce = true,
                LockWaitTime = TimeSpan.FromMilliseconds(250)
            });

            Task.WaitAny(Task.Run(() =>
            {
                Assert.Throws<LockMaxAttemptsReachedException>(() => 
                contender.Acquire()
                );
            }),
            Task.Delay(2 * lockOptions.LockWaitTime.Milliseconds).ContinueWith((t) => Assert.True(false, "Took too long"))
            );

            lockKey.Release();

            contender.Acquire();
            contender.Release();
            contender.Destroy();
        }