Exemplo n.º 1
0
        private (c.Cluster cluster, CouchbaseConfig couchbaseConfig) LoadCouchbaseConfig(string config)
        {
            if (config == null)
            {
                throw new System.NullReferenceException("传入的配置信息为空。");
            }
            CouchbaseConfig r = null;

            try
            {
                r = GetCouchbaseConfig(config);
            }
            catch (System.Exception)
            {
                throw new ConfigurationException("读取配置文件引发此异常,检查配置信息是否正确。");
            }

            if (r.Cluster.UserName == null || r.Cluster.Password == null)
            {
                throw new ClusterAuthenticatorException("连接集群时引发此异常,用户名、密码验证失败。");
            }

            var serverUrl = new List <Uri>();

            try
            {
                foreach (var item in r.Cluster.Servers)
                {
                    serverUrl.Add(new Uri($"{item.Ip}:{item.Port}"));
                }
            }
            catch (System.Exception)
            {
                throw new ClusterAuthenticatorException(@"读取配置文件引发此异常,检查""Servers""节点配置信息。");
            }


            c.Cluster cluster = null;

            try
            {
                cluster = new c.Cluster(new ClientConfiguration
                {
                    Servers = serverUrl,
                    UseSsl  = r.Cluster.UseSSL,
                    SslPort = r.Cluster.SSLPort
                });
            }
            catch (System.Exception)
            {
                throw new ClusterAuthenticatorException(@"读取配置文件引发此异常,检查""Cluster""节点配置信息。");
            }


            var authenticator = new PasswordAuthenticator(r.Cluster.UserName, r.Cluster.Password);

            cluster.Authenticate(authenticator);
            return(cluster, r);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Returns a Couchbase bucket connection using specified settings and the cluster credentials.
        /// </summary>
        /// <param name="settings">The Couchbase settings.</param>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        /// <param name="timeout">The optional timeout (defaults to 60 seconds).</param>
        /// <param name="ignoreDurability">Optionally configure the bucket to ignore durability parameters.</param>
        /// <returns>The connected <see cref="NeonBucket"/>.</returns>
        /// <exception cref="TimeoutException">Thrown if the bucket is not ready after waiting <paramref name="timeout"/>.</exception>
        /// <remarks>
        /// <para>
        /// You may explicitly pass <paramref name="ignoreDurability"/><c>=true</c> for
        /// development and test environments where there may not be enough cluster nodes to
        /// satisfy durability constraints.  If this is <c>null</c> (the default) then the bucket
        /// will look for the presence of the <b>DEV_WORKSTATION</b> environment variable
        /// and ignore durability constraints if this variable exists, otherwise durability
        /// constraints will be honored.
        /// </para>
        /// </remarks>
        public static NeonBucket OpenBucket(this CouchbaseSettings settings,
                                            string username,
                                            string password,
                                            TimeSpan timeout      = default(TimeSpan),
                                            bool?ignoreDurability = null)
        {
            var bucketConfig =
                new BucketConfiguration()
            {
                BucketName            = settings.Bucket,
                UseEnhancedDurability = settings.UseEnhancedDurability,

                PoolConfiguration = new PoolConfiguration()
                {
                    ConnectTimeout = settings.ConnectTimeout,
                    SendTimeout    = settings.SendTimeout,
                    MaxSize        = settings.MaxPoolConnections,
                    MinSize        = settings.MinPoolConnections
                }
            };

            bucketConfig.PoolConfiguration.ClientConfiguration =
                new ClientConfiguration()
            {
                QueryRequestTimeout = (uint)settings.QueryRequestTimeout,
                ViewRequestTimeout  = settings.ViewRequestTimeout,
                Serializer          = () => new EntitySerializer()
            };

            var config = settings.ToClientConfig();

            config.BucketConfigs.Clear();
            config.BucketConfigs.Add(settings.Bucket, bucketConfig);

            var cluster = new Cluster(config);

            // We have to wait for three Couchbase operations to complete
            // successfully:
            //
            //      1. Authenticate
            //      2. Open Bucket
            //      3. List Indexes
            //
            // Each of these can fail if Couchbase isn't ready.  The Open Bucket
            // can fail after the Authenticate succeeded because the bucket is
            // still warming up in the cluster.

            if (timeout <= TimeSpan.Zero)
            {
                timeout = NeonBucket.ReadyTimeout;
            }

            //-----------------------------------------------------------------
            // Authenticate against the Couchbase cluster.

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            NeonHelper.WaitFor(
                () =>
            {
                try
                {
                    cluster.Authenticate(username, password);
                    return(true);
                }
                catch
                {
                    return(false);
                }
            },
                timeout: timeout,
                pollTime: TimeSpan.FromSeconds(0.5));

            //-----------------------------------------------------------------
            // Open the bucket.  Note that we're going to recreate the bucket after
            // each failed attempt because it doesn't seem to recover from connection
            // failures.
            //
            // I believe this may be due to the index and or query services not being
            // ready yet after Couchbase has just been spun up and the bucket isn't
            // notified when these become ready, even after some time passes.

            timeout = timeout - stopwatch.Elapsed;  // Adjust the timeout downward by the time taken to authenticate.
            stopwatch.Restart();

            var bucket = (NeonBucket)null;

            NeonHelper.WaitFor(
                () =>
            {
                try
                {
                    bucket = new NeonBucket(cluster.OpenBucket(settings.Bucket), settings, ignoreDurability);
                    return(true);
                }
                catch
                {
                    return(false);
                }
            },
                timeout: timeout,
                pollTime: TimeSpan.FromSeconds(0.5));

            //-----------------------------------------------------------------
            // Wait until the bucket can perform a simple read operation without
            // failing.  It appears that we can see early failures for Couchbase
            // clusters that have just been created (e.g. during unit tests).

            timeout = timeout - stopwatch.Elapsed;  // Adjust the timeout downward by the time taken to connect.
            stopwatch.Restart();

            bucket.WaitUntilReadyAsync(timeout).Wait();

            return(bucket);
        }