Пример #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="options">options to initialize</param>
        public EtcdClient(EtcdClientOpitions options)
        {
            if (options == null)
                throw new ArgumentNullException("options");
            if (options.Urls == null || options.Urls.Length == 0)
                throw new ArgumentException("`EtcdClientOpitions.Urls` does not contain valid url");

            WebRequestHandler handler = new WebRequestHandler()
            {
                UseProxy = options.UseProxy,
                AllowAutoRedirect = false,
                AllowPipelining = true,
                CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore),
            };
            if (options.X509Certificate != null)
                handler.ClientCertificates.Add(options.X509Certificate);

            AuthenticationHeaderValue authenticationHeaderValue = null;
            if( !string.IsNullOrWhiteSpace(options.Username) &&
                !string.IsNullOrWhiteSpace(options.Password) )
            {
                string auth = string.Format("{0}:{1}", options.Username, options.Password);
                authenticationHeaderValue = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(auth)));
            }

            _jsonDeserializer = options.JsonDeserializer == null ? new DefaultJsonDeserializer() : options.JsonDeserializer;

            if (options.IgnoreCertificateError)
                handler.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return true; };

            HttpClientEx [] httpClients = options.Urls.Select(u =>
                {
                    if (string.IsNullOrWhiteSpace(u))
                        throw new ArgumentNullException("`urls` array contains empty url");

                    HttpClientEx httpClient = new HttpClientEx(handler);
                    httpClient.BaseAddress = new Uri(u);
                    httpClient.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
                    return httpClient;
                }).ToArray();

            // make the clients as a ring, so that we can try the next one when one fails
            if( httpClients.Length > 1 )
            {
                for( int i = httpClients.Length - 2; i >= 0; i--)
                {
                    httpClients[i].Next = httpClients[i + 1];
                }
            }
            httpClients[httpClients.Length - 1].Next = httpClients[0];

            // pick a client randomly
            _currentClient = httpClients[DateTime.UtcNow.Ticks % httpClients.Length];
        }
Пример #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="options">options to initialize</param>
        public EtcdClient(EtcdClientOpitions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }
            if (options.Urls == null || options.Urls.Length == 0)
            {
                throw new ArgumentException("`EtcdClientOpitions.Urls` does not contain valid url");
            }
#if NET45
            WebRequestHandler handler = new WebRequestHandler()
            {
                UseProxy          = options.UseProxy,
                AllowAutoRedirect = false,
                AllowPipelining   = true,
                CachePolicy       = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore),
            };
            if (options.X509Certificate != null)
            {
                handler.ClientCertificates.Add(options.X509Certificate);
            }
#endif
            AuthenticationHeaderValue authenticationHeaderValue = null;
            if (!string.IsNullOrWhiteSpace(options.Username) &&
                !string.IsNullOrWhiteSpace(options.Password))
            {
                string auth = string.Format("{0}:{1}", options.Username, options.Password);
                authenticationHeaderValue = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(auth)));
            }

            _jsonDeserializer = options.JsonDeserializer == null ? new DefaultJsonDeserializer() : options.JsonDeserializer;
#if NET45
            if (options.IgnoreCertificateError)
            {
                handler.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return(true); }
            }
            ;
#endif
            HttpClientEx [] httpClients = options.Urls.Select(u =>
            {
                if (string.IsNullOrWhiteSpace(u))
                {
                    throw new ArgumentNullException("`urls` array contains empty url");
                }
#if NET45
                HttpClientEx httpClient = new HttpClientEx(handler);
#else
                HttpClientEx httpClient = new HttpClientEx();
#endif
                httpClient.BaseAddress = new Uri(u);
                httpClient.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
                return(httpClient);
            }).ToArray();

            // make the clients as a ring, so that we can try the next one when one fails
            if (httpClients.Length > 1)
            {
                for (int i = httpClients.Length - 2; i >= 0; i--)
                {
                    httpClients[i].Next = httpClients[i + 1];
                }
            }
            httpClients[httpClients.Length - 1].Next = httpClients[0];

            // pick a client randomly
            _currentClient = httpClients[DateTime.UtcNow.Ticks % httpClients.Length];
        }
Пример #3
0
        static async Task DoSample()
        {
            EtcdClientOpitions options = new EtcdClientOpitions() {
                Urls = new string[] { "https://etcd0.em", "https://etcd1.em", "https://etcd2.em" },
                Username = "******",
                Password = "******",
                UseProxy = false,
                IgnoreCertificateError = true, // If the ectd server is running with self-signed SSL certificate and we can ignore the SSL error
                //X509Certificate = new X509Certificate2(@"client.p12"),  // client cerificate
                JsonDeserializer = new NewtonsoftJsonDeserializer(),
            };
            EtcdClient etcdClient = new EtcdClient(options);

            

            string key = "/my/key";
            string value;
            // query the value of the node using GetNodeValueAsync
            try {
                value = await etcdClient.GetNodeValueAsync(key);
                Console.WriteLine("The value of `{0}` is `{1}`", key, value);
            }
            catch(EtcdCommonException.KeyNotFound) {
                Console.WriteLine("Key `{0}` does not exist", key);
            }
            

            // update the value using SetNodeAsync
            EtcdResponse resp = await etcdClient.SetNodeAsync(key, "some value");
            Console.WriteLine("Key `{0}` is changed, modifiedIndex={1}", key, resp.Node.ModifiedIndex);

            // query the node using GetNodeAsync
            resp = await etcdClient.GetNodeAsync(key, ignoreKeyNotFoundException: true);
            if (resp == null || resp.Node == null)
                Console.WriteLine("Key `{0}` does not exist", key);
            else
                Console.WriteLine("The value of `{0}` is `{1}`", key, resp.Node.Value);

            //////////////////////////////////////////////////////////

            List<Task<EtcdResponse>> tasks = new List<Task<EtcdResponse>>();
            key = "/in-order-queue";

            // start monitoring the expire event
            WatchChanges(etcdClient, key);

            // create 5 in-order nodes, TTL = 3 second
            for (int i = 0; i < 5; i++) {
                tasks.Add( etcdClient.CreateInOrderNodeAsync(key, i.ToString(), ttl: 3) );
            }

            await Task.WhenAll(tasks);

            // list the in-order nodes
            resp = await etcdClient.GetNodeAsync(key, false, recursive: true, sorted:true);
            if (resp.Node.Nodes != null) {
                foreach (var node in resp.Node.Nodes)
                {
                    Console.WriteLine("`{0}` = {1}", node.Key, node.Value);
                }
            }


            /////////////////////////////////////////////////////////////
            key = "/my/cas-test";
            value = Guid.NewGuid().ToString();
            try {
                resp = await etcdClient.CreateNodeAsync(key, value, null, dir : false);
                Console.WriteLine("Key `{0}` is created with value {1}", key, value);
            }
            catch (EtcdCommonException.NodeExist) {
                Console.WriteLine("Key `{0}` already exists", key);
                
            }

            long prevIndex = 1;
            try {
                resp = await etcdClient.CompareAndSwapNodeAsync(key, value, "new value");
                Console.WriteLine("Key `{0}` is updated to `{1}`", key, resp.Node.Value);

                prevIndex = resp.Node.ModifiedIndex;
            }
            catch (EtcdCommonException.KeyNotFound) {
                Console.WriteLine("Key `{0}` does not exists", key);
            }
            catch (EtcdCommonException.TestFailed) {
                Console.WriteLine("Key `{0}` can not be updated because the supplied previous value is incorrect", key);
            }

            try {
                resp = await etcdClient.CompareAndSwapNodeAsync(key, prevIndex, "new value2");
                Console.WriteLine("Key `{0}` is updated to `{1}`", key, resp.Node.Value);
            }
            catch (EtcdCommonException.KeyNotFound) {
                Console.WriteLine("Key `{0}` does not exists", key);
            }
            catch (EtcdCommonException.TestFailed) {
                Console.WriteLine("Key `{0}` can not be updated because the supplied previous index is incorrect", key);
            }

            

            try {
                resp = await etcdClient.CompareAndDeleteNodeAsync(key, prevIndex+1);
                Console.WriteLine("Key `{0}` is deleted", key);
            }
            catch (EtcdCommonException.KeyNotFound) {
                Console.WriteLine("Key `{0}` does not exists", key);
            }
            catch (EtcdCommonException.TestFailed) {
                Console.WriteLine("Key `{0}` can not be deleted because the supplied previous index is incorrect", key);
            }

            if (prevIndex == 1) // the previous CAS failed
            {
                try {
                    resp = await etcdClient.CompareAndDeleteNodeAsync(key, "new value2");
                    Console.WriteLine("Key `{0}` is deleted", key);
                }
                catch (EtcdCommonException.KeyNotFound) {
                    Console.WriteLine("Key `{0}` does not exists", key);
                }
                catch (EtcdCommonException.TestFailed) {
                    Console.WriteLine("Key `{0}` can not be deleted because the supplied previous value is incorrect", key);
                    etcdClient.DeleteNodeAsync(key, ignoreKeyNotFoundException: true).Wait();
                }
            }
            
        }