/// <summary>
 /// Queries the specified request.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="request">The request.</param>
 /// <returns></returns>
 public IAnalyticsResult <T> Query <T>(IAnalyticsRequest request)
 {
     using (new SynchronizationContextExclusion())
     {
         return(QueryAsync <T>(request, CancellationToken.None).Result);
     }
 }
        /// <summary>
        /// Sends an <see cref="IAnalyticsResult{T}"/> to the server to be executed.
        /// </summary>
        /// <typeparam name="T">The Type T of the body of each result row.</typeparam>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        /// <exception cref="System.TimeoutException">Could not acquire a server.</exception>
        public override IAnalyticsResult <T> SendWithRetry <T>(IAnalyticsRequest request)
        {
            IAnalyticsResult <T> result;

            try
            {
                EnsureServiceAvailable(ConfigInfo.IsAnalyticsCapable, "Analytics");

                // Ugly but prevents Lifespan being public on IAnalyticsRequest
                ((AnalyticsRequest)request).ConfigureLifespan(ConfigInfo.ClientConfig.QueryRequestTimeout);

                result = RetryRequest(
                    ConfigInfo.GetAnalyticsNode,
                    (server, req) => server.Send <T>(req),
                    (req, res) => !(res.Success || req.TimedOut()) && res.ShouldRetry(),
                    request);
            }
            catch (Exception exception)
            {
                Log.Info(exception);
                result = CreateFailedAnalyticsResult <T>(exception);
            }

            return(result);
        }
Example #3
0
        /// <summary>
        /// Sends an analytics request to the server.
        /// </summary>
        /// <typeparam name="T">The <see cref="Type" /> T of the body for each row (or document) result.</typeparam>
        /// <param name="analyticsRequest">The analytics request.</param>
        /// <returns></returns>
        public IAnalyticsResult <T> Send <T>(IAnalyticsRequest analyticsRequest)
        {
            IAnalyticsResult <T> result;

            if (_isDown)
            {
                result = HandleNodeUnavailable <T>(analyticsRequest);
            }
            else
            {
                try
                {
                    result = AnalyticsClient.Query <T>(analyticsRequest);
                }
                catch (Exception exception)
                {
                    result = new AnalyticsResult <T>
                    {
                        Exception = exception,
                        Message   = exception.Message,
                        Success   = false,
                    };
                }
            }
            return(result);
        }
 /// <summary>
 /// Queries the specified request.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="request">The request.</param>
 /// <returns></returns>
 public IAnalyticsResult <T> Query <T>(IAnalyticsRequest request)
 {
     return(QueryAsync <T>(request, CancellationToken.None)
            .ConfigureAwait(false)
            .GetAwaiter()
            .GetResult());
 }
Example #5
0
        /// <summary>
        /// Asynchronously sends an analytics request to the server.
        /// </summary>
        /// <typeparam name="T">The <see cref="Type" /> T of the body for each row (or document) result.</typeparam>
        /// <param name="analyticsRequest">The analytics request.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public Task <IAnalyticsResult <T> > SendAsync <T>(IAnalyticsRequest analyticsRequest, CancellationToken cancellationToken)
        {
            Task <IAnalyticsResult <T> > result;

            if (_isDown)
            {
                result = Task.FromResult(HandleNodeUnavailable <T>(analyticsRequest));
            }
            else
            {
                try
                {
                    result = AnalyticsClient.QueryAsync <T>(analyticsRequest, cancellationToken);
                }
                catch (Exception exception)
                {
                    result = Task.FromResult <IAnalyticsResult <T> >(new AnalyticsResult <T>
                    {
                        Exception = exception,
                        Message   = exception.Message,
                        Success   = false,
                    });
                }
            }
            return(result);
        }
        /// <summary>
        /// Asynchronously sends an <see cref="IAnalyticsResult{T}"/> to the server to be executed.
        /// </summary>
        /// <typeparam name="T">The Type T of the body of each result row.</typeparam>
        /// <param name="request">The <see cref="IAnalyticsRequest"/> object to send to the server.</param>
        /// <param name="cancellationToken">Token which can cancel the analytics request.</param>
        /// <returns>An <see cref="Task{IAnalyticsRequest}"/> object to be awaited on that is the result of the analytics request.</returns>
        /// <exception cref="ServiceNotSupportedException">The cluster does not support analytics services.</exception>
        public override async Task <IAnalyticsResult <T> > SendWithRetryAsync <T>(IAnalyticsRequest request, CancellationToken cancellationToken)
        {
            IAnalyticsResult <T> result;

            try
            {
                EnsureServiceAvailable(ConfigInfo.IsAnalyticsCapable, "Analytics");

                // Ugly but prevents Lifespan being public
                ((AnalyticsRequest)request).ConfigureLifespan(ConfigInfo.ClientConfig.QueryRequestTimeout);

                result = await RetryRequestAsync(
                    ConfigInfo.GetAnalyticsNode,
                    (server, req, token) => server.SendAsync <T>(req, token),
                    (req, res) => !(res.Success || req.TimedOut()) && res.ShouldRetry(),
                    request,
                    cancellationToken,
                    (int)ConfigInfo.ClientConfig.AnalyticsRequestTimeout
                    ).ContinueOnAnyContext();
            }
            catch (Exception exception)
            {
                Log.Info(exception);
                result = CreateFailedAnalyticsResult <T>(exception);
            }
            return(result);
        }
Example #7
0
 internal static ISpanBuilder BuildSpan(this ITracer tracer, IAnalyticsRequest request, string operationName)
 {
     return(tracer.BuildSpan(operationName)
            .WithTag(CouchbaseTags.OperationId, request.CurrentContextId)
            .WithTag(CouchbaseTags.Service, CouchbaseTags.ServiceAnalytics)
            .WithTag(Tags.DbStatement, request.OriginalStatement)
            .AsChildOf(request.ActiveSpan));
 }
 public static string GetParametersAsJson(this IAnalyticsRequest request)
 {
     if (request.PositionalArguments.Any())
     {
         return(JsonConvert.SerializeObject(request.PositionalArguments));
     }
     return(JsonConvert.SerializeObject(request.NamedParameters));
 }
Example #9
0
        internal static IRequestSpan WithOperationId(this IRequestSpan span, IAnalyticsRequest request)
        {
            if (span.CanWrite)
            {
                span.SetAttribute(InnerRequestSpans.DispatchSpan.Attributes.OperationId, request.ClientContextId ?? Guid.NewGuid().ToString());
            }

            return(span);
        }
Example #10
0
        /// <summary>
        /// Queries the asynchronous.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queryRequest">The query request.</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        public async Task <IAnalyticsResult <T> > QueryAsync <T>(IAnalyticsRequest queryRequest, CancellationToken token)
        {
            var result = new AnalyticsResult <T>();

            FailureCountingUri baseUri;

            if (!TryGetUri(result, out baseUri))
            {
                return(result);
            }

            ApplyCredentials(queryRequest, ClientConfiguration);

            using (var content = new StringContent(queryRequest.GetFormValuesAsJson(), System.Text.Encoding.UTF8, MediaType.Json))
            {
                try
                {
                    Log.Trace("Sending analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                    var request = await HttpClient.PostAsync(baseUri, content, token).ContinueOnAnyContext();

                    using (var response = await request.Content.ReadAsStreamAsync().ContinueOnAnyContext())
                    {
                        result                = DataMapper.Map <AnalyticsResultData <T> >(response).ToQueryResult();
                        result.Success        = result.Status == QueryStatus.Success;
                        result.HttpStatusCode = request.StatusCode;
                        Log.Trace("Received analytics query cid{0}: {1}", result.ClientContextId, result.ToString());
                    }
                    baseUri.ClearFailed();
                }
                catch (HttpRequestException e)
                {
                    Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                    baseUri.IncrementFailed();
                    ProcessError(e, result);
                    Log.Error(e);
                }
                catch (AggregateException ae)
                {
                    ae.Flatten().Handle(e =>
                    {
                        Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                        ProcessError(e, result);
                        return(true);
                    });
                }
                catch (Exception e)
                {
                    Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                    Log.Info(e);
                    ProcessError(e, result);
                }
            }

            UpdateLastActivity();

            return(result);
        }
        private IRequestSpan RootSpan(string operation, IAnalyticsRequest analyticsRequest)
        {
            var span = _tracer.RequestSpan(operation);

            span.SetAttribute(OuterRequestSpans.Attributes.System.Key, OuterRequestSpans.Attributes.System.Value);
            span.SetAttribute(OuterRequestSpans.Attributes.Service, nameof(OuterRequestSpans.ServiceSpan.AnalyticsQuery).ToLowerInvariant());
            span.SetAttribute(OuterRequestSpans.Attributes.BucketName, analyticsRequest.BucketName);
            span.SetAttribute(OuterRequestSpans.Attributes.ScopeName, analyticsRequest.ScopeName);
            span.SetAttribute(OuterRequestSpans.Attributes.Operation, operation);
            return(span);
        }
Example #12
0
        internal static IRequestSpan DispatchSpan(this IRequestSpan parentSpan, IAnalyticsRequest request)
        {
            var childSpan = DispatchSpan(parentSpan);

            if (childSpan.CanWrite)
            {
                childSpan.SetAttribute(InnerRequestSpans.DispatchSpan.Attributes.OperationId, request.ClientContextId ?? Guid.NewGuid().ToString());
            }

            return(childSpan);
        }
 private static void ApplyCredentials(IAnalyticsRequest request, ClientConfiguration config)
 {
     if (config.HasCredentials)
     {
         var creds = config.GetCredentials(AuthContext.ClusterAnalytics);
         foreach (var cred in creds)
         {
             request.Credentials(cred.Key, cred.Value, false);
         }
     }
 }
Example #14
0
        /// <summary>
        /// Creates a failure result for an <see cref="IAnalyticsResult{T}"/> when a node is not available.
        /// </summary>
        /// <typeparam name="T">The target type for result rows to deserialize into.</typeparam>
        /// <param name="request">The analytics request.</param>
        /// <returns></returns>
        private IAnalyticsResult <T> HandleNodeUnavailable <T>(IAnalyticsRequest request)
        {
            var msg = ExceptionUtil.GetNodeUnavailableMsg(EndPoint, _clientConfiguration.NodeAvailableCheckInterval);

            return(new AnalyticsResult <T>
            {
                Exception = new NodeUnavailableException(msg),
                Success = false,
                Status = QueryStatus.Fatal
            });
        }
Example #15
0
        internal static IScope StartParentScope(this ITracer tracer, IAnalyticsRequest request, bool addIgnoreTag = false)
        {
            var builder = tracer.BuildSpan(request);

            if (addIgnoreTag)
            {
                builder.WithIgnoreTag();
            }

            return(builder.StartActive());
        }
Example #16
0
        internal static ISpan StartParentSpan(this ITracer tracer, IAnalyticsRequest request, bool addIgnoreTag = false)
        {
            var builder = tracer.BuildSpan(request);

            if (addIgnoreTag)
            {
                builder.WithIgnoreTag();
            }

            var span = builder.Start();

            request.ActiveSpan = span;

            return(span);
        }
        public override void OnEntry(MethodExecutionArgs args)
        {
            IAnalyticsRequest request = ServerAnalytics.CurrentRequest;

            if (request != null)
            {
                ITimedAnalyticsEvent timedEvent;
                if (this.IncludeArguments)
                {
                    List <KeyValuePair <string, object> > arguments = new List <KeyValuePair <string, object> >();
                    for (int i = 0; i < this.parameterNames.Length; i++)
                    {
                        arguments.Add(new KeyValuePair <string, object>(this.parameterNames[i], args.Arguments[i]));
                    }
                    timedEvent = request.StartTimedEvent(this.methodPath, arguments);
                }
                else
                {
                    timedEvent = request.StartTimedEvent(this.methodPath);
                }

                args.MethodExecutionTag = timedEvent;
            }
        }
 public Task <IAnalyticsResult <T> > SendAsync <T>(IAnalyticsRequest analyticsRequest, CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
 public IAnalyticsResult <T> Send <T>(IAnalyticsRequest analyticsRequest)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Queries the asynchronous.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queryRequest">The query request.</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        public async Task <IAnalyticsResult <T> > QueryAsync <T>(IAnalyticsRequest queryRequest, CancellationToken token)
        {
            // try get Analytics node
            if (!ClusterOptions.GlobalNodes.TryGetRandom(x => x.HasAnalytics(), out var node))
            {
                //const string noNodeAvailableMessage = "Unable to locate analytics node to submit query to.";
                //Logger.LogError(noNodeAvailableMessage);
                throw new ServiceNotAvailableException(ServiceType.Analytics);
            }

            var result = new AnalyticsResult <T>();

            string body;

            //using (ClientConfiguration.Tracer.BuildSpan(queryRequest, CouchbaseOperationNames.RequestEncoding).StartActive())
            //{
            body = queryRequest.GetFormValuesAsJson();
            //}

            using (var content = new StringContent(body, System.Text.Encoding.UTF8, MediaType.Json))
            {
                try
                {
                    //Log.Trace("Sending analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);

                    HttpResponseMessage response;
                    //using (ClientConfiguration.Tracer.BuildSpan(queryRequest, CouchbaseOperationNames.DispatchToServer).StartActive())
                    //{
                    var request = new HttpRequestMessage(HttpMethod.Post, node.AnalyticsUri)
                    {
                        Content = content
                    };

                    if (queryRequest is AnalyticsRequest req && req.PriorityValue != 0)
                    {
                        request.Headers.Add(AnalyticsPriorityHeaderName, new[] { req.PriorityValue.ToString() });
                    }

                    response = await HttpClient.SendAsync(request, token).ConfigureAwait(false);

                    //}

                    //using (var scope = ClientConfiguration.Tracer.BuildSpan(queryRequest, CouchbaseOperationNames.ResponseDecoding).StartActive())
                    using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    {
                        result = DataMapper.Map <AnalyticsResultData <T> >(stream).ToQueryResult(HttpClient, DataMapper);
                        //result.MetaData.Success = result.MetaData.Status == QueryStatus.Success || result.MetaData.Status == QueryStatus.Running;
                        result.MetaData.HttpStatusCode = response.StatusCode;
                        //Log.Trace("Received analytics query cid{0}: {1}", result.ClientContextId, result.ToString());

                        //scope.Span.SetPeerLatencyTag(result.Metrics.ElaspedTime);
                    }
                    //uri.ClearFailed();analytu
                }
                catch (OperationCanceledException e)
                {
                    //var operationContext = OperationContext.CreateAnalyticsContext(queryRequest.CurrentContextId, Context.BucketName, uri?.Authority);
                    //if (queryRequest is AnalyticsRequest request)
                    //{
                    //    operationContext.TimeoutMicroseconds = request.TimeoutValue;
                    //}

                    //Log.Info(operationContext.ToString());
                    ProcessError(e, result);
                }
                catch (HttpRequestException e)
                {
                    //Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                    //uri.IncrementFailed();
                    ProcessError(e, result);
                    //Log.Error(e);
                }
                catch (AggregateException ae)
                {
                    ae.Flatten().Handle(e =>
                    {
                        //Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                        //Log.Error(e);
                        ProcessError(e, result);
                        return(true);
                    });
                }
                catch (Exception e)
                {
                    //Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                    //Log.Info(e);
                    ProcessError(e, result);
                }
            }

            UpdateLastActivity();

            return(result);
        }
Example #21
0
        internal static ISpanBuilder BuildSpan(this ITracer tracer, IAnalyticsRequest request)
        {
            const string operationName = "cbas";

            return(tracer.BuildSpan(request, operationName));
        }
Example #22
0
        public async Task <IAnalyticsResult <T> > QueryAsync <T>(IAnalyticsRequest queryRequest, CancellationToken token = default)
        {
            // try get Analytics node
            var analyticsUri = _serviceUriProvider.GetRandomAnalyticsUri();
            AnalyticsResultBase <T> result;
            var body = queryRequest.GetFormValuesAsJson();

            using (var content = new StringContent(body, Encoding.UTF8, MediaType.Json))
            {
                try
                {
                    var request = new HttpRequestMessage(HttpMethod.Post, analyticsUri)
                    {
                        Content = content
                    };

                    if (queryRequest is AnalyticsRequest req && req.PriorityValue != 0)
                    {
                        request.Headers.Add(AnalyticsPriorityHeaderName, new[] { req.PriorityValue.ToString() });
                    }

                    var response = await HttpClient.SendAsync(request, token).ConfigureAwait(false);

                    var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

                    if (_typeSerializer is IStreamingTypeDeserializer streamingTypeDeserializer)
                    {
                        result = new StreamingAnalyticsResult <T>(stream, streamingTypeDeserializer)
                        {
                            HttpStatusCode = response.StatusCode
                        };
                    }
                    else
                    {
                        result = new BlockAnalyticsResult <T>(stream, _typeSerializer)
                        {
                            HttpStatusCode = response.StatusCode
                        };
                    }

                    await result.InitializeAsync(token).ConfigureAwait(false);

                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        if (result.ShouldRetry())
                        {
                            UpdateLastActivity();
                            return(result);
                        }

                        if (result.LinkNotFound())
                        {
                            throw new LinkNotFoundException();
                        }
                        if (result.DataverseExists())
                        {
                            throw new DataverseExistsException();
                        }
                        if (result.DatasetExists())
                        {
                            throw new DatasetExistsException();
                        }
                        if (result.DataverseNotFound())
                        {
                            throw new DataverseNotFoundException();
                        }
                        if (result.DataSetNotFound())
                        {
                            throw new DatasetNotFoundException();
                        }
                        if (result.JobQueueFull())
                        {
                            throw new JobQueueFullException();
                        }
                        if (result.CompilationFailure())
                        {
                            throw new CompilationFailureException();
                        }
                        if (result.InternalServerFailure())
                        {
                            throw new InternalServerFailureException();
                        }
                        if (result.AuthenticationFailure())
                        {
                            throw new AuthenticationFailureException();
                        }
                        if (result.TemporaryFailure())
                        {
                            throw new TemporaryFailureException();
                        }
                        if (result.ParsingFailure())
                        {
                            throw new ParsingFailureException();
                        }
                        if (result.IndexNotFound())
                        {
                            throw new IndexNotFoundException();
                        }
                        if (result.IndexExists())
                        {
                            throw new IndexExistsException();
                        }
                    }
                }
                catch (OperationCanceledException e)
                {
                    _logger.LogDebug(LoggingEvents.AnalyticsEvent, e, "Analytics request timeout.");
                    if (queryRequest.ReadOnly)
                    {
                        throw new UnambiguousTimeoutException("The query was timed out via the Token.", e);
                    }

                    throw new AmbiguousTimeoutException("The query was timed out via the Token.", e);
                }
                catch (HttpRequestException e)
                {
                    _logger.LogDebug(LoggingEvents.AnalyticsEvent, e, "Analytics request cancelled.");
                    throw new RequestCanceledException("The query was canceled.", e);
                }
            }

            UpdateLastActivity();
            return(result);
        }
Example #23
0
        /// <summary>
        /// Queries the asynchronous.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queryRequest">The query request.</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        public async Task <IAnalyticsResult <T> > QueryAsync <T>(IAnalyticsRequest queryRequest, CancellationToken token)
        {
            var result = new AnalyticsResult <T>();

            FailureCountingUri baseUri;

            if (!TryGetUri(result, out baseUri))
            {
                return(result);
            }

            ApplyCredentials(queryRequest, ClientConfiguration);

            string body;

            using (ClientConfiguration.Tracer.BuildSpan(queryRequest, CouchbaseOperationNames.RequestEncoding).StartActive())
            {
                body = queryRequest.GetFormValuesAsJson();
            }

            using (var content = new StringContent(body, System.Text.Encoding.UTF8, MediaType.Json))
            {
                try
                {
                    Log.Trace("Sending analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);

                    HttpResponseMessage response;
                    using (ClientConfiguration.Tracer.BuildSpan(queryRequest, CouchbaseOperationNames.DispatchToServer).StartActive())
                    {
                        var request = new HttpRequestMessage(HttpMethod.Post, baseUri)
                        {
                            Content = content
                        };

                        if (queryRequest is AnalyticsRequest req && req.PriorityValue != 0)
                        {
                            request.Headers.Add(AnalyticsPriorityHeaderName, new[] { req.PriorityValue.ToString() });
                        }

                        response = await HttpClient.SendAsync(request, token).ContinueOnAnyContext();
                    }

                    using (var scope = ClientConfiguration.Tracer.BuildSpan(queryRequest, CouchbaseOperationNames.ResponseDecoding).StartActive())
                        using (var stream = await response.Content.ReadAsStreamAsync().ContinueOnAnyContext())
                        {
                            result                = DataMapper.Map <AnalyticsResultData <T> >(stream).ToQueryResult();
                            result.Success        = result.Status == QueryStatus.Success;
                            result.HttpStatusCode = response.StatusCode;
                            Log.Trace("Received analytics query cid{0}: {1}", result.ClientContextId, result.ToString());

                            scope.Span.SetPeerLatencyTag(result.Metrics.ElaspedTime);
                        }
                    baseUri.ClearFailed();
                }
                catch (OperationCanceledException e)
                {
                    var operationContext = OperationContext.CreateAnalyticsContext(queryRequest.CurrentContextId, Context.BucketName, baseUri?.Authority);
                    if (queryRequest is AnalyticsRequest request)
                    {
                        operationContext.TimeoutMicroseconds = request.TimeoutValue;
                    }

                    Log.Info(operationContext.ToString());
                    ProcessError(e, result);
                }
                catch (HttpRequestException e)
                {
                    Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                    baseUri.IncrementFailed();
                    ProcessError(e, result);
                    Log.Error(e);
                }
                catch (AggregateException ae)
                {
                    ae.Flatten().Handle(e =>
                    {
                        Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                        ProcessError(e, result);
                        return(true);
                    });
                }
                catch (Exception e)
                {
                    Log.Info("Failed analytics query cid{0}: {1}", queryRequest.CurrentContextId, baseUri);
                    Log.Info(e);
                    ProcessError(e, result);
                }
            }

            UpdateLastActivity();

            return(result);
        }
        /// <summary>
        /// Executes a query and ingests the results as documents into Couchbase server for further analytics.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="bucket"></param>
        /// <param name="request"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public static async Task <IList <IOperationResult <T> > > IngestAsync <T>(this IBucket bucket, IAnalyticsRequest request, IngestOptions options = null)
        {
            //use defaults if not options not explicitly passed
            options = options ?? new IngestOptions();

            if (options.CancellationTokenValue.IsCancellationRequested)
            {
                options.CancellationTokenValue.ThrowIfCancellationRequested();
            }

            //execute the analytics query
            var analyticsResult =
                await bucket.QueryAsync <T>(request, options.CancellationTokenValue).ContinueOnAnyContext();

            //the initial analytics query has failed so immediately abort
            if (!analyticsResult.Success)
            {
                throw new AnalyticsException(analyticsResult.Message, analyticsResult.Exception)
                      {
                          Errors = analyticsResult.Errors
                      };
            }

            //use the IngestMethod
            var results = new ConcurrentBag <Task <IOperationResult <T> > >();

            foreach (var row in analyticsResult.Rows)
            {
                Task <IOperationResult <T> > op;
                switch (options.IngestMethodValue)
                {
                case IngestMethod.Insert:
                    op = bucket.InsertAsync(options.IdGeneratorValue(row), row, options.ExpirationValue, options.TimeoutValue);
                    break;

                case IngestMethod.Upsert:
                    op = bucket.UpsertAsync(options.IdGeneratorValue(row), row, options.ExpirationValue, options.TimeoutValue);
                    break;

                case IngestMethod.Replace:
                    op = bucket.ReplaceAsync(options.IdGeneratorValue(row), row, options.ExpirationValue, options.TimeoutValue);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                results.Add(op);
            }

            return(await Task.WhenAll(results).ContinueOnAnyContext());
        }
Example #25
0
 public virtual IAnalyticsResult <T> SendWithRetry <T>(IAnalyticsRequest queryRequest)
 {
     throw new NotImplementedException();
 }
Example #26
0
 public virtual Task <IAnalyticsResult <T> > SendWithRetryAsync <T>(IAnalyticsRequest queryRequest, CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
Example #27
0
        public async Task <IAnalyticsResult <T> > QueryAsync <T>(IAnalyticsRequest queryRequest, CancellationToken token = default)
        {
            using var rootSpan = _tracer.RootSpan(RequestTracing.ServiceIdentifier.Analytics, OperationNames.AnalyticsQuery)
                                 .WithTag(CouchbaseTags.OperationId, queryRequest.ClientContextId ?? Guid.NewGuid().ToString())
                                 .WithLocalAddress();

            // try get Analytics node
            var analyticsUri = _serviceUriProvider.GetRandomAnalyticsUri();

            rootSpan.WithRemoteAddress(analyticsUri);

            _logger.LogDebug("Sending analytics query with a context id {contextId} to server {searchUri}",
                             queryRequest.ClientContextId, analyticsUri);

            using var encodingSpan = rootSpan.StartPayloadEncoding();

            AnalyticsResultBase <T> result;
            var body = queryRequest.GetFormValuesAsJson();

            using (var content = new StringContent(body, Encoding.UTF8, MediaType.Json))
            {
                try
                {
                    var request = new HttpRequestMessage(HttpMethod.Post, analyticsUri)
                    {
                        Content = content
                    };

                    if (queryRequest is AnalyticsRequest req && req.PriorityValue != 0)
                    {
                        request.Headers.Add(AnalyticsPriorityHeaderName, new[] { req.PriorityValue.ToString() });
                    }

                    encodingSpan.Dispose();
                    using var dispatchSpan = rootSpan.StartDispatch();
                    var response = await HttpClient.SendAsync(request, token).ConfigureAwait(false);

                    dispatchSpan.Dispose();
                    var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

                    if (_typeSerializer is IStreamingTypeDeserializer streamingTypeDeserializer)
                    {
                        result = new StreamingAnalyticsResult <T>(stream, streamingTypeDeserializer)
                        {
                            HttpStatusCode = response.StatusCode
                        };
                    }
                    else
                    {
                        result = new BlockAnalyticsResult <T>(stream, _typeSerializer)
                        {
                            HttpStatusCode = response.StatusCode
                        };
                    }

                    await result.InitializeAsync(token).ConfigureAwait(false);

                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        if (result.ShouldRetry())
                        {
                            UpdateLastActivity();
                            return(result);
                        }

                        var context = new AnalyticsErrorContext
                        {
                            ClientContextId = queryRequest.ClientContextId,
                            HttpStatus      = response.StatusCode,
                            Statement       = queryRequest.Statement,
                            Parameters      = queryRequest.GetParametersAsJson(),
                            Errors          = result.Errors
                        };

                        if (result.LinkNotFound())
                        {
                            throw new LinkNotFoundException(context);
                        }
                        if (result.DataverseExists())
                        {
                            throw new DataverseExistsException(context);
                        }
                        if (result.DatasetExists())
                        {
                            throw new DatasetExistsException();
                        }
                        if (result.DataverseNotFound())
                        {
                            throw new DataverseNotFoundException(context);
                        }
                        if (result.DataSetNotFound())
                        {
                            throw new DatasetNotFoundException(context);
                        }
                        if (result.JobQueueFull())
                        {
                            throw new JobQueueFullException(context);
                        }
                        if (result.CompilationFailure())
                        {
                            throw new CompilationFailureException(context);
                        }
                        if (result.InternalServerFailure())
                        {
                            throw new InternalServerFailureException(context);
                        }
                        if (result.AuthenticationFailure())
                        {
                            throw new AuthenticationFailureException(context);
                        }
                        if (result.TemporaryFailure())
                        {
                            throw new TemporaryFailureException(context);
                        }
                        if (result.ParsingFailure())
                        {
                            throw new ParsingFailureException(context);
                        }
                        if (result.IndexNotFound())
                        {
                            throw new IndexNotFoundException(context);
                        }
                        if (result.IndexExists())
                        {
                            throw new IndexExistsException(context);
                        }
                    }
                }
                catch (OperationCanceledException e)
                {
                    var context = new AnalyticsErrorContext
                    {
                        ClientContextId = queryRequest.ClientContextId,
                        Statement       = queryRequest.Statement,
                        Parameters      = queryRequest.GetParametersAsJson()
                    };

                    _logger.LogDebug(LoggingEvents.AnalyticsEvent, e, "Analytics request timeout.");
                    if (queryRequest.ReadOnly)
                    {
                        throw new UnambiguousTimeoutException("The query was timed out via the Token.", e)
                              {
                                  Context = context
                              };
                    }

                    throw new AmbiguousTimeoutException("The query was timed out via the Token.", e)
                          {
                              Context = context
                          };
                }
                catch (HttpRequestException e)
                {
                    var context = new AnalyticsErrorContext
                    {
                        ClientContextId = queryRequest.ClientContextId,
                        Statement       = queryRequest.Statement,
                        Parameters      = queryRequest.GetParametersAsJson()
                    };

                    _logger.LogDebug(LoggingEvents.AnalyticsEvent, e, "Analytics request cancelled.");
                    throw new RequestCanceledException("The query was canceled.", e)
                          {
                              Context = context
                          };
                }
            }

            UpdateLastActivity();
            return(result);
        }