Пример #1
0
 public void AddNode(IClusterNode node)
 {
     if (Nodes.Add(node))
     {
         _logger.LogDebug("Added {endPoint}", _redactor.SystemData(node.EndPoint));
     }
 }
        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}",
                                   _redactor.MetaData(_bucketName), _redactor.MetaData(designDocName), _redactor.SystemData(uri));

            try
            {
                using var httpClient = _httpClientFactory.Create();

                var result = await httpClient.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}",
                                 _redactor.MetaData(_bucketName), _redactor.MetaData(designDocName), _redactor.SystemData(uri));
                throw;
            }
        }
Пример #3
0
        public async Task CreateBucketAsync(BucketSettings settings, CreateBucketOptions?options = null)
        {
            options ??= new CreateBucketOptions();
            var uri = GetUri();

            _logger.LogInformation("Attempting to create bucket with name {settings.Name} - {uri}",
                                   _redactor.MetaData(settings.Name), _redactor.SystemData(uri));

            try
            {
                // create bucket
                var content = new FormUrlEncodedContent(settings !.ToFormValues());
                using var httpClient = _httpClientFactory.Create();
                var result = await httpClient.PostAsync(uri, content, options.TokenValue).ConfigureAwait(false);

                if (result.IsSuccessStatusCode)
                {
                    return;
                }

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

                var ctx = new ManagementErrorContext
                {
                    HttpStatus = result.StatusCode,
                    Message    = body,
                    Statement  = uri.ToString()
                };

                //Throw specific exception if a rate limiting exception is thrown.
                result.ThrowIfRateLimitingError(body, ctx);



                if (result.StatusCode == HttpStatusCode.BadRequest)
                {
                    if (body.IndexOf("Bucket with given name already exists",
                                     StringComparison.InvariantCultureIgnoreCase) >= 0)
                    {
                        throw new BucketExistsException(settings.Name);
                    }
                }

                //Throw any other error cases
                result.ThrowOnError(ctx);
            }
            catch (BucketExistsException)
            {
                _logger.LogError("Failed to create bucket with name {settings.Name} because it already exists",
                                 _redactor.MetaData(settings.Name));
                throw;
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to create bucket with name {settings.Name} - {uri}",
                                 _redactor.MetaData(settings.Name), _redactor.SystemData(uri));
                throw;
            }
        }
Пример #4
0
        public void Start(IConnectionPool connectionPool)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(DefaultConnectionPoolScaleController));
            }

            _connectionPool = connectionPool ?? throw new ArgumentNullException(nameof(connectionPool));

            _logger.LogDebug(
                "Starting connection pool monitor on {endpoint}, idle timeout {idleTimeout}, back pressure threshold {backPressureThreshold}",
                _redactor.SystemData(_connectionPool.EndPoint), IdleConnectionTimeout, BackPressureThreshold);

            Task.Run(MonitorAsync, _cts.Token);
        }
        public async Task <bool> CollectionExistsAsync(CollectionSpec spec, CollectionExistsOptions?options = null)
        {
            options ??= CollectionExistsOptions.Default;
            var uri = GetUri(RestApi.GetScope(_bucketName, spec.ScopeName));

            _logger.LogInformation(
                "Attempting to verify if scope/collection {spec.ScopeName}/{spec.Name} exists - {uri}", spec.ScopeName,
                spec.Name, _redactor.SystemData(uri));

            try
            {
                // get all scopes
                var scopes =
                    await GetAllScopesAsync(new GetAllScopesOptions().CancellationToken(options.TokenValue))
                    .ConfigureAwait(false);

                // try find scope / collection
                return(scopes.Any(scope =>
                                  scope.Name == spec.ScopeName && scope.Collections.Any(collection => collection.Name == spec.Name)
                                  ));
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to verify if collection {spec.ScopeName}/{spec.Name} exists - {uri}", spec.ScopeName,
                                 spec.Name, _redactor.SystemData(uri));
                throw;
            }
        }
Пример #6
0
 public void AddNode(IClusterNode node)
 {
     _logger.LogDebug("Adding node {endPoint} to {nodes}.", _redactor.SystemData(node.EndPoint), Nodes);
     if (Nodes.Add(node))
     {
         _logger.LogDebug("Added node {endPoint} to {nodes}", _redactor.SystemData(node.EndPoint), Nodes);
     }
 }
Пример #7
0
        public void Start(IConnectionPool connectionPool)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(DefaultConnectionPoolScaleController));
            }

            _connectionPool = connectionPool ?? throw new ArgumentNullException(nameof(connectionPool));

            _logger.LogDebug(
                "Starting connection pool monitor on {endpoint}, idle timeout {idleTimeout}, back pressure threshold {backPressureThreshold}",
                _redactor.SystemData(_connectionPool.EndPoint), IdleConnectionTimeout, BackPressureThreshold);

            using (ExecutionContext.SuppressFlow())
            {
                // We must suppress flow so that the tracing Activity which is current during bootstrap doesn't live on forever
                // as the parent span for all scaling activities.

                Task.Run(MonitorAsync, _cts.Token);
            }
        }
        public async Task CreateBucketAsync(BucketSettings settings, CreateBucketOptions?options = null)
        {
            options ??= new CreateBucketOptions();
            var uri = GetUri();

            _logger.LogInformation("Attempting to create bucket with name {settings.Name} - {uri}",
                                   _redactor.MetaData(settings.Name), _redactor.SystemData(uri));

            try
            {
                // create bucket
                var content = new FormUrlEncodedContent(GetBucketSettingAsFormValues(settings));
                var result  = await _client.PostAsync(uri, content, options.TokenValue).ConfigureAwait(false);

                if (result.StatusCode == HttpStatusCode.BadRequest)
                {
                    var json = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                    if (json.IndexOf("Bucket with given name already exists", StringComparison.InvariantCultureIgnoreCase) >= 0)
                    {
                        throw new BucketExistsException(settings.Name);
                    }
                }

                result.EnsureSuccessStatusCode();
            }
            catch (BucketExistsException)
            {
                _logger.LogError("Failed to create bucket with name {settings.Name} because it already exists",
                                 _redactor.MetaData(settings.Name));
                throw;
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to create bucket with name {settings.Name} - {uri}",
                                 _redactor.MetaData(settings.Name), _redactor.SystemData(uri));
                throw;
            }
        }
Пример #9
0
        public virtual async Task TestUri(FailureCountingUri uri, CancellationToken cancellationToken = default)
        {
            if (uri == null)
            {
                throw new ArgumentNullException(nameof(uri));
            }

            var pingUri = GetPingUri(uri);

            try
            {
                _logger.LogTrace("Pinging {nodeType} node {node} using ping URI {pingUri}", NodeType,
                                 _redactor.SystemData(uri), _redactor.SystemData(pingUri));

                var response = await _httpClient.GetAsync(pingUri, cancellationToken).ConfigureAwait(false);

                if (response.IsSuccessStatusCode)
                {
                    _logger.LogInformation("{nodeType} node {node} back online", NodeType, _redactor.SystemData(uri));
                    uri.ClearFailed();
                }
                else
                {
                    _logger.LogInformation("{nodeType} node {node} still offline", NodeType, _redactor.SystemData(uri));
                }
            }
            catch (AggregateException ae)
            {
                ae.Flatten().Handle(e =>
                {
                    _logger.LogInformation(e, "{nodeType} node {node} still offline", NodeType, _redactor.SystemData(uri));
                    return(true);
                });
            }
            catch (Exception e)
            {
                _logger.LogInformation(e, "{nodeType} node {node} still offline", NodeType, _redactor.SystemData(uri));
            }
        }
        public async Task AllowQueryingAsync(string indexName, AllowQueryingSearchIndexOptions?options = null)
        {
            options ??= AllowQueryingSearchIndexOptions.Default;
            var baseUri = GetQueryControlUri(indexName, true);

            _logger.LogInformation("Trying to allow querying for index with name {indexName} - {baseUri}",
                                   _redactor.MetaData(indexName), _redactor.SystemData(baseUri));

            try
            {
                using var httpClient = _httpClientFactory.Create();
                var result = await httpClient.PostAsync(baseUri, null !, options.TokenValue).ConfigureAwait(false);

                //Handle any errors that may exist
                await CheckStatusAndThrowIfErrorsAsync(result, baseUri, indexName).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to allow querying for index with name {indexName} - {baseUri}",
                                 _redactor.MetaData(indexName), _redactor.SystemData(baseUri));
                throw;
            }
        }
Пример #11
0
        public async Task AllowQueryingAsync(string indexName, AllowQueryingSearchIndexOptions?options = null)
        {
            options ??= AllowQueryingSearchIndexOptions.Default;
            var baseUri = GetQueryControlUri(indexName, true);

            _logger.LogInformation("Trying to allow querying for index with name {indexName} - {baseUri}",
                                   _redactor.MetaData(indexName), _redactor.SystemData(baseUri));

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

                if (result.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new SearchIndexNotFound(indexName);
                }

                result.EnsureSuccessStatusCode();
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Failed to allow querying for index with name {indexName} - {baseUri}",
                                 _redactor.MetaData(indexName), _redactor.SystemData(baseUri));
                throw;
            }
        }
Пример #12
0
        public async Task <IViewResult <TKey, TValue> > ExecuteAsync <TKey, TValue>(IViewQuery query)
        {
            using var rootSpan = _tracer.RootSpan(RequestTracing.ServiceIdentifier.View, OperationNames.ViewQuery)
                                 .WithTag(CouchbaseTags.Service, RequestTracing.ServiceIdentifier.View)
                                 .WithLocalAddress();

            using var encodingSpan = rootSpan.StartPayloadEncoding();
            var uri = query.RawUri();

            rootSpan.WithRemoteAddress(uri);

            ViewResultBase <TKey, TValue> viewResult;

            var body = query.CreateRequestBody();

            try
            {
                _logger.LogDebug("Sending view request to: {uri}", _redactor.SystemData(uri));
                var content = new StringContent(body, Encoding.UTF8, MediaType.Json);
                encodingSpan.Dispose();

                using var dispatchSpan = rootSpan.StartDispatch();
                var response = await HttpClient.PostAsync(uri, content).ConfigureAwait(false);

                dispatchSpan.Dispose();

                var serializer = query.Serializer ?? _serializer;
                if (response.IsSuccessStatusCode)
                {
                    if (serializer is IStreamingTypeDeserializer streamingTypeDeserializer)
                    {
                        viewResult = new StreamingViewResult <TKey, TValue>(
                            response.StatusCode,
                            Success,
                            await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
                            streamingTypeDeserializer
                            );
                    }
                    else
                    {
                        viewResult = new BlockViewResult <TKey, TValue>(
                            response.StatusCode,
                            Success,
                            await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
                            serializer
                            );
                    }

                    await viewResult.InitializeAsync().ConfigureAwait(false);
                }
                else
                {
                    if (serializer is IStreamingTypeDeserializer streamingTypeDeserializer)
                    {
                        viewResult = new StreamingViewResult <TKey, TValue>(
                            response.StatusCode,
                            await response.Content.ReadAsStringAsync().ConfigureAwait(false),
                            streamingTypeDeserializer
                            );
                    }
                    else
                    {
                        viewResult = new BlockViewResult <TKey, TValue>(
                            response.StatusCode,
                            await response.Content.ReadAsStringAsync().ConfigureAwait(false),
                            serializer
                            );
                    }

                    await viewResult.InitializeAsync().ConfigureAwait(false);

                    if (viewResult.ShouldRetry())
                    {
                        UpdateLastActivity();
                        return(viewResult);
                    }

                    if (viewResult.ViewNotFound())
                    {
                        throw new ViewNotFoundException(uri.ToString())
                              {
                                  Context = new ViewContextError
                                  {
                                      DesignDocumentName = query.DesignDocName,
                                      ViewName           = query.ViewName,
                                      ClientContextId    = query.ClientContextId,
                                      HttpStatus         = response.StatusCode,
                                      Errors             = viewResult.Message
                                  }
                              };
                    }
                }
            }
            catch (OperationCanceledException e)
            {
                _logger.LogDebug(LoggingEvents.ViewEvent, e, "View request timeout.");
                throw new AmbiguousTimeoutException("The view query was timed out via the Token.", e)
                      {
                          Context = new ViewContextError
                          {
                              DesignDocumentName = query.DesignDocName,
                              ViewName           = query.ViewName,
                              ClientContextId    = query.ClientContextId,
                              HttpStatus         = HttpStatusCode.RequestTimeout
                          }
                      };
            }
            catch (HttpRequestException e)
            {
                _logger.LogDebug(LoggingEvents.QueryEvent, e, "View request cancelled.");
                throw new RequestCanceledException("The view query was canceled.", e)
                      {
                          Context = new ViewContextError
                          {
                              DesignDocumentName = query.DesignDocName,
                              ViewName           = query.ViewName,
                              ClientContextId    = query.ClientContextId,
                              HttpStatus         = HttpStatusCode.RequestTimeout
                          }
                      };
            }

            UpdateLastActivity();
            return(viewResult);
        }
Пример #13
0
        public async Task <IViewResult <TKey, TValue> > ExecuteAsync <TKey, TValue>(IViewQuery query)
        {
            using var rootSpan = RootSpan(OuterRequestSpans.ServiceSpan.ViewQuery, query);
            rootSpan.WithLocalAddress()
            .WithOperation(query);

            var uri = query.RawUri();

            rootSpan.WithRemoteAddress(uri);

            using var encodingSpan = rootSpan.EncodingSpan();

            ViewResultBase <TKey, TValue> viewResult;

            var body = query.CreateRequestBody();

            try
            {
                _logger.LogDebug("Sending view request to: {uri}", _redactor.SystemData(uri));
                var content = new StringContent(body, Encoding.UTF8, MediaType.Json);
                encodingSpan.Dispose();

                using var dispatchSpan = rootSpan.DispatchSpan(query);

                using var httpClient = CreateHttpClient();
                // set timeout to infinite so we can stream results without the connection
                // closing part way through
                httpClient.Timeout = Timeout.InfiniteTimeSpan;

                var response = await httpClient.PostAsync(uri, content).ConfigureAwait(false);

                dispatchSpan.Dispose();

                var serializer = query.Serializer ?? _serializer;
                if (response.IsSuccessStatusCode)
                {
                    if (serializer is IStreamingTypeDeserializer streamingTypeDeserializer)
                    {
                        viewResult = new StreamingViewResult <TKey, TValue>(
                            response.StatusCode,
                            Success,
                            await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
                            streamingTypeDeserializer
                            );
                    }
                    else
                    {
                        viewResult = new BlockViewResult <TKey, TValue>(
                            response.StatusCode,
                            Success,
                            await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
                            serializer
                            );
                    }

                    await viewResult.InitializeAsync().ConfigureAwait(false);
                }
                else
                {
                    if (serializer is IStreamingTypeDeserializer streamingTypeDeserializer)
                    {
                        viewResult = new StreamingViewResult <TKey, TValue>(
                            response.StatusCode,
                            await response.Content.ReadAsStringAsync().ConfigureAwait(false),
                            streamingTypeDeserializer
                            );
                    }
                    else
                    {
                        viewResult = new BlockViewResult <TKey, TValue>(
                            response.StatusCode,
                            await response.Content.ReadAsStringAsync().ConfigureAwait(false),
                            serializer
                            );
                    }

                    await viewResult.InitializeAsync().ConfigureAwait(false);

                    if (viewResult.ShouldRetry())
                    {
                        viewResult.NoRetryException = new CouchbaseException()
                        {
                            Context = new ViewContextError
                            {
                                DesignDocumentName = query.DesignDocName,
                                ViewName           = query.ViewName,
                                ClientContextId    = query.ClientContextId,
                                HttpStatus         = response.StatusCode,
                                Errors             = viewResult.Message
                            }
                        };
                        UpdateLastActivity();
                        return(viewResult);
                    }

                    if (viewResult.ViewNotFound())
                    {
                        throw new ViewNotFoundException("The queried view is not found on the server.")
                              {
                                  Context = new ViewContextError
                                  {
                                      DesignDocumentName = query.DesignDocName,
                                      ViewName           = query.ViewName,
                                      ClientContextId    = query.ClientContextId,
                                      HttpStatus         = response.StatusCode,
                                      Errors             = viewResult.Message
                                  }
                              };
                    }
                }
            }
            catch (OperationCanceledException e)
            {
                //treat as an orphaned response
                rootSpan.LogOrphaned();

                _logger.LogDebug(LoggingEvents.ViewEvent, e, "View request timeout.");
                throw new AmbiguousTimeoutException("The view query was timed out via the Token.", e)
                      {
                          Context = new ViewContextError
                          {
                              DesignDocumentName = query.DesignDocName,
                              ViewName           = query.ViewName,
                              ClientContextId    = query.ClientContextId,
                              HttpStatus         = HttpStatusCode.RequestTimeout
                          }
                      };
            }
            catch (HttpRequestException e)
            {
                //treat as an orphaned response
                rootSpan.LogOrphaned();

                _logger.LogDebug(LoggingEvents.QueryEvent, e, "View request cancelled.");
                throw new RequestCanceledException("The view query was canceled.", e)
                      {
                          Context = new ViewContextError
                          {
                              DesignDocumentName = query.DesignDocName,
                              ViewName           = query.ViewName,
                              ClientContextId    = query.ClientContextId,
                              HttpStatus         = HttpStatusCode.RequestTimeout
                          }
                      };
            }

            UpdateLastActivity();
            return(viewResult);
        }
        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;
            }
        }