Пример #1
0
        public async Task <DesignDocument> GetDesignDocumentAsync(string designDocName, DesignDocumentNamespace @namespace, GetDesignDocumentOptions?options = null)
        {
            options ??= GetDesignDocumentOptions.Default;
            var uri = GetUri(designDocName, @namespace);

            _logger.LogInformation($"Attempting to get design document {_bucketName}/{designDocName} - {uri}");

            try
            {
                var result = await _client.GetAsync(uri, options.TokenValue).ConfigureAwait(false);

                if (result.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new DesignDocumentNotFoundException(_bucketName, designDocName);
                }

                result.EnsureSuccessStatusCode();

                var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                var designDocument = JsonConvert.DeserializeObject <DesignDocument>(content);
                designDocument.Name = designDocName;

                return(designDocument);
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, $"Failed to get design document {_bucketName}/{designDocName} - {uri}");
                throw;
            }
        }
        public async Task <Dictionary <string, BucketSettings> > GetAllBucketsAsync(GetAllBucketsOptions?options = null)
        {
            options ??= new GetAllBucketsOptions();
            var uri = GetUri();

            _logger.LogInformation("Attempting to get all buckets - {uri}", _redactor.SystemData(uri));

            try
            {
                var result = await _client.GetAsync(uri, options.TokenValue).ConfigureAwait(false);

                result.EnsureSuccessStatusCode();

                var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                var buckets = new Dictionary <string, BucketSettings>();
                var json    = JArray.Parse(content);

                foreach (var row in json)
                {
                    var settings = GetBucketSettings(row);
                    buckets.Add(settings.Name, settings);
                }

                return(buckets);
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to get all buckets - {uri}", _redactor.SystemData(uri));
                throw;
            }
        }
        public async Task <UserAndMetaData> GetUserAsync(string username, GetUserOptions?options = null)
        {
            options ??= GetUserOptions.Default;
            var uri = GetUsersUri(options.DomainNameValue, username);

            _logger.LogInformation("Attempting to get user with username {username} - {uri}",
                                   _redactor.UserData(username), _redactor.SystemData(uri));

            try
            {
                // check user exists before trying to read content
                var result = await _client.GetAsync(uri, options.TokenValue).ConfigureAwait(false);

                if (result.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new UserNotFoundException(username);
                }

                result.EnsureSuccessStatusCode();

                // get user from result
                var json = JObject.Parse(await result.Content.ReadAsStringAsync().ConfigureAwait(false));
                return(UserAndMetaData.FromJson(json));
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Error trying to get user with username {username} - {uri}",
                                 _redactor.UserData(username), _redactor.SystemData(uri));
                throw;
            }
        }
Пример #4
0
        public async Task <IEnumerable <SearchIndex> > GetAllIndexesAsync(GetAllSearchIndexesOptions?options = null)
        {
            options ??= GetAllSearchIndexesOptions.Default;
            var baseUri = GetIndexUri();

            _logger.LogInformation("Trying to get all indexes - {baseUri}", _redactor.SystemData(baseUri));

            try
            {
                var result = await _client.GetAsync(baseUri, options.TokenValue).ConfigureAwait(false);

                result.EnsureSuccessStatusCode();

                var json = JObject.Parse(await result.Content.ReadAsStringAsync().ConfigureAwait(false));
                return(json["indexDefs"]["indexDefs"].ToObject <Dictionary <string, SearchIndex> >().Values);
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to get all indexes - {baseUri}", _redactor.SystemData(baseUri));
                throw;
            }
        }
Пример #5
0
        public async Task <IEnumerable <ScopeSpec> > GetAllScopesAsync(GetAllScopesOptions?options = null)
        {
            options ??= GetAllScopesOptions.Default;
            var uri = GetUri();

            _logger.LogInformation($"Attempting to get all scopes - {uri}");

            try
            {
                // get manifest
                var result = await _client.GetAsync(uri, options.TokenValue).ConfigureAwait(false);

                result.EnsureSuccessStatusCode();

                // check scope & collection exists in manifest
                var json   = JObject.Parse(await result.Content.ReadAsStringAsync().ConfigureAwait(false));
                var scopes = json.SelectToken("scopes");

                if (scopes.Type != JTokenType.Array) // TODO: remove after SDK beta as per RFC
                {
                    // older style - scopes is a map
                    return(scopes.Select(scope =>
                    {
                        var scopeName = scope.Path.Substring(scope.Path.LastIndexOf(".", StringComparison.InvariantCulture) + 1);
                        var collections = scope.First()["collections"].Select(collection =>
                        {
                            var collectionName = collection.Path.Substring(collection.Path.LastIndexOf(".", StringComparison.InvariantCulture) + 1);
                            return new CollectionSpec(scopeName, collectionName);
                        }).ToList();

                        return new ScopeSpec(scopeName)
                        {
                            Collections = collections
                        };
                    }).ToList());
                }

                // newer style - scopes is an array
                return(scopes.Select(scope => new ScopeSpec(scope["name"].Value <string>())
                {
                    Collections = scope["collections"].Select(collection =>
                                                              new CollectionSpec(collection["name"].Value <string>(), scope["name"].Value <string>())
                                                              ).ToList()
                }).ToList());
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, $"Failed to get all scopes - {uri}");
                throw;
            }
        }
Пример #6
0
        public async Task <Dictionary <string, int> > GetPendingMutationsAsync(GetPendingAnalyticsMutationsOptions?options = null)
        {
            options ??= new GetPendingAnalyticsMutationsOptions();
            _logger.LogInformation("Getting pending mutations.");
            try
            {
                var builder = new UriBuilder(_serviceUriProvider.GetRandomManagementUri());
                builder.Path += "analytics/node/agg/stats/remaining";
                var uri    = builder.Uri;
                var result = await _couchbaseHttpClient.GetAsync(uri, options.TokenValue).ConfigureAwait(false);

                result.EnsureSuccessStatusCode();
                var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                var json = JToken.Parse(content);

                return(parseResult(json));
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to retrieve pending mutations.");
                throw;
            }
        }
        public async Task <IEnumerable <ScopeSpec> > GetAllScopesAsync(GetAllScopesOptions?options = null)
        {
            options ??= GetAllScopesOptions.Default;
            var uri = GetUri();

            _logger.LogInformation("Attempting to get all scopes - {uri}", _redactor.SystemData(uri));

            try
            {
                // get manifest
                var result = await _client.GetAsync(uri, options.TokenValue).ConfigureAwait(false);

                result.EnsureSuccessStatusCode();

                // check scope & collection exists in manifest
                var json   = JObject.Parse(await result.Content.ReadAsStringAsync().ConfigureAwait(false));
                var scopes = json.SelectToken("scopes");

                return(scopes.Select(scope => new ScopeSpec(scope["name"].Value <string>())
                {
                    Collections = scope["collections"].Select(collection =>
                                                              new CollectionSpec(scope["name"].Value <string>(), collection["name"].Value <string>())
                    {
                        MaxExpiry = collection["maxTTL"] == null
                                ? (TimeSpan?)null
                                : TimeSpan.FromSeconds(collection["maxTTL"].Value <long>())
                    }
                                                              ).ToList()
                }).ToList());
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to get all scopes - {uri}", _redactor.SystemData(uri));
                throw;
            }
        }
Пример #8
0
        /// <summary>
        /// Starts the HTTP streaming connection to the Couchbase Server and gets the latest configuration for a SASL authenticated Bucket.
        /// </summary>
        /// <param name="bucketName">The name of the Couchbase Bucket.</param>
        /// <param name="password">The SASL password used to connect to the Bucket.</param>
        /// <returns>A <see cref="IConfigInfo"/> object representing the latest configuration.</returns>
        public override IConfigInfo GetConfig(string bucketName, string username, string password)
        {
            var bucketConfiguration = GetOrCreateConfiguration(bucketName);

            //if the client is using a password make sure the client configuration references it
            password = string.IsNullOrEmpty(password) ? bucketConfiguration.Password : password;
            if (string.IsNullOrEmpty(bucketConfiguration.Password))
            {
                bucketConfiguration.Password = password;
            }

            StartProvider(bucketName, username, password);
            var bucketConfig = GetBucketConfig(bucketName, password, username);

            try
            {
                ConfigLock.EnterWriteLock();
                IConfigInfo configInfo = null;
                var         nodes      = bucketConfig.Nodes.ToList();
                while (nodes.Any())
                {
                    try
                    {
                        nodes.Shuffle();
                        var node = nodes.First();
                        nodes.Remove(node);

                        IBucketConfig newConfig;
                        using (new SynchronizationContextExclusion())
                        {
                            using (var httpClient = new CouchbaseHttpClient(username, password, ClientConfig))
                            {
                                // try to get config using terse uri
                                var uri      = bucketConfig.GetTerseUri(node, bucketConfiguration.UseSsl);
                                var response = httpClient.GetAsync(uri).Result;
                                if (!response.IsSuccessStatusCode)
                                {
                                    // try to get config using verbose uri
                                    uri      = bucketConfig.GetUri(node, bucketConfiguration.UseSsl);
                                    response = httpClient.GetAsync(uri).Result;
                                }

                                // if still not a success, let it throw
                                response.EnsureSuccessStatusCode();

                                var body = response.Content.ReadAsStringAsync().Result;
                                body      = body.Replace("$HOST", uri.Host);
                                newConfig = JsonConvert.DeserializeObject <BucketConfig>(body);
                            }
                        }

                        if (string.IsNullOrWhiteSpace(newConfig.BucketType) && newConfig.BucketCapabilities != null)
                        {
                            newConfig.BucketType = (newConfig.BucketCapabilities.Contains("couchapi", StringComparer.OrdinalIgnoreCase)
                                ? BucketTypeEnum.Couchbase
                                : BucketTypeEnum.Ephemeral).ToString().ToLowerInvariant();
                        }
                        newConfig.Password = password;
                        newConfig.Username = username;
                        if (ClientConfig.UseSsl)
                        {
                            foreach (var ipEndPoint in bucketConfig.VBucketServerMap.IPEndPoints)
                            {
                                ipEndPoint.Port = ClientConfig.SslPort;
                            }
                        }

                        configInfo          = CreateConfigInfo(newConfig, username, password);
                        Configs[bucketName] = configInfo;
                        break;
                    }
                    catch (AggregateException e)
                    {
                        Log.Error(e.InnerException);
                    }
                    catch (IOException e)
                    {
                        Log.Error(e);
                    }
                }

                if (configInfo == null)
                {
                    throw new BucketNotFoundException();
                }
                return(configInfo);
            }
            finally
            {
                ConfigLock.ExitWriteLock();
            }
        }
        /// <summary>
        /// Starts the streaming connection to couchbase server that will
        /// listen for configuration changes and then update the client as needed.
        /// </summary>
        /// <remarks>
        /// Should not be used when a <see cref="SynchronizationContext" /> is present on the thread, as this
        /// could cause deadlocks.  This method is currently only used from within a dedicated thread,
        /// created by <see cref="HttpStreamingProvider.RegisterObserver"/>, so it is safe because there will not
        /// be a SynchronizationContext present on the thread.
        /// </remarks>
        public void ListenForConfigChanges()
        {
            var count = 0;

            //Make a copy of the nodes and shuffle them for randomness
            var nodes = _bucketConfig.Nodes.ToList();

            //if RBAC is being used with >= CB 5.0, then use the username otherwise use the bucket name
            var bucketNameOrUserName = string.IsNullOrWhiteSpace(_bucketConfig.Username)
                ? _bucketConfig.Name
                : _bucketConfig.Username;

            using (var httpClient = new CouchbaseHttpClient(bucketNameOrUserName, _bucketConfig.Password, _clientConfiguration))
            {
                httpClient.Timeout = Timeout.InfiniteTimeSpan;

                //This will keep trying until it runs out of servers to try in the cluster
                while (nodes.ToList().Any())
                {
                    try
                    {
                        //If the main thread has canceled, break out of the loop otherwise
                        //the next node in the server list will be tried; but in this case
                        //we want to shut things down and terminate the thread
                        if (_cancellationToken.IsCancellationRequested)
                        {
                            break;
                        }
                        nodes = nodes.Shuffle();
                        var node = nodes[0];
                        nodes.Remove(node);

                        var streamingUri = _bucketConfig.GetTerseStreamingUri(node, _bucketConfig.UseSsl);
                        Log.Info("Listening to {0}", streamingUri);

                        var response =
                            httpClient.GetAsync(streamingUri, HttpCompletionOption.ResponseHeadersRead,
                                                _cancellationToken)
                            .Result;
                        response.EnsureSuccessStatusCode();

                        using (var stream = response.Content.ReadAsStreamAsync().Result)
                        {
                            //this will cancel the infinite wait below
                            _cancellationToken.Register(stream.Dispose);

                            stream.ReadTimeout = Timeout.Infinite;

                            using (var reader = new StreamReader(stream, Encoding.UTF8, false))
                            {
                                string config;
                                while (!_cancellationToken.IsCancellationRequested &&
                                       ((config = reader.ReadLineAsync().Result) != null))
                                {
                                    if (config != String.Empty)
                                    {
                                        Log.Info("configuration changed count: {0}", count++);
                                        Log.Info("Worker Thread: {0}", Thread.CurrentThread.ManagedThreadId);
                                        var config1 = config;
                                        Log.Debug("{0}", config1);

                                        config = config.Replace("$HOST", streamingUri.Host);
                                        var bucketConfig = JsonConvert.DeserializeObject <BucketConfig>(config);
                                        bucketConfig.SurrogateHost = GetSurrogateHost(streamingUri);
                                        if (_configChangedDelegate != null)
                                        {
                                            bucketConfig.Password = _bucketConfig.Password;
                                            bucketConfig.Username = _bucketConfig.Username;
                                            _configChangedDelegate(bucketConfig);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (AggregateException e)
                    {
                        var exceptions = e.Flatten().InnerExceptions;
                        if (exceptions.OfType <ObjectDisposedException>().Any())
                        {
                            Log.Info("The config listener has shut down.");
                        }
                        foreach (var ex in exceptions.Where(x => x.GetType() != typeof(ObjectDisposedException)))
                        {
                            Log.Error(ex);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);
                    }
                }
            }

            //We tried all nodes in the current configuration, alert the provider that we
            //need to try to re-bootstrap from the beginning
            if (nodes.Count == 0)
            {
                _errorOccurredDelegate(_bucketConfig);
            }
        }