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; using var httpClient = _httpClientFactory.Create(); var result = await httpClient.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 <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; } }
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 using var httpClient = _httpClientFactory.Create(); var result = await httpClient.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; } }
public override async Task <BucketConfig> GetClusterMapAsync(string bucketName, HostEndpoint hostEndpoint, CancellationToken cancellationToken) { var uri = new UriBuilder { Scheme = _context.ClusterOptions.EffectiveEnableTls ? Uri.UriSchemeHttps : Uri.UriSchemeHttp, Host = hostEndpoint.Host, Port = _context.ClusterOptions.EffectiveEnableTls ? _context.ClusterOptions.BootstrapHttpPortTls : _context.ClusterOptions.BootstrapHttpPort, Path = Path + bucketName }; using var httpClient = _httpClientFactory.Create(); using (var response = await httpClient.GetAsync(uri.Uri, cancellationToken).ConfigureAwait(false)) { response.EnsureSuccessStatusCode(); var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); var bucketConfig = await JsonSerializer .DeserializeAsync(stream, InternalSerializationContext.Default.BucketConfig, cancellationToken) .ConfigureAwait(false); bucketConfig !.ReplacePlaceholderWithBootstrapHost(uri.Host); return(bucketConfig); } }
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; } }
public async Task <IEnumerable <ScopeSpec> > GetAllScopesAsync(GetAllScopesOptions?options = null) { options ??= GetAllScopesOptions.Default; var uri = GetUri(RestApi.GetScopes(_bucketName)); _logger.LogInformation("Attempting to get all scopes - {uri}", _redactor.SystemData(uri)); try { // get manifest using var httpClient = _httpClientFactory.Create(); var result = await httpClient.GetAsync(uri, options.TokenValue).ConfigureAwait(false); var body = await result.Content.ReadAsStringAsync().ConfigureAwait(false); //Throw any other error cases if (result.StatusCode != HttpStatusCode.OK) { 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); result.ThrowOnError(ctx); } using var stream = await result.Content.ReadAsStreamAsync().ConfigureAwait(false); using var jsonReader = new JsonTextReader(new StreamReader(stream, Encoding.UTF8)); // check scope & collection exists in manifest var json = await JToken.ReadFromAsync(jsonReader, options.TokenValue).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());
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; } }
private Task StartBackgroundTask() { // Ensure that we don't flow the ExecutionContext into the long running task below using var flowControl = ExecutionContext.SuppressFlow(); return(Task.Run(async() => { var delayMs = InitialDelayMs; var bucket = _bucket as BucketBase; while (!_cancellationTokenSource.IsCancellationRequested) { try { var nodes = bucket?.Nodes.ToList().Shuffle(); while (nodes != null && nodes.Any()) { try { var node = nodes.First(); nodes?.Remove(node); _logger.LogDebug("HTTP Streaming with node {node}", node.EndPoint.Host); var streamingUri = new UriBuilder() { Scheme = _clusterOptions.EffectiveEnableTls ? Uri.UriSchemeHttps : Uri.UriSchemeHttp, Host = node.ManagementUri.Host, Port = node.ManagementUri.Port, Path = _streamingUriPath }; using var httpClient = _httpClientFactory.Create(); httpClient.Timeout = Timeout.InfiniteTimeSpan; var response = await httpClient.GetAsync(streamingUri.Uri, HttpCompletionOption.ResponseHeadersRead, _cancellationTokenSource.Token).ConfigureAwait(false); response.EnsureSuccessStatusCode(); using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); if (stream.CanTimeout) { //the stream itself can timeout if CanTimeout is true on a platform stream.ReadTimeout = Timeout.Infinite; } using var reader = new StreamReader(stream, Encoding.UTF8, false); string?config; while (!_cancellationTokenSource.IsCancellationRequested && (config = await reader.ReadLineAsync().ConfigureAwait(false)) != null) { if (config != string.Empty) { _logger.LogDebug(LoggingEvents.ConfigEvent, config); config = config.Replace("$HOST", node.EndPoint.Host); var bucketConfig = JsonSerializer.Deserialize(config, InternalSerializationContext.Default.BucketConfig) !; _configHandler.Publish(bucketConfig); } // on success, reset the exponential delay delayMs = InitialDelayMs; } } catch (Exception e) { _logger.LogError(e, "HTTP Streaming error."); } } } catch (Exception e) { _logger.LogError(e, "HTTP Streaming error. (outer loop)"); } // if we exited the inner loop, then all servers failed and we need to start over. // however, we don't want to create a failstorm in the logs if the failure is 100% // try again, but with an exponential delay of up to 10s. await Task.Delay(delayMs).ConfigureAwait(false); delayMs = Math.Min(delayMs * 10, MaxDelayMs); } }, _cancellationTokenSource.Token)); }