Пример #1
0
        public AsyncCollection(IProducerConsumerCollection <T> collection, int boundingCapacity)
        {
            if (collection == null)
            {
                throw new ArgumentNullException("collection");
            }

            if (boundingCapacity < 1)
            {
                throw new ArgumentOutOfRangeException("boundedCapacity is not a positive value.");
            }

            int count = collection.Count;

            if (boundingCapacity < count)
            {
                throw new ArgumentOutOfRangeException("boundedCapacity is less than the size of collection.");
            }

            this.collection       = collection;
            this.boundingCapacity = boundingCapacity;
            this.notFull          = this.IsUnbounded ? null : new SemaphoreSlim(boundingCapacity - count, boundingCapacity);
            this.notEmpty         = new SemaphoreSlim(count);
            MethodInfo tryPeekMethod = this.collection.GetType().GetMethod("TryPeek", BindingFlags.Instance | BindingFlags.Public);

            this.tryPeekDelegate = tryPeekMethod == null ?
                                   null : (TryPeekDelegate)CustomTypeExtensions.CreateDelegate(typeof(TryPeekDelegate), this.collection, tryPeekMethod);
        }
        private unsafe void WriteEventCoreWithActivityId(Guid activityId, int eventId, int eventDataCount, EventSource.EventData *dataDesc)
        {
            // EventProvider's ActivityId is set on the current thread context (not on the CallContext), so it
            // must be explicitly be set before writing the event.
            CustomTypeExtensions.SetActivityId(ref activityId);

            this.WriteEventCore(eventId, eventDataCount, dataDesc);
        }
Пример #3
0
 public void ByPassQueryParsing()
 {
     if (IntPtr.Size == 8)
     {
         Assert.IsFalse(CustomTypeExtensions.ByPassQueryParsing());
     }
     else
     {
         Assert.IsTrue(CustomTypeExtensions.ByPassQueryParsing());
     }
 }
 private static bool ServiceInteropAvailable()
 {
     return(!CustomTypeExtensions.ByPassQueryParsing());
 }
Пример #5
0
 public override bool ByPassQueryParsing()
 {
     return(CustomTypeExtensions.ByPassQueryParsing());
 }
        public static async Task <IDocumentQueryExecutionContext> CreateDocumentQueryExecutionContextAsync(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            bool isContinuationExpected,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            ContainerProperties collection = null;

            if (resourceTypeEnum.IsCollectionChild())
            {
                CollectionCache collectionCache = await client.GetCollectionCacheAsync();

                using (
                    DocumentServiceRequest request = DocumentServiceRequest.Create(
                        OperationType.Query,
                        resourceTypeEnum,
                        resourceLink,
                        AuthorizationTokenType.Invalid)) //this request doesnt actually go to server
                {
                    collection = await collectionCache.ResolveCollectionAsync(request, token);
                }

                if (feedOptions != null && feedOptions.PartitionKey != null && feedOptions.PartitionKey.Equals(Documents.PartitionKey.None))
                {
                    feedOptions.PartitionKey = Documents.PartitionKey.FromInternalKey(collection.GetNoneValue());
                }
            }

            DocumentQueryExecutionContextBase.InitParams constructorParams = new DocumentQueryExecutionContextBase.InitParams(
                client,
                resourceTypeEnum,
                resourceType,
                expression,
                feedOptions,
                resourceLink,
                false,
                correlatedActivityId);

            // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop, so need to bypass in that case.
            // We are also now bypassing this for 32 bit host process running even on Windows as there are many 32 bit apps that will not work without this
            if (CustomTypeExtensions.ByPassQueryParsing())
            {
                // We create a ProxyDocumentQueryExecutionContext that will be initialized with DefaultDocumentQueryExecutionContext
                // which will be used to send the query to Gateway and on getting 400(bad request) with 1004(cross partition query not servable), we initialize it with
                // PipelinedDocumentQueryExecutionContext by providing the partition query execution info that's needed(which we get from the exception returned from Gateway).
                ProxyDocumentQueryExecutionContext proxyQueryExecutionContext =
                    ProxyDocumentQueryExecutionContext.Create(
                        client,
                        resourceTypeEnum,
                        resourceType,
                        expression,
                        feedOptions,
                        resourceLink,
                        token,
                        collection,
                        isContinuationExpected,
                        correlatedActivityId);

                return(proxyQueryExecutionContext);
            }

            DefaultDocumentQueryExecutionContext queryExecutionContext = await DefaultDocumentQueryExecutionContext.CreateAsync(
                constructorParams, isContinuationExpected, token);

            // If isContinuationExpected is false, we want to check if there are aggregates.
            if (
                resourceTypeEnum.IsCollectionChild() &&
                resourceTypeEnum.IsPartitioned() &&
                (feedOptions.EnableCrossPartitionQuery || !isContinuationExpected))
            {
                //todo:elasticcollections this may rely on information from collection cache which is outdated
                //if collection is deleted/created with same name.
                //need to make it not rely on information from collection cache.
                PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = await queryExecutionContext.GetPartitionedQueryExecutionInfoAsync(
                    partitionKeyDefinition : collection.PartitionKey,
                    requireFormattableOrderByQuery : true,
                    isContinuationExpected : isContinuationExpected,
                    allowNonValueAggregateQuery : true,
                    hasLogicalPartitionKey : feedOptions.PartitionKey != null,
                    cancellationToken : token);

                if (DocumentQueryExecutionContextFactory.ShouldCreateSpecializedDocumentQueryExecutionContext(
                        resourceTypeEnum,
                        feedOptions,
                        partitionedQueryExecutionInfo,
                        collection.PartitionKey,
                        isContinuationExpected))
                {
                    List <PartitionKeyRange> targetRanges = await GetTargetPartitionKeyRangesAsync(
                        queryExecutionContext,
                        partitionedQueryExecutionInfo,
                        collection,
                        feedOptions);

                    // Devnote this will get replace by the new v3 to v2 logic
                    throw new NotSupportedException("v2 query excution context is currently not supported.");
                }
            }

            return(queryExecutionContext);
        }
Пример #7
0
        private async Task <FeedResponse <dynamic> > ExecuteOnceAsync(IDocumentClientRetryPolicy retryPolicyInstance, CancellationToken cancellationToken)
        {
            // Don't reuse request, as the rest of client SDK doesn't reuse requests between retries.
            // The code leaves some temporary garbage in request (in RequestContext etc.),
            // which shold be erased during retries.
            using (DocumentServiceRequest request = await this.CreateRequestAsync())
            {
                if (retryPolicyInstance != null)
                {
                    retryPolicyInstance.OnBeforeSendRequest(request);
                }

                if (!string.IsNullOrEmpty(request.Headers[HttpConstants.HttpHeaders.PartitionKey]) ||
                    !request.ResourceType.IsPartitioned())
                {
                    return(await this.ExecuteRequestAsync(request, cancellationToken));
                }

                CollectionCache collectionCache = await this.Client.GetCollectionCacheAsync();

                CosmosContainerSettings collection =
                    await collectionCache.ResolveCollectionAsync(request, CancellationToken.None);

                if (!string.IsNullOrEmpty(base.PartitionKeyRangeId))
                {
                    request.RouteTo(new PartitionKeyRangeIdentity(collection.ResourceId, base.PartitionKeyRangeId));
                    return(await this.ExecuteRequestAsync(request, cancellationToken));
                }

                // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop for parsing the query,
                // so forcing the request through Gateway. We are also now by-passing this for 32-bit host process in NETFX on Windows
                // as the ServiceInterop dll is only available in 64-bit.
                if (CustomTypeExtensions.ByPassQueryParsing())
                {
                    request.UseGatewayMode = true;
                    return(await this.ExecuteRequestAsync(request, cancellationToken));
                }

                QueryPartitionProvider queryPartitionProvider = await this.Client.GetQueryPartitionProviderAsync(cancellationToken);

                IRoutingMapProvider routingMapProvider = await this.Client.GetRoutingMapProviderAsync();

                List <CompositeContinuationToken> suppliedTokens;
                Range <string> rangeFromContinuationToken =
                    this.partitionRoutingHelper.ExtractPartitionKeyRangeFromContinuationToken(request.Headers, out suppliedTokens);
                Tuple <PartitionRoutingHelper.ResolvedRangeInfo, IReadOnlyList <Range <string> > > queryRoutingInfo =
                    await this.TryGetTargetPartitionKeyRangeAsync(
                        request,
                        collection,
                        queryPartitionProvider,
                        routingMapProvider,
                        rangeFromContinuationToken,
                        suppliedTokens);

                if (request.IsNameBased && queryRoutingInfo == null)
                {
                    request.ForceNameCacheRefresh = true;
                    collection = await collectionCache.ResolveCollectionAsync(request, CancellationToken.None);

                    queryRoutingInfo = await this.TryGetTargetPartitionKeyRangeAsync(
                        request,
                        collection,
                        queryPartitionProvider,
                        routingMapProvider,
                        rangeFromContinuationToken,
                        suppliedTokens);
                }

                if (queryRoutingInfo == null)
                {
                    throw new NotFoundException($"{DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}: Was not able to get queryRoutingInfo even after resolve collection async with force name cache refresh to the following collectionRid: {collection.ResourceId} with the supplied tokens: {JsonConvert.SerializeObject(suppliedTokens)}");
                }

                request.RouteTo(new PartitionKeyRangeIdentity(collection.ResourceId, queryRoutingInfo.Item1.ResolvedRange.Id));

                FeedResponse <dynamic> response = await this.ExecuteRequestAsync(request, cancellationToken);

                if (!await this.partitionRoutingHelper.TryAddPartitionKeyRangeToContinuationTokenAsync(
                        response.Headers,
                        providedPartitionKeyRanges: queryRoutingInfo.Item2,
                        routingMapProvider: routingMapProvider,
                        collectionRid: collection.ResourceId,
                        resolvedRangeInfo: queryRoutingInfo.Item1))
                {
                    // Collection to which this request was resolved doesn't exist.
                    // Retry policy will refresh the cache and return NotFound.
                    throw new NotFoundException($"{DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}: Call to TryAddPartitionKeyRangeToContinuationTokenAsync failed to the following collectionRid: {collection.ResourceId} with the supplied tokens: {JsonConvert.SerializeObject(suppliedTokens)}");
                }

                return(response);
            }
        }
Пример #8
0
        public static async Task <IDocumentQueryExecutionContext> CreateDocumentQueryExecutionContextAsync(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            bool isContinuationExpected,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            DocumentQueryExecutionContextBase.InitParams constructorParams = new DocumentQueryExecutionContextBase.InitParams(
                client,
                resourceTypeEnum,
                resourceType,
                expression,
                feedOptions,
                resourceLink,
                false,
                correlatedActivityId);

            CosmosContainerSettings collection = null;

            if (resourceTypeEnum.IsCollectionChild())
            {
                CollectionCache collectionCache = await client.GetCollectionCacheAsync();

                using (
                    DocumentServiceRequest request = DocumentServiceRequest.Create(
                        OperationType.Query,
                        resourceTypeEnum,
                        resourceLink,
                        AuthorizationTokenType.Invalid)) //this request doesnt actually go to server
                {
                    collection = await collectionCache.ResolveCollectionAsync(request, token);
                }
            }

            // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop, so need to bypass in that case.
            // We are also now bypassing this for 32 bit host process running even on Windows as there are many 32 bit apps that will not work without this
            if (CustomTypeExtensions.ByPassQueryParsing())
            {
                // We create a ProxyDocumentQueryExecutionContext that will be initialized with DefaultDocumentQueryExecutionContext
                // which will be used to send the query to Gateway and on getting 400(bad request) with 1004(cross partition query not servable), we initialize it with
                // PipelinedDocumentQueryExecutionContext by providing the partition query execution info that's needed(which we get from the exception returned from Gateway).
                ProxyDocumentQueryExecutionContext proxyQueryExecutionContext =
                    ProxyDocumentQueryExecutionContext.CreateAsync(
                        client,
                        resourceTypeEnum,
                        resourceType,
                        expression,
                        feedOptions,
                        resourceLink,
                        token,
                        collection,
                        isContinuationExpected,
                        correlatedActivityId);

                return(proxyQueryExecutionContext);
            }

            DefaultDocumentQueryExecutionContext queryExecutionContext = await DefaultDocumentQueryExecutionContext.CreateAsync(
                constructorParams, isContinuationExpected, token);

            // If isContinuationExpected is false, we want to check if there are aggregates.
            if (
                resourceTypeEnum.IsCollectionChild() &&
                resourceTypeEnum.IsPartitioned() &&
                (feedOptions.EnableCrossPartitionQuery || !isContinuationExpected))
            {
                //todo:elasticcollections this may rely on information from collection cache which is outdated
                //if collection is deleted/created with same name.
                //need to make it not rely on information from collection cache.
                PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = await queryExecutionContext.GetPartitionedQueryExecutionInfoAsync(
                    collection.PartitionKey,
                    true,
                    isContinuationExpected,
                    token);

                if (DocumentQueryExecutionContextFactory.ShouldCreateSpecializedDocumentQueryExecutionContext(
                        resourceTypeEnum,
                        feedOptions,
                        partitionedQueryExecutionInfo,
                        collection.PartitionKey,
                        isContinuationExpected))
                {
                    List <PartitionKeyRange> targetRanges;
                    if (!string.IsNullOrEmpty(feedOptions.PartitionKeyRangeId))
                    {
                        targetRanges =
                            new List <PartitionKeyRange>
                        {
                            await queryExecutionContext.GetTargetPartitionKeyRangeById(
                                collection.ResourceId,
                                feedOptions.PartitionKeyRangeId)
                        };
                    }
                    else
                    {
                        List <Range <string> > queryRanges = partitionedQueryExecutionInfo.QueryRanges;
                        if (feedOptions.PartitionKey != null)
                        {
                            queryRanges = new List <Range <string> >
                            {
                                Range <string> .GetPointRange(
                                    feedOptions.PartitionKey.InternalKey.GetEffectivePartitionKeyString(
                                        collection.PartitionKey))
                            };
                        }

                        targetRanges =
                            await queryExecutionContext.GetTargetPartitionKeyRanges(collection.ResourceId, queryRanges);
                    }



                    return(await CreateSpecializedDocumentQueryExecutionContext(
                               constructorParams,
                               partitionedQueryExecutionInfo,
                               targetRanges,
                               collection.ResourceId,
                               isContinuationExpected,
                               token));
                }
            }

            return(queryExecutionContext);
        }
 public void ServiceInteropUsedByDefault()
 {
     // Test initialie does load CosmosClient
     Assert.IsFalse(CustomTypeExtensions.ByPassQueryParsing());
 }
Пример #10
0
        private static void ParseStringToIntPtr(SecureString secureString, IntPtr bytes, int allocationSize, out uint actualLength)
        {
            IntPtr unmanagedString = IntPtr.Zero;

            try
            {
                unmanagedString = CustomTypeExtensions.SecureStringToCoTaskMemAnsi(secureString);

                int currentReadOffset  = 0;
                int currentWriteOffset = 0;

                byte currentCharacter = 0;
                while (currentReadOffset < allocationSize &&
                       (currentCharacter = Marshal.ReadByte(unmanagedString, currentReadOffset)) != '\0')
                {
                    uint currentValue = 0;
                    int  nBits        = 0;
                    for (int i = 0; i < 4; i++)
                    {
                        if (currentReadOffset >= allocationSize)
                        {
                            break;
                        }

                        currentCharacter = Marshal.ReadByte(unmanagedString, currentReadOffset);
                        int valueOfCharacter = 0;
                        {
                            if (currentCharacter >= 'A' && currentCharacter <= 'Z')
                            {
                                valueOfCharacter = currentCharacter - 'A' + 0;    // 0 range starts at 'A'
                            }
                            else if (currentCharacter >= 'a' && currentCharacter <= 'z')
                            {
                                valueOfCharacter = currentCharacter - 'a' + 26;    // 26 range starts at 'a'
                            }
                            else if (currentCharacter >= '0' && currentCharacter <= '9')
                            {
                                valueOfCharacter = currentCharacter - '0' + 52;    // 52 range starts at '0'
                            }
                            else if (currentCharacter == '+')
                            {
                                valueOfCharacter = 62;
                            }
                            else if (currentCharacter == '/')
                            {
                                valueOfCharacter = 63;
                            }
                            else
                            {
                                valueOfCharacter = -1;
                            }
                        }

                        currentReadOffset++;
                        if (valueOfCharacter == -1)
                        {
                            // skip this char - be tolerant of Base64 encodings that insert CR/LF for legibility
                            i--;
                            continue;
                        }

                        currentValue <<= 6;
                        currentValue  |= (byte)valueOfCharacter;
                        nBits         += 6;
                    }

                    // Ensure space in the byte buffer attempting to write to it.
                    if (currentWriteOffset + (nBits / 8) > (allocationSize))
                    {
                        throw new ArgumentException("allocationSize");
                    }

                    // Serialize the collected value into the byte buffer, left to right
                    currentValue <<= 24 - nBits;
                    for (int i = 0; i < nBits / 8; i++)
                    {
                        Marshal.WriteByte(bytes, currentWriteOffset, (byte)((currentValue & 0x00ff0000) >> 16));
                        currentWriteOffset++;
                        currentValue <<= 8;
                    }
                }

                actualLength = (uint)currentWriteOffset;
            }
            finally
            {
                if (unmanagedString != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemAnsi(unmanagedString);
                    unmanagedString = IntPtr.Zero;
                }
            }
        }