private async Task <Tuple <PartitionRoutingHelper.ResolvedRangeInfo, IReadOnlyList <Range <string> > > > TryGetTargetPartitionKeyRangeAsync(
            DocumentServiceRequest request,
            ContainerProperties collection,
            QueryPartitionProvider queryPartitionProvider,
            IRoutingMapProvider routingMapProvider,
            Range <string> rangeFromContinuationToken,
            List <CompositeContinuationToken> suppliedTokens)
        {
            string version = request.Headers[HttpConstants.HttpHeaders.Version];

            version = string.IsNullOrEmpty(version) ? HttpConstants.Versions.CurrentVersion : version;

            bool enableCrossPartitionQuery = false;

            string enableCrossPartitionQueryHeader = request.Headers[HttpConstants.HttpHeaders.EnableCrossPartitionQuery];

            if (enableCrossPartitionQueryHeader != null)
            {
                if (!bool.TryParse(enableCrossPartitionQueryHeader, out enableCrossPartitionQuery))
                {
                    throw new BadRequestException(
                              string.Format(
                                  CultureInfo.InvariantCulture,
                                  RMResources.InvalidHeaderValue,
                                  enableCrossPartitionQueryHeader,
                                  HttpConstants.HttpHeaders.EnableCrossPartitionQuery));
                }
            }

            IReadOnlyList <Range <string> > providedRanges;

            if (!this.providedRangesCache.TryGetValue(collection.ResourceId, out providedRanges))
            {
                if (this.ShouldExecuteQueryRequest)
                {
                    FeedOptions            feedOptions = this.GetFeedOptions(null);
                    PartitionKeyDefinition partitionKeyDefinition;
                    if ((feedOptions.Properties != null) && feedOptions.Properties.TryGetValue(
                            DefaultDocumentQueryExecutionContext.InternalPartitionKeyDefinitionProperty,
                            out object partitionKeyDefinitionObject))
                    {
                        if (partitionKeyDefinitionObject is PartitionKeyDefinition definition)
                        {
                            partitionKeyDefinition = definition;
                        }
                        else
                        {
                            throw new ArgumentException(
                                      "partitionkeydefinition has invalid type",
                                      nameof(partitionKeyDefinitionObject));
                        }
                    }
                    else
                    {
                        partitionKeyDefinition = collection.PartitionKey;
                    }

                    providedRanges = PartitionRoutingHelper.GetProvidedPartitionKeyRanges(
                        (errorMessage) => new BadRequestException(errorMessage),
                        this.QuerySpec,
                        enableCrossPartitionQuery,
                        false,
                        this.isContinuationExpected,
                        false, //haslogicalpartitionkey
                        partitionKeyDefinition,
                        queryPartitionProvider,
                        version,
                        out QueryInfo queryInfo);
                }
                else if (request.Properties != null && request.Properties.TryGetValue(
                             WFConstants.BackendHeaders.EffectivePartitionKeyString,
                             out object effectivePartitionKey))
                {
                    if (effectivePartitionKey is string effectivePartitionKeyString)
                    {
                        providedRanges = new List <Range <string> >()
                        {
                            Range <string> .GetPointRange(effectivePartitionKeyString),
                        };
                    }
                    else
                    {
                        throw new ArgumentException(
                                  "EffectivePartitionKey must be a string",
                                  WFConstants.BackendHeaders.EffectivePartitionKeyString);
                    }
                }
                else
                {
                    providedRanges = new List <Range <string> >
                    {
                        new Range <string>(
                            PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                            PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                            true,
                            false)
                    };
                }

                this.providedRangesCache[collection.ResourceId] = providedRanges;
            }

            PartitionRoutingHelper.ResolvedRangeInfo resolvedRangeInfo = await this.partitionRoutingHelper.TryGetTargetRangeFromContinuationTokenRangeAsync(
                providedRanges,
                routingMapProvider,
                collection.ResourceId,
                rangeFromContinuationToken,
                suppliedTokens);

            if (resolvedRangeInfo.ResolvedRange == null)
            {
                return(null);
            }
            else
            {
                return(Tuple.Create(resolvedRangeInfo, providedRanges));
            }
        }
Beispiel #2
0
        private async Task <Tuple <PartitionRoutingHelper.ResolvedRangeInfo, IReadOnlyList <Range <string> > > > TryGetTargetPartitionKeyRangeAsync(
            DocumentServiceRequest request,
            CosmosContainerSettings collection,
            QueryPartitionProvider queryPartitionProvider,
            IRoutingMapProvider routingMapProvider,
            Range <string> rangeFromContinuationToken,
            List <CompositeContinuationToken> suppliedTokens)
        {
            string version = request.Headers[HttpConstants.HttpHeaders.Version];

            version = string.IsNullOrEmpty(version) ? HttpConstants.Versions.CurrentVersion : version;

            bool enableCrossPartitionQuery = false;

            string enableCrossPartitionQueryHeader = request.Headers[HttpConstants.HttpHeaders.EnableCrossPartitionQuery];

            if (enableCrossPartitionQueryHeader != null)
            {
                if (!bool.TryParse(enableCrossPartitionQueryHeader, out enableCrossPartitionQuery))
                {
                    throw new BadRequestException(
                              string.Format(
                                  CultureInfo.InvariantCulture,
                                  RMResources.InvalidHeaderValue,
                                  enableCrossPartitionQueryHeader,
                                  HttpConstants.HttpHeaders.EnableCrossPartitionQuery));
                }
            }

            IReadOnlyList <Range <string> > providedRanges;

            if (!this.providedRangesCache.TryGetValue(collection.ResourceId, out providedRanges))
            {
                if (this.ShouldExecuteQueryRequest)
                {
                    QueryInfo queryInfo;
                    providedRanges = PartitionRoutingHelper.GetProvidedPartitionKeyRanges(
                        this.QuerySpec,
                        enableCrossPartitionQuery,
                        false,
                        isContinuationExpected,
                        collection.PartitionKey,
                        queryPartitionProvider,
                        version,
                        out queryInfo);
                }
                else
                {
                    providedRanges = new List <Range <string> >
                    {
                        new Range <string>(
                            PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                            PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                            true,
                            false)
                    };
                }

                this.providedRangesCache[collection.ResourceId] = providedRanges;
            }

            PartitionRoutingHelper.ResolvedRangeInfo resolvedRangeInfo = await this.partitionRoutingHelper.TryGetTargetRangeFromContinuationTokenRange(
                providedRanges,
                routingMapProvider,
                collection.ResourceId,
                rangeFromContinuationToken,
                suppliedTokens);

            if (resolvedRangeInfo.ResolvedRange == null)
            {
                return(null);
            }
            else
            {
                return(Tuple.Create(resolvedRangeInfo, providedRanges));
            }
        }