public static IReadOnlyList <Range <string> > GetProvidedPartitionKeyRanges(
            SqlQuerySpec querySpec,
            bool enableCrossPartitionQuery,
            bool parallelizeCrossPartitionQuery,
            bool isContinuationExpected,
            PartitionKeyDefinition partitionKeyDefinition,
            QueryPartitionProvider queryPartitionProvider,
            string clientApiVersion,
            out QueryInfo queryInfo)
        {
            if (querySpec == null)
            {
                throw new ArgumentNullException("querySpec");
            }

            if (partitionKeyDefinition == null)
            {
                throw new ArgumentNullException("partitionKeyDefinition");
            }

            if (queryPartitionProvider == null)
            {
                throw new ArgumentNullException("queryPartitionProvider");
            }

            PartitionedQueryExecutionInfo queryExecutionInfo = null;

            queryExecutionInfo = queryPartitionProvider.GetPartitionedQueryExecutionInfo(
                querySpec: querySpec,
                partitionKeyDefinition: partitionKeyDefinition,
                requireFormattableOrderByQuery: VersionUtility.IsLaterThan(clientApiVersion, HttpConstants.Versions.v2016_11_14),
                isContinuationExpected: isContinuationExpected,
                allowNonValueAggregateQuery: false);

            if (queryExecutionInfo == null ||
                queryExecutionInfo.QueryRanges == null ||
                queryExecutionInfo.QueryInfo == null ||
                queryExecutionInfo.QueryRanges.Any(range => range.Min == null || range.Max == null))
            {
                DefaultTrace.TraceInformation("QueryPartitionProvider returned bad query info");
            }

            bool isSinglePartitionQuery = queryExecutionInfo.QueryRanges.Count == 1 && queryExecutionInfo.QueryRanges[0].IsSingleValue;

            bool queryFansOutToMultiplePartitions = partitionKeyDefinition.Paths.Count > 0 && !isSinglePartitionQuery;

            if (queryFansOutToMultiplePartitions)
            {
                if (!enableCrossPartitionQuery)
                {
                    throw new BadRequestException(RMResources.CrossPartitionQueryDisabled);
                }
                else
                {
                    bool queryNotServiceableByGateway = parallelizeCrossPartitionQuery ||
                                                        queryExecutionInfo.QueryInfo.HasTop ||
                                                        queryExecutionInfo.QueryInfo.HasOrderBy ||
                                                        queryExecutionInfo.QueryInfo.HasAggregates ||
                                                        queryExecutionInfo.QueryInfo.HasDistinct ||
                                                        queryExecutionInfo.QueryInfo.HasOffset ||
                                                        queryExecutionInfo.QueryInfo.HasLimit;

                    if (queryNotServiceableByGateway)
                    {
                        if (!IsSupportedPartitionedQueryExecutionInfo(queryExecutionInfo, clientApiVersion))
                        {
                            throw new BadRequestException(RMResources.UnsupportedCrossPartitionQuery);
                        }
                        else if (queryExecutionInfo.QueryInfo.HasAggregates && !IsAggregateSupportedApiVersion(clientApiVersion))
                        {
                            throw new BadRequestException(RMResources.UnsupportedCrossPartitionQueryWithAggregate);
                        }
                        else
                        {
                            DocumentClientException exception = new DocumentClientException(
                                RMResources.UnsupportedCrossPartitionQuery,
                                HttpStatusCode.BadRequest,
                                SubStatusCodes.CrossPartitionQueryNotServable);

                            exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                            throw exception;
                        }
                    }
                }
            }
            else
            {
                if (queryExecutionInfo.QueryInfo.HasAggregates && !isContinuationExpected)
                {
                    // For single partition query with aggregate functions and no continuation expected,
                    // we would try to accumulate the results for them on the SDK, if supported.

                    if (IsAggregateSupportedApiVersion(clientApiVersion))
                    {
                        DocumentClientException exception = new DocumentClientException(
                            RMResources.UnsupportedQueryWithFullResultAggregate,
                            HttpStatusCode.BadRequest,
                            SubStatusCodes.CrossPartitionQueryNotServable);

                        exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                        throw exception;
                    }
                    else
                    {
                        throw new BadRequestException(RMResources.UnsupportedQueryWithFullResultAggregate);
                    }
                }
                else if (queryExecutionInfo.QueryInfo.HasDistinct)
                {
                    // If the query has distinct then we have to reject it since the backend only returns
                    // elements that are distinct within a page and we need the client to do post distinct processing
                    DocumentClientException exception = new DocumentClientException(
                        RMResources.UnsupportedCrossPartitionQuery,
                        HttpStatusCode.BadRequest,
                        SubStatusCodes.CrossPartitionQueryNotServable);

                    exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                    throw exception;
                }
            }

            queryInfo = queryExecutionInfo.QueryInfo;
            return(queryExecutionInfo.QueryRanges);
        }
示例#2
0
        public async Task <DocumentCollection> CreateTargetDocumentCollection(DocumentClient targetClient, IndexingPolicy indexingPolicy, PartitionKeyDefinition partitionKeyDefinition)
        {
            try
            {
                //var targetCosmosDBSettings = CloneSettings.GetConfigurationSection("TargetCosmosDBSettings");
                string targetDatabaseName   = CloneSettings.TargetSettings.DatabaseName;
                string targetCollectionName = CloneSettings.TargetSettings.CollectionName;

                await targetClient.CreateDatabaseIfNotExistsAsync(new Database { Id = targetDatabaseName });

                DocumentCollection newDocumentCollection;
                if (partitionKeyDefinition != null && partitionKeyDefinition.Paths.Count > 0)
                {
                    if (CloneSettings.CopyPartitionKey)
                    {
                        // Partition key exists in Source (Unlimited Storage)
                        newDocumentCollection = (DocumentCollection)await targetClient.CreateDocumentCollectionIfNotExistsAsync
                                                    (UriFactory.CreateDatabaseUri(targetDatabaseName),
                                                    new DocumentCollection { Id = targetCollectionName, PartitionKey = partitionKeyDefinition, IndexingPolicy = indexingPolicy },
                                                    new RequestOptions { OfferEnableRUPerMinuteThroughput = true, OfferThroughput = CloneSettings.TargetMigrationOfferThroughputRUs });
                    }
                    else
                    {
                        newDocumentCollection = (DocumentCollection)await targetClient.CreateDocumentCollectionIfNotExistsAsync
                                                    (UriFactory.CreateDatabaseUri(targetDatabaseName),
                                                    new DocumentCollection { Id = targetCollectionName, IndexingPolicy = indexingPolicy },
                                                    new RequestOptions { OfferEnableRUPerMinuteThroughput = true, OfferThroughput = CloneSettings.TargetMigrationOfferThroughputRUs });
                    }
                }
                else
                {   //no partition key set in source (Fixed storage)
                    newDocumentCollection = (DocumentCollection)await targetClient.CreateDocumentCollectionIfNotExistsAsync
                                                (UriFactory.CreateDatabaseUri(targetDatabaseName),
                                                new DocumentCollection { Id = targetCollectionName, IndexingPolicy = indexingPolicy },
                                                new RequestOptions { OfferEnableRUPerMinuteThroughput = true, OfferThroughput = CloneSettings.TargetMigrationOfferThroughputRUs });
                }
                logger.LogInfo($"SuccessFully Created Target. Database: {targetDatabaseName} Collection:{targetCollectionName}");
                return(newDocumentCollection);
            }
            catch (Exception ex)
            {
                logger.LogError(ex);
                throw;
            }
        }
        public async Task TestCosmosQueryPartitionKeyDefinition()
        {
            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();
            QueryRequestOptions    queryRequestOptions    = new QueryRequestOptions
            {
                Properties = new Dictionary <string, object>()
                {
                    { "x-ms-query-partitionkey-definition", partitionKeyDefinition }
                }
            };

            SqlQuerySpec            sqlQuerySpec = new SqlQuerySpec(@"select * from t where t.something = 42 ");
            bool                    allowNonValueAggregateQuery = true;
            bool                    isContinuationExpected      = true;
            CancellationTokenSource cancellationTokenSource     = new CancellationTokenSource();
            CancellationToken       cancellationtoken           = cancellationTokenSource.Token;

            Mock <CosmosQueryClient> client = new Mock <CosmosQueryClient>();
            string exceptionMessage         = "Verified that the PartitionKeyDefinition was correctly set. Cancel the rest of the query";

            client
            .Setup(x => x.GetCachedContainerQueryPropertiesAsync(It.IsAny <Uri>(), It.IsAny <Cosmos.PartitionKey?>(), cancellationtoken))
            .ReturnsAsync(new ContainerQueryProperties("mockContainer", null, partitionKeyDefinition));
            client
            .Setup(x => x.ByPassQueryParsing())
            .Returns(false);
            client
            .Setup(x => x.TryGetPartitionedQueryExecutionInfoAsync(
                       It.IsAny <SqlQuerySpec>(),
                       It.IsAny <PartitionKeyDefinition>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <CancellationToken>()))
            .ReturnsAsync(TryCatch <PartitionedQueryExecutionInfo> .FromException(
                              new InvalidOperationException(
                                  exceptionMessage)));

            CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters(
                sqlQuerySpec: sqlQuerySpec,
                initialUserContinuationToken: null,
                maxConcurrency: queryRequestOptions?.MaxConcurrency,
                maxItemCount: queryRequestOptions?.MaxItemCount,
                maxBufferedItemCount: queryRequestOptions?.MaxBufferedItemCount,
                partitionKey: queryRequestOptions?.PartitionKey,
                properties: queryRequestOptions?.Properties,
                partitionedQueryExecutionInfo: null,
                executionEnvironment: queryRequestOptions?.ExecutionEnvironment,
                testInjections: queryRequestOptions?.TestSettings);

            CosmosQueryContext cosmosQueryContext = new CosmosQueryContextCore(
                client: client.Object,
                queryRequestOptions: queryRequestOptions,
                resourceTypeEnum: ResourceType.Document,
                operationType: OperationType.Query,
                resourceType: typeof(QueryResponse),
                resourceLink: new Uri("dbs/mockdb/colls/mockColl", UriKind.Relative),
                isContinuationExpected: isContinuationExpected,
                allowNonValueAggregateQuery: allowNonValueAggregateQuery,
                correlatedActivityId: new Guid("221FC86C-1825-4284-B10E-A6029652CCA6"));

            CosmosQueryExecutionContext context = CosmosQueryExecutionContextFactory.Create(
                cosmosQueryContext,
                inputParameters);

            QueryResponseCore queryResponse = await context.ExecuteNextAsync(cancellationtoken);

            Assert.AreEqual(HttpStatusCode.BadRequest, queryResponse.StatusCode);
            Assert.IsTrue(queryResponse.ErrorMessage.Contains(exceptionMessage));
        }
        private async static Task AutomaticIndexing(DocumentClient client)
        {
            Console.WriteLine();
            Console.WriteLine(">>> Override Automatic Indexing <<<");

            // Create collection with automatic indexing
            var partitionKeyDefinition = new PartitionKeyDefinition();

            partitionKeyDefinition.Paths.Add("/id");
            var collectionDefinition = new DocumentCollection
            {
                Id           = "autoindexing",
                PartitionKey = partitionKeyDefinition
            };
            var options = new RequestOptions {
                OfferThroughput = 1000
            };
            var collection = await client.CreateDocumentCollectionAsync(MyDbDatabaseUri, collectionDefinition, options);

            var collectionUri = UriFactory.CreateDocumentCollectionUri("FamiliesDb", "autoindexing");

            // Add a document (indexed)
            dynamic indexedDocumentDefinition = new
            {
                id          = "JOHN",
                firstName   = "John",
                lastName    = "Doe",
                addressLine = "123 Main Street",
                city        = "Brooklyn",
                state       = "New York",
                zip         = "11229",
            };
            Document indexedDocument =
                await client.CreateDocumentAsync(collectionUri, indexedDocumentDefinition);

            // Add another document (request no indexing)
            dynamic unindexedDocumentDefinition = new
            {
                id          = "JANE",
                firstName   = "Jane",
                lastName    = "Doe",
                addressLine = "123 Main Street",
                city        = "Brooklyn",
                state       = "New York",
                zip         = "11229",
            };
            var requestOptions = new RequestOptions {
                IndexingDirective = IndexingDirective.Exclude
            };
            Document unindexedDocument =
                await client.CreateDocumentAsync(collectionUri, unindexedDocumentDefinition, requestOptions);

            var feedOptions = new FeedOptions {
                EnableCrossPartitionQuery = true
            };

            // Unindexed document won't get returned when querying on non-ID (or self-link) property

            var doeDocs = client
                          .CreateDocumentQuery(collectionUri, "SELECT * FROM c WHERE c.lastName = 'Doe'", feedOptions)
                          .ToList();

            Console.WriteLine($"Documents WHERE lastName = 'Doe': {doeDocs.Count}");
            foreach (var doeDoc in doeDocs)
            {
                Console.WriteLine($" ID: {doeDoc.id}, Name: {doeDoc.firstName} {doeDoc.lastName}");
            }
            Console.WriteLine();

            // Unindexed document will get returned when using no WHERE clause
            var allDocs = client.CreateDocumentQuery(collectionUri, "SELECT * FROM c", feedOptions).ToList();

            Console.WriteLine($"All documents: {allDocs.Count}");
            foreach (var doc in allDocs)
            {
                Console.WriteLine($" ID: {doc.id}, Name: {doc.firstName} {doc.lastName}");
            }
            Console.WriteLine();

            // Unindexed document will get returned when querying by ID (or self-link) property
            var janeDoc = client
                          .CreateDocumentQuery(collectionUri, "SELECT * FROM c WHERE c.id = 'JANE'", feedOptions)
                          .AsEnumerable()
                          .FirstOrDefault();

            Console.WriteLine($"Unindexed document:");
            Console.WriteLine($" ID: {janeDoc.id}, Name: {janeDoc.firstName} {janeDoc.lastName}");

            // Delete the collection
            await client.DeleteDocumentCollectionAsync(collectionUri);
        }
        internal PartitionedQueryExecutionInfoInternal GetPartitionedQueryExecutionInfoInternal(
            SqlQuerySpec querySpec,
            PartitionKeyDefinition partitionKeyDefinition,
            bool requireFormattableOrderByQuery,
            bool isContinuationExpected,
            bool allowNonValueAggregateQuery,
            bool hasLogicalPartitionKey)
        {
            if (querySpec == null || partitionKeyDefinition == null)
            {
                return(DefaultInfoInternal);
            }

            string queryText = JsonConvert.SerializeObject(querySpec);

            List <string> paths = new List <string>(partitionKeyDefinition.Paths);

            List <string[]> pathParts = new List <string[]>();

            paths.ForEach(path =>
            {
                pathParts.Add(PathParser.GetPathParts(path).ToArray());
            });

            string[] allParts     = pathParts.SelectMany(parts => parts).ToArray();
            uint[]   partsLengths = pathParts.Select(parts => (uint)parts.Length).ToArray();

            PartitionKind partitionKind = partitionKeyDefinition.Kind;

            this.Initialize();

            byte[] buffer = new byte[InitialBufferSize];
            uint   errorCode;
            uint   serializedQueryExecutionInfoResultLength;

            unsafe
            {
                fixed(byte *bytePtr = buffer)
                {
                    errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery(
                        this.serviceProvider,
                        queryText,
                        requireFormattableOrderByQuery,
                        isContinuationExpected,
                        allowNonValueAggregateQuery,
                        hasLogicalPartitionKey,
                        allParts,
                        partsLengths,
                        (uint)partitionKeyDefinition.Paths.Count,
                        partitionKind,
                        new IntPtr(bytePtr),
                        (uint)buffer.Length,
                        out serializedQueryExecutionInfoResultLength);

                    if (errorCode == DISP_E_BUFFERTOOSMALL)
                    {
                        buffer = new byte[serializedQueryExecutionInfoResultLength];
                        fixed(byte *bytePtr2 = buffer)
                        {
                            errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery(
                                this.serviceProvider,
                                queryText,
                                requireFormattableOrderByQuery,
                                isContinuationExpected,
                                allowNonValueAggregateQuery,
                                hasLogicalPartitionKey, // has logical partition key
                                allParts,
                                partsLengths,
                                (uint)partitionKeyDefinition.Paths.Count,
                                partitionKind,
                                new IntPtr(bytePtr2),
                                (uint)buffer.Length,
                                out serializedQueryExecutionInfoResultLength);
                        }
                    }
                }
            }

            string serializedQueryExecutionInfo = Encoding.UTF8.GetString(buffer, 0, (int)serializedQueryExecutionInfoResultLength);

            Exception exception = Marshal.GetExceptionForHR((int)errorCode);

            if (exception != null)
            {
                DefaultTrace.TraceInformation("QueryEngineConfiguration: " + this.queryengineConfiguration);
                string errorMessage;
                if (string.IsNullOrEmpty(serializedQueryExecutionInfo))
                {
                    errorMessage = $"Message: Query service interop parsing hit an unexpected exception: {exception.ToString()}";
                }
                else
                {
                    errorMessage = "Message: " + serializedQueryExecutionInfo;
                }

                throw new CosmosException(
                          HttpStatusCode.BadRequest,
                          errorMessage);
            }

            PartitionedQueryExecutionInfoInternal queryInfoInternal =
                JsonConvert.DeserializeObject <PartitionedQueryExecutionInfoInternal>(
                    serializedQueryExecutionInfo,
                    new JsonSerializerSettings
            {
                DateParseHandling = DateParseHandling.None
            });

            return(queryInfoInternal);
        }
        public static string GetPartitionKeyRangeId(PartitionKey partitionKey, PartitionKeyDefinition partitionKeyDefinition, Routing.CollectionRoutingMap collectionRoutingMap)
        {
            string effectivePartitionKey = partitionKey.InternalKey.GetEffectivePartitionKeyString(partitionKeyDefinition);

            return(collectionRoutingMap.GetRangeByEffectivePartitionKey(effectivePartitionKey).Id);
        }
        private async Task ValidateCollectionIndexProgressHeaders(CosmosClient client)
        {
            Cosmos.Database db = await client.CreateDatabaseAsync(Guid.NewGuid().ToString());

            try
            {
                PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition {
                    Paths = new System.Collections.ObjectModel.Collection <string>(new[] { "/id" }), Kind = PartitionKind.Hash
                };
                var lazyCollection = new ContainerProperties()
                {
                    Id = Guid.NewGuid().ToString(), PartitionKey = partitionKeyDefinition
                };
                lazyCollection.IndexingPolicy.IndexingMode = Cosmos.IndexingMode.Lazy;
                Container lazyContainer = await db.CreateContainerAsync(lazyCollection);

                var consistentCollection = new ContainerProperties()
                {
                    Id = Guid.NewGuid().ToString(), PartitionKey = partitionKeyDefinition
                };
                consistentCollection.IndexingPolicy.IndexingMode = Cosmos.IndexingMode.Consistent;
                Container consistentContainer = await db.CreateContainerAsync(consistentCollection);

                var noneIndexCollection = new ContainerProperties()
                {
                    Id = Guid.NewGuid().ToString(), PartitionKey = partitionKeyDefinition
                };
                noneIndexCollection.IndexingPolicy.Automatic    = false;
                noneIndexCollection.IndexingPolicy.IndexingMode = Cosmos.IndexingMode.None;
                Container noneIndexContainer = await db.CreateContainerAsync(noneIndexCollection);

                var doc = new Document()
                {
                    Id = Guid.NewGuid().ToString()
                };
                await lazyContainer.CreateItemAsync <Document>(doc);

                await consistentContainer.CreateItemAsync <Document>(doc);

                await noneIndexContainer.CreateItemAsync <Document>(doc);


                // Lazy-indexing collection.
                {
                    ContainerResponse collectionResponse = await lazyContainer.ReadContainerAsync(requestOptions : new ContainerRequestOptions {
                        PopulateQuotaInfo = true
                    });

                    Assert.IsTrue(int.Parse(collectionResponse.Headers[HttpConstants.HttpHeaders.CollectionLazyIndexingProgress], CultureInfo.InvariantCulture) >= 0,
                                  "Expect lazy indexer progress when reading lazy collection.");
                    Assert.AreEqual(100, int.Parse(collectionResponse.Headers[HttpConstants.HttpHeaders.CollectionIndexTransformationProgress], CultureInfo.InvariantCulture),
                                    "Expect reindexer progress when reading lazy collection.");
                }

                // Consistent-indexing collection.
                {
                    ContainerResponse collectionResponse = await consistentContainer.ReadContainerAsync(requestOptions : new ContainerRequestOptions {
                        PopulateQuotaInfo = true
                    });

                    Assert.IsFalse(collectionResponse.Headers.AllKeys().Contains(HttpConstants.HttpHeaders.CollectionLazyIndexingProgress),
                                   "No lazy indexer progress when reading consistent collection.");
                    Assert.AreEqual(100, int.Parse(collectionResponse.Headers[HttpConstants.HttpHeaders.CollectionIndexTransformationProgress], CultureInfo.InvariantCulture),
                                    "Expect reindexer progress when reading consistent collection.");
                }

                // None-indexing collection.
                {
                    ContainerResponse collectionResponse = await noneIndexContainer.ReadContainerAsync(requestOptions : new ContainerRequestOptions {
                        PopulateQuotaInfo = true
                    });

                    Assert.IsFalse(collectionResponse.Headers.AllKeys().Contains(HttpConstants.HttpHeaders.CollectionLazyIndexingProgress),
                                   "No lazy indexer progress when reading none-index collection.");
                    Assert.AreEqual(100, int.Parse(collectionResponse.Headers[HttpConstants.HttpHeaders.CollectionIndexTransformationProgress], CultureInfo.InvariantCulture),
                                    "Expect reindexer progress when reading none-index collection.");
                }
            }
            finally
            {
                await db.DeleteAsync();
            }
        }
        public static Func <bool, IQueryable <Family> > GenerateFamilyCosmosData(
            Cosmos.Database cosmosDatabase, out Container container)
        {
            // The test collection should have range index on string properties
            // for the orderby tests
            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition {
                Paths = new System.Collections.ObjectModel.Collection <string>(new[] { "/Pk" }), Kind = PartitionKind.Hash
            };
            ContainerProperties newCol = new ContainerProperties()
            {
                Id             = Guid.NewGuid().ToString(),
                PartitionKey   = partitionKeyDefinition,
                IndexingPolicy = new Microsoft.Azure.Cosmos.IndexingPolicy()
                {
                    IncludedPaths = new Collection <Cosmos.IncludedPath>()
                    {
                        new Cosmos.IncludedPath()
                        {
                            Path    = "/*",
                            Indexes = new System.Collections.ObjectModel.Collection <Microsoft.Azure.Cosmos.Index>()
                            {
                                Microsoft.Azure.Cosmos.Index.Range(Microsoft.Azure.Cosmos.DataType.Number, -1),
                                Microsoft.Azure.Cosmos.Index.Range(Microsoft.Azure.Cosmos.DataType.String, -1)
                            }
                        }
                    },
                    CompositeIndexes = new Collection <Collection <Cosmos.CompositePath> >()
                    {
                        new Collection <Cosmos.CompositePath>()
                        {
                            new Cosmos.CompositePath()
                            {
                                Path = "/FamilyId", Order = Cosmos.CompositePathSortOrder.Ascending
                            },
                            new Cosmos.CompositePath()
                            {
                                Path = "/Int", Order = Cosmos.CompositePathSortOrder.Ascending
                            }
                        },
                        new Collection <Cosmos.CompositePath>()
                        {
                            new Cosmos.CompositePath()
                            {
                                Path = "/FamilyId", Order = Cosmos.CompositePathSortOrder.Ascending
                            },
                            new Cosmos.CompositePath()
                            {
                                Path = "/Int", Order = Cosmos.CompositePathSortOrder.Descending
                            }
                        },
                        new Collection <Cosmos.CompositePath>()
                        {
                            new Cosmos.CompositePath()
                            {
                                Path = "/FamilyId", Order = Cosmos.CompositePathSortOrder.Ascending
                            },
                            new Cosmos.CompositePath()
                            {
                                Path = "/Int", Order = Cosmos.CompositePathSortOrder.Ascending
                            },
                            new Cosmos.CompositePath()
                            {
                                Path = "/IsRegistered", Order = Cosmos.CompositePathSortOrder.Descending
                            }
                        },
                        new Collection <Cosmos.CompositePath>()
                        {
                            new Cosmos.CompositePath()
                            {
                                Path = "/Int", Order = Cosmos.CompositePathSortOrder.Ascending
                            },
                            new Cosmos.CompositePath()
                            {
                                Path = "/IsRegistered", Order = Cosmos.CompositePathSortOrder.Descending
                            }
                        },
                        new Collection <Cosmos.CompositePath>()
                        {
                            new Cosmos.CompositePath()
                            {
                                Path = "/IsRegistered", Order = Cosmos.CompositePathSortOrder.Ascending
                            },
                            new Cosmos.CompositePath()
                            {
                                Path = "/Int", Order = Cosmos.CompositePathSortOrder.Descending
                            }
                        }
                    }
                }
            };

            container = cosmosDatabase.CreateContainerAsync(newCol).Result;
            const int Records                   = 100;
            const int MaxNameLength             = 100;
            const int MaxThingStringLength      = 50;
            const int MaxChild                  = 5;
            const int MaxPets                   = MaxChild;
            const int MaxThings                 = MaxChild;
            const int MaxGrade                  = 101;
            const int MaxTransaction            = 20;
            const int MaxTransactionMinuteRange = 200;
            int       MaxTransactionType        = Enum.GetValues(typeof(TransactionType)).Length;

            Family createDataObj(Random random)
            {
                Family obj = new Family
                {
                    FamilyId     = random.NextDouble() < 0.05 ? "some id" : Guid.NewGuid().ToString(),
                    IsRegistered = random.NextDouble() < 0.5,
                    NullableInt  = random.NextDouble() < 0.5 ? (int?)random.Next() : null,
                    Int          = random.NextDouble() < 0.5 ? 5 : random.Next(),
                    Id           = Guid.NewGuid().ToString(),
                    Pk           = "Test",
                    Parents      = new Parent[random.Next(2) + 1]
                };

                for (int i = 0; i < obj.Parents.Length; ++i)
                {
                    obj.Parents[i] = new Parent()
                    {
                        FamilyName = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)),
                        GivenName  = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength))
                    };
                }

                obj.Tags = new string[random.Next(MaxChild)];
                for (int i = 0; i < obj.Tags.Length; ++i)
                {
                    obj.Tags[i] = (i + random.Next(30, 36)).ToString();
                }

                obj.Children = new Child[random.Next(MaxChild)];
                for (int i = 0; i < obj.Children.Length; ++i)
                {
                    obj.Children[i] = new Child()
                    {
                        Gender     = random.NextDouble() < 0.5 ? "male" : "female",
                        FamilyName = obj.Parents[random.Next(obj.Parents.Length)].FamilyName,
                        GivenName  = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)),
                        Grade      = random.Next(MaxGrade)
                    };

                    obj.Children[i].Pets = new List <Pet>();
                    for (int j = 0; j < random.Next(MaxPets); ++j)
                    {
                        obj.Children[i].Pets.Add(new Pet()
                        {
                            GivenName = random.NextDouble() < 0.5 ?
                                        LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)) :
                                        "Fluffy"
                        });
                    }

                    obj.Children[i].Things = new Dictionary <string, string>();
                    for (int j = 0; j < random.Next(MaxThings) + 1; ++j)
                    {
                        obj.Children[i].Things.Add(
                            j == 0 ? "A" : $"{j}-{random.Next().ToString()}",
                            LinqTestsCommon.RandomString(random, random.Next(MaxThingStringLength)));
                    }
                }

                obj.Records = new Logs
                {
                    LogId        = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)),
                    Transactions = new Transaction[random.Next(MaxTransaction)]
                };
                for (int i = 0; i < obj.Records.Transactions.Length; ++i)
                {
                    Transaction transaction = new Transaction()
                    {
                        Amount = random.Next(),
                        Date   = DateTime.Now.AddMinutes(random.Next(MaxTransactionMinuteRange)),
                        Type   = (TransactionType)random.Next(MaxTransactionType)
                    };
                    obj.Records.Transactions[i] = transaction;
                }

                return(obj);
            }

            Func <bool, IQueryable <Family> > getQuery = LinqTestsCommon.GenerateTestCosmosData(createDataObj, Records, container);

            return(getQuery);
        }
        public static IReadOnlyList <Range <string> > GetProvidedPartitionKeyRanges(
            SqlQuerySpec querySpec,
            bool enableCrossPartitionQuery,
            bool parallelizeCrossPartitionQuery,
            bool isContinuationExpected,
            PartitionKeyDefinition partitionKeyDefinition,
            QueryPartitionProvider queryPartitionProvider,
            string clientApiVersion,
            out QueryInfo queryInfo)
        {
            if (querySpec == null)
            {
                throw new ArgumentNullException("querySpec");
            }

            if (partitionKeyDefinition == null)
            {
                throw new ArgumentNullException("partitionKeyDefinition");
            }

            if (queryPartitionProvider == null)
            {
                throw new ArgumentNullException("queryPartitionProvider");
            }

            PartitionedQueryExecutionInfo queryExecutionInfo = null;

            queryExecutionInfo = queryPartitionProvider.GetPartitionedQueryExecutionInfo(
                querySpec,
                partitionKeyDefinition,
                VersionUtility.IsLaterThan(clientApiVersion, HttpConstants.Versions.v2016_11_14),
                isContinuationExpected);

            if (queryExecutionInfo == null ||
                queryExecutionInfo.QueryRanges == null ||
                queryExecutionInfo.QueryInfo == null ||
                queryExecutionInfo.QueryRanges.Any(range => range.Min == null || range.Max == null))
            {
                DefaultTrace.TraceInformation("QueryPartitionProvider returned bad query info");
            }

            bool isSinglePartitionQuery = queryExecutionInfo.QueryRanges.Count == 1 && queryExecutionInfo.QueryRanges[0].IsSingleValue;

            if (partitionKeyDefinition.Paths.Count > 0 && !isSinglePartitionQuery)
            {
                if (!enableCrossPartitionQuery)
                {
                    throw new BadRequestException(RMResources.CrossPartitionQueryDisabled);
                }
                else
                {
                    if (parallelizeCrossPartitionQuery ||
                        (queryExecutionInfo.QueryInfo != null && (queryExecutionInfo.QueryInfo.HasTop || queryExecutionInfo.QueryInfo.HasOrderBy || queryExecutionInfo.QueryInfo.HasAggregates)))
                    {
                        if (!IsSupportedPartitionedQueryExecutionInfo(queryExecutionInfo, clientApiVersion))
                        {
                            throw new BadRequestException(RMResources.UnsupportedCrossPartitionQuery);
                        }
                        else if (queryExecutionInfo.QueryInfo.HasAggregates && !IsAggregateSupportedApiVersion(clientApiVersion))
                        {
                            throw new BadRequestException(RMResources.UnsupportedCrossPartitionQueryWithAggregate);
                        }
                        else
                        {
                            DocumentClientException exception = new DocumentClientException(
                                RMResources.UnsupportedCrossPartitionQuery,
                                HttpStatusCode.BadRequest,
                                SubStatusCodes.CrossPartitionQueryNotServable);

                            exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                            throw exception;
                        }
                    }
                }
            }
            // For single partition query with aggregate functions and no continuation expected,
            // we would try to accumulate the results for them on the SDK, if supported.
            else if (queryExecutionInfo.QueryInfo.HasAggregates && !isContinuationExpected)
            {
                if (IsAggregateSupportedApiVersion(clientApiVersion))
                {
                    DocumentClientException exception = new DocumentClientException(
                        RMResources.UnsupportedQueryWithFullResultAggregate,
                        HttpStatusCode.BadRequest,
                        SubStatusCodes.CrossPartitionQueryNotServable);

                    exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                    throw exception;
                }
                else
                {
                    throw new BadRequestException(RMResources.UnsupportedQueryWithFullResultAggregate);
                }
            }

            queryInfo = queryExecutionInfo.QueryInfo;
            return(queryExecutionInfo.QueryRanges);
        }
示例#10
0
        public async Task Initalize()
        {
            try
            {
                Console.WriteLine("MultiMaster Conflicts Initialize");

                //Database definition
                Database database = new Database {
                    Id = databaseName
                };

                //Throughput - RUs
                RequestOptions options = new RequestOptions {
                    OfferThroughput = 1000
                };

                //create the database
                await clients[0].CreateDatabaseIfNotExistsAsync(database, options);

                //Shared Container properties
                PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();
                partitionKeyDefinition.Paths.Add(PartitionKeyProperty);

                //Conflict Policy for Container using Last Writer Wins
                ConflictResolutionPolicy lwwPolicy = new ConflictResolutionPolicy
                {
                    Mode = ConflictResolutionMode.LastWriterWins,
                    ConflictResolutionPath = "/userDefinedId"
                };

                DocumentCollection containerLww = new DocumentCollection
                {
                    Id                       = lwwContainerName,
                    PartitionKey             = partitionKeyDefinition,
                    ConflictResolutionPolicy = lwwPolicy
                };
                await clients[0].CreateDocumentCollectionIfNotExistsAsync(databaseUri, containerLww);

                string udpStoredProcName = "spConflictUDP";
                Uri    spUri             = UriFactory.CreateStoredProcedureUri(databaseName, udpContainerName, udpStoredProcName);

                //Conflict Policy for Container with User-Defined Stored Procedure
                ConflictResolutionPolicy udpPolicy = new ConflictResolutionPolicy
                {
                    Mode = ConflictResolutionMode.Custom,
                    ConflictResolutionProcedure = spUri.ToString()
                };

                DocumentCollection containerUdp = new DocumentCollection
                {
                    Id                       = udpContainerName,
                    PartitionKey             = partitionKeyDefinition,
                    ConflictResolutionPolicy = udpPolicy
                };
                await clients[0].CreateDocumentCollectionIfNotExistsAsync(databaseUri, containerUdp);

                //Stored Procedure definition
                StoredProcedure spConflictUdp = new StoredProcedure
                {
                    Id   = udpStoredProcName,
                    Body = File.ReadAllText($@"{udpStoredProcName}.js")
                };

                //Create the Conflict Resolution stored procedure
                await clients[0].CreateStoredProcedureAsync(udpContainerUri, spConflictUdp);


                //Conflict Policy for Container with no Policy and writing to Conflicts Feed
                ConflictResolutionPolicy nonePolicy = new ConflictResolutionPolicy
                {
                    Mode = ConflictResolutionMode.Custom
                };

                DocumentCollection containerNone = new DocumentCollection
                {
                    Id                       = noneContainerName,
                    PartitionKey             = partitionKeyDefinition,
                    ConflictResolutionPolicy = nonePolicy
                };
                await clients[0].CreateDocumentCollectionIfNotExistsAsync(databaseUri, containerNone);
            }
            catch (DocumentClientException dcx)
            {
                Console.WriteLine(dcx.Message);
                Debug.Assert(false);
            }
        }
        public async static Task PopulateLimitedIndexesCollection(List <DgProvider> narrowProviders)
        {
            Uri uri = UriFactory.CreateDocumentCollectionUri(BhProvidersDatabaseDa.DatabaseName, BhProvidersDatabaseDa.CollectionNames.LimtedIndexes.ToString());
            //Delete collection if exists
            bool exists = BhProvidersDatabaseDa.DocumentClient.CreateDocumentCollectionQuery(BhProvidersDatabaseDa.DatabaseUri)
                          .ToList()
                          .Exists(c => c.Id == BhProvidersDatabaseDa.CollectionNames.LimtedIndexes.ToString());

            if (exists)
            {
                await BhProvidersDatabaseDa.DocumentClient.DeleteDocumentCollectionAsync(uri);
            }

            //Set throughput and partition key
            int    reservedRUs  = 9000;
            string partitionKey = "/locations[0].zip";

            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();

            partitionKeyDefinition.Paths.Add(partitionKey); //Weird.  Cannot have more than one partition key...

            RequestOptions requestOptions = new RequestOptions {
                OfferThroughput = reservedRUs
            };
            DocumentCollection limitedIndexesCollection = new DocumentCollection {
                Id = BhProvidersDatabaseDa.CollectionNames.LimtedIndexes.ToString()
            };

            limitedIndexesCollection.IndexingPolicy.IncludedPaths = new System.Collections.ObjectModel.Collection <IncludedPath>();
            limitedIndexesCollection.IndexingPolicy.IncludedPaths.Add
                (new IncludedPath
            {
                Indexes = new System.Collections.ObjectModel.Collection <Index>
                {
                    new HashIndex(DataType.String)
                    {
                        Precision = -1
                    },
                    new RangeIndex(DataType.String)
                    {
                        Precision = -1
                    }
                },
                Path = "/whateverPath/*"
            });
            limitedIndexesCollection.IndexingPolicy.IndexingMode = IndexingMode.Lazy;
            ResourceResponse <DocumentCollection> response = await BhProvidersDatabaseDa.DocumentClient.CreateDocumentCollectionAsync(
                BhProvidersDatabaseDa.DatabaseUri,
                new DocumentCollection
            {
                Id           = BhProvidersDatabaseDa.CollectionNames.LimtedIndexes.ToString(),
                PartitionKey = partitionKeyDefinition
            },
                requestOptions
                );

            DocumentCollection collection = response.Resource;
            DocumentCollection narrowProviderCollection = new DocumentCollection {
                Id = BhProvidersDatabaseDa.CollectionNames.DgNarrowProviders.ToString()
            };

            narrowProviderCollection.IndexingPolicy.IndexingMode = IndexingMode.Lazy;

            /*            Index index = new Index();
             *          narrowProviderCollection.IndexingPolicy.IncludedPaths = new System.Collections.ObjectModel.Collection<IncludedPath>()
             *          {
             *              new IncludedPath
             *              {
             *                  Indexes = new System.Collections.ObjectModel.Collection<Index>()
             *                  { new  ;
             */
            await BhProvidersDatabaseDa.CreateCollection(BhProvidersDatabaseDa.CollectionNames.DgNarrowProviders);

            foreach (DgProvider provider in filteredProviders)
            {
                DataModels.Narrow.DgProvider        narrow = provider;
                Task <ResourceResponse <Document> > task   = BhProvidersDatabaseDa.DocumentClient.CreateDocumentAsync(uri, narrow);
            }
            Console.WriteLine($"Received {filteredProviders.Count}");
        }
示例#12
0
        /// <summary>
        /// Checks whether a collections exists. Creates a new collection if
        /// the collection does not exist.
        /// <para>WARNING: CreateCollectionIfNotExistsAsync will create a
        /// new collection with reserved throughput which has pricing
        /// implications. For details visit:
        /// https://azure.microsoft.com/en-us/pricing/details/cosmos-db/
        /// </para>
        /// </summary>
        /// <param name="databaseName">Name of database to create</param>
        /// <param name="collectionName">Name of collection to create within the specified database</param>
        /// <param name="throughput">Amount of throughput to provision for the collection to be created</param>
        /// <param name="partitionKey">Partition Key for the collection to be created</param>
        /// <returns>A Task to allow asynchronous execution</returns>
        public static async Task CreateCollectionIfNotExistsAsync(
            DocumentClient client,
            string databaseName,
            string collectionName,
            int throughput,
            string partitionKey,
            ILogger logger,
            bool indexAllProperties = false,
            bool deleteExistingColl = false)
        {
            await client.CreateDatabaseIfNotExistsAsync(new Database { Id = databaseName });

            PartitionKeyDefinition pkDefn = null;

            Collection <string> paths = new Collection <string>();

            paths.Add(partitionKey);
            pkDefn = new PartitionKeyDefinition()
            {
                Paths = paths
            };

            try
            {
                DocumentCollection existingColl = await client.ReadDocumentCollectionAsync(string.Format("/dbs/{0}/colls/{1}", databaseName, collectionName));

                if (existingColl != null)
                {
                    if (!deleteExistingColl)
                    {
                        logger.WriteMessage(string.Format("{0} - Collection already present. Continuing without delete...", collectionName));
                    }
                    else
                    {
                        await client.DeleteDocumentCollectionAsync(string.Format("/dbs/{0}/colls/{1}", databaseName, collectionName));

                        IndexingPolicy policy = new IndexingPolicy();
                        if (!indexAllProperties)
                        {
                            policy.Automatic    = false;
                            policy.IndexingMode = IndexingMode.None;
                            policy.IncludedPaths.Clear();
                            policy.ExcludedPaths.Clear();
                        }
                        await client.CreateDocumentCollectionAsync(
                            UriFactory.CreateDatabaseUri(databaseName),
                            new DocumentCollection { Id = collectionName, PartitionKey = pkDefn, IndexingPolicy = policy },
                            new RequestOptions { OfferThroughput = throughput });

                        logger.WriteMessage(string.Format("{0} - Collection was already present. Deleted and recreated the collection...", collectionName));
                    }
                }
            }
            catch (DocumentClientException dce)
            {
                if ((int)dce.StatusCode == 404)
                {
                    try
                    {
                        IndexingPolicy policy = new IndexingPolicy();
                        if (!indexAllProperties)
                        {
                            policy.Automatic    = false;
                            policy.IndexingMode = IndexingMode.None;
                            policy.IncludedPaths.Clear();
                            policy.ExcludedPaths.Clear();
                        }

                        await client.CreateDocumentCollectionAsync(
                            UriFactory.CreateDatabaseUri(databaseName),
                            new DocumentCollection { Id = collectionName, PartitionKey = pkDefn, IndexingPolicy = policy },
                            new RequestOptions { OfferThroughput = throughput });

                        logger.WriteMessage(string.Format("{0} - Collection was not present. Successfully created the collection", collectionName));
                    }
                    catch (Exception ex)
                    {
                        logger.WriteMessage(string.Format(
                                                "Exception thrown when attempting to create the collection {0} in database: {1}: with message: {2}",
                                                collectionName,
                                                databaseName,
                                                ex.Message));
                    }
                }
                else
                {
                    throw;
                }
            }
        }
        private async Task SetupPersistedGrants()
        {
            _persistedGrantsUri =
                UriFactory.CreateDocumentCollectionUri(Database.Id, Constants.CollectionNames.PersistedGrant);
            Logger?.LogDebug($"Persisted Grants URI: {_persistedGrantsUri}");

            var partitionKeyDefinition = new PartitionKeyDefinition
            {
                Paths = { Constants.CollectionPartitionKeys.PersistedGrant }
            };

            Logger?.LogDebug($"Persisted Grants Partition Key: {partitionKeyDefinition}");

            var indexingPolicy = new IndexingPolicy
            {
                Automatic     = true,
                IndexingMode  = IndexingMode.Consistent,
                IncludedPaths =
                {
                    new IncludedPath
                    {
                        Path    = "/expiration/?",
                        Indexes =
                        {
                            Index.Range(DataType.String)
                        }
                    },
                    new IncludedPath
                    {
                        Path    = "/",
                        Indexes ={ Index.Range(DataType.String)           }
                    }
                }
            };

            Logger?.LogDebug($"Persisted Grants Indexing Policy: {indexingPolicy}");

            var uniqueKeyPolicy = new UniqueKeyPolicy
            {
                UniqueKeys =
                {
                    new UniqueKey
                    {
                        Paths =
                        {
                            "/clientId",
                            "/subjectId",
                            "/type"
                        }
                    }
                }
            };

            Logger?.LogDebug($"Persisted Grants Unique Key Policy: {uniqueKeyPolicy}");

            _persistedGrants = new DocumentCollection
            {
                Id              = Constants.CollectionNames.PersistedGrant,
                PartitionKey    = partitionKeyDefinition,
                IndexingPolicy  = indexingPolicy,
                UniqueKeyPolicy = uniqueKeyPolicy
            };
            Logger?.LogDebug($"Persisted Grants Collection: {_persistedGrants}");

            var persistedGrantsRequestOptions = new RequestOptions
            {
                OfferThroughput = GetRUsFor(CollectionName.PersistedGrants)
            };

            Logger?.LogDebug($"Persisted Grants Request Options: {persistedGrantsRequestOptions}");

            Logger?.LogDebug($"Ensure Persisted Grants (ID:{_persistedGrants.Id}) collection exists...");
            var persistedGrantsResults =
                await DocumentClient.CreateDocumentCollectionIfNotExistsAsync(DatabaseUri, _persistedGrants,
                                                                              persistedGrantsRequestOptions);

            Logger?.LogDebug($"{_persistedGrants.Id} Creation Results: {persistedGrantsResults.StatusCode}");
            if (persistedGrantsResults.StatusCode.EqualsOne(HttpStatusCode.Created, HttpStatusCode.OK))
            {
                _persistedGrants = persistedGrantsResults.Resource;
            }
        }
        /// <summary>
        /// Creates a new collection with the specified name or re-creates the collection if it already exists
        /// </summary>
        /// <param name="databaseId">Name of the Cosmos DB database within which to create or re-create the collection</param>
        /// <param name="collectionId">Name of the Cosmos DB collection to create or re-create</param>
        /// <param name="deleteExistingColl">Flag indicating whether or not to delete an exisitng collection</param>
        /// <returns></returns>
        private async Task CreateDocumentCollectionAsync(
            string databaseId,
            string collectionId,
            bool deleteExistingColl = true)
        {
            Database database = (await this.DocumentClient.ReadDatabaseAsync(string.Format("/dbs/{0}", databaseId))).Resource;

            if (database != null)
            {
                Console.WriteLine("Database with resourceid: {0} retrieved", database.ResourceId);
            }

            string partitionKey    = ConfigurationManager.AppSettings["CollectionPartitionKey"];
            int    offerThroughput = int.Parse(ConfigurationManager.AppSettings["CollectionThroughput"]);

            try
            {
                DocumentCollection existingColl = await this.DocumentClient.ReadDocumentCollectionAsync(string.Format("/dbs/{0}/colls/{1}", databaseId, collectionId));

                if (existingColl != null)
                {
                    if (!deleteExistingColl)
                    {
                        Console.WriteLine("Collection already present, returning...");
                    }
                    else
                    {
                        Console.WriteLine("Collection already present. Deleting collection...");
                        await this.DocumentClient.DeleteDocumentCollectionAsync(string.Format("/dbs/{0}/colls/{1}", databaseId, collectionId));

                        Console.WriteLine("Finished deleting the collection.");
                    }
                }
            }
            catch (DocumentClientException dce)
            {
                if (dce.StatusCode == HttpStatusCode.NotFound)
                {
                    Console.WriteLine("Collection not found, continuing as normal...");
                }
                else
                {
                    throw;
                }
            }

            RangeIndex     rangeIndexOverride1  = Index.Range(DataType.String, -1);
            RangeIndex     rangeIndexOverride2  = Index.Range(DataType.Number, -1);
            SpatialIndex   spatialIndexOverride = Index.Spatial(DataType.Point);
            IndexingPolicy indexingPolicy       = new IndexingPolicy(rangeIndexOverride1, rangeIndexOverride2, spatialIndexOverride);

            Console.WriteLine("Creating collection..");
            ResourceResponse <DocumentCollection> createResponse = null;

            PartitionKeyDefinition pkDefn = null;

            if (partitionKey != null)
            {
                Collection <string> paths = new Collection <string>();
                paths.Add(partitionKey);
                pkDefn = new PartitionKeyDefinition()
                {
                    Paths = paths
                };
            }
            if (pkDefn != null)
            {
                createResponse = await this.DocumentClient.CreateDocumentCollectionAsync(
                    database.SelfLink,
                    new DocumentCollection { Id = collectionId, IndexingPolicy = indexingPolicy, PartitionKey = pkDefn },
                    new RequestOptions { OfferThroughput = offerThroughput });
            }
            else
            {
                createResponse = await this.DocumentClient.CreateDocumentCollectionAsync(
                    database.SelfLink,
                    new DocumentCollection { Id = collectionId, IndexingPolicy = indexingPolicy },
                    new RequestOptions { OfferThroughput = offerThroughput });
            }

            Console.WriteLine("Successfully created the collection\n");
        }
示例#15
0
 internal abstract IDocumentContainer CreateDocumentContainer(
     PartitionKeyDefinition partitionKeyDefinition,
     FlakyDocumentContainer.FailureConfigs failureConfigs = default);
示例#16
0
        /// <summary>
        /// Extracts effective <see cref="PartitionKeyInternal"/> from serialized document.
        /// </summary>
        /// <remarks>
        /// This code doesn't do any validation, as it assumes that IndexingPolicy is valid, as it is coming from the backend.
        /// Expected format is "/prop1/prop2/?". No array expressions are expected.
        /// </remarks>
        /// <param name="documentString">Serialized document to extract partition key value from.</param>
        /// <param name="partitionKeyDefinition">Information about partition key.</param>
        /// <returns>Instance of <see cref="PartitionKeyInternal"/>.</returns>
        public static PartitionKeyInternal ExtractPartitionKeyValue(string documentString, PartitionKeyDefinition partitionKeyDefinition)
        {
            if (partitionKeyDefinition == null || partitionKeyDefinition.Paths.Count == 0)
            {
                return(PartitionKeyInternal.Empty);
            }

            return(DocumentAnalyzer.ExtractPartitionKeyValue(documentString, partitionKeyDefinition, (docString) => JToken.Parse(docString)));
        }
示例#17
0
        async public Task <bool> Open()
        {
            try
            {
                _client = new DocumentClient(
                    new Uri(ConnectionString.ExtractConnectionStringParameter("AccountEndpoint")),
                    ConnectionString.ExtractConnectionStringParameter("AccountKey"));

                var database = _client.CreateDatabaseQuery()
                               .Where(db => db.Id == ConnectionString.ExtractConnectionStringParameter("Database"))
                               .AsEnumerable()
                               .FirstOrDefault();

                if (database == null)
                {
                    throw new Exception($"Database {ConnectionString.ExtractConnectionStringParameter("Database")} not exits");
                }

                _spatialCollectionRef = _client.CreateDocumentCollectionQuery(database.SelfLink)
                                        .Where(col => col.Id == SpatialCollectionRefName)
                                        .AsEnumerable()
                                        .FirstOrDefault();

                if (_spatialCollectionRef == null)
                {
                    var partitionKey = new PartitionKeyDefinition();
                    partitionKey.Paths.Add("/name");

                    var response = await _client.CreateDocumentCollectionAsync(
                        database.SelfLink,
                        new DocumentCollection()
                    {
                        Id           = SpatialCollectionRefName,
                        PartitionKey = partitionKey
                    });

                    _spatialCollectionRef = response.Resource;
                }

                #region Points Collection

                _featureCollection_points = _client.CreateDocumentCollectionQuery(database.SelfLink)
                                            .Where(col => col.Id == FeatureCollectionNamePoints)
                                            .AsEnumerable()
                                            .FirstOrDefault();

                if (_featureCollection_points == null)
                {
                    IndexingPolicy indexingPolicyWithSpatialEnabled = new IndexingPolicy
                    {
                        IncludedPaths = new System.Collections.ObjectModel.Collection <IncludedPath>()
                        {
                            new IncludedPath
                            {
                                Path    = "/*",
                                Indexes = new System.Collections.ObjectModel.Collection <Index>()
                                {
                                    new SpatialIndex(DataType.Point),
                                    new RangeIndex(DataType.Number)
                                    {
                                        Precision = -1
                                    },
                                    new RangeIndex(DataType.String)
                                    {
                                        Precision = -1
                                    }
                                }
                            }
                        }
                    };

                    var partitionKey = new PartitionKeyDefinition();
                    partitionKey.Paths.Add("/_fc");


                    var response = await _client.CreateDocumentCollectionAsync(
                        database.SelfLink,
                        new DocumentCollection()
                    {
                        Id             = FeatureCollectionNamePoints,
                        PartitionKey   = partitionKey,
                        IndexingPolicy = indexingPolicyWithSpatialEnabled
                    });

                    // ToDo: Create Spatial Index

                    _featureCollection_points = response.Resource;
                }

                #endregion

                #region Lines Collection

                _featureCollection_lines = _client.CreateDocumentCollectionQuery(database.SelfLink)
                                           .Where(col => col.Id == FeatureCollectionNameLines)
                                           .AsEnumerable()
                                           .FirstOrDefault();

                if (_featureCollection_lines == null)
                {
                    IndexingPolicy indexingPolicyWithSpatialEnabled = new IndexingPolicy
                    {
                        IncludedPaths = new System.Collections.ObjectModel.Collection <IncludedPath>()
                        {
                            new IncludedPath
                            {
                                Path    = "/*",
                                Indexes = new System.Collections.ObjectModel.Collection <Index>()
                                {
                                    new SpatialIndex(DataType.LineString),
                                    new RangeIndex(DataType.Number)
                                    {
                                        Precision = -1
                                    },
                                    new RangeIndex(DataType.String)
                                    {
                                        Precision = -1
                                    }
                                }
                            }
                        }
                    };

                    var partitionKey = new PartitionKeyDefinition();
                    partitionKey.Paths.Add("/_fc");


                    var response = await _client.CreateDocumentCollectionAsync(
                        database.SelfLink,
                        new DocumentCollection()
                    {
                        Id             = FeatureCollectionNameLines,
                        PartitionKey   = partitionKey,
                        IndexingPolicy = indexingPolicyWithSpatialEnabled
                    });

                    _featureCollection_lines = response.Resource;
                }

                #endregion

                #region Polygons Collection

                _featureCollection_polygons = _client.CreateDocumentCollectionQuery(database.SelfLink)
                                              .Where(col => col.Id == FeatureCollectionNamePolygons)
                                              .AsEnumerable()
                                              .FirstOrDefault();

                if (_featureCollection_polygons == null)
                {
                    IndexingPolicy indexingPolicyWithSpatialEnabled = new IndexingPolicy
                    {
                        IncludedPaths = new System.Collections.ObjectModel.Collection <IncludedPath>()
                        {
                            new IncludedPath
                            {
                                Path    = "/*",
                                Indexes = new System.Collections.ObjectModel.Collection <Index>()
                                {
                                    new SpatialIndex(DataType.Point),
                                    new SpatialIndex(DataType.Polygon),
                                    new RangeIndex(DataType.Number)
                                    {
                                        Precision = -1
                                    },
                                    new RangeIndex(DataType.String)
                                    {
                                        Precision = -1
                                    }
                                }
                            }
                        }
                    };

                    var partitionKey = new PartitionKeyDefinition();
                    partitionKey.Paths.Add("/_fc");


                    var response = await _client.CreateDocumentCollectionAsync(
                        database.SelfLink,
                        new DocumentCollection()
                    {
                        Id             = FeatureCollectionNamePolygons,
                        PartitionKey   = partitionKey,
                        IndexingPolicy = indexingPolicyWithSpatialEnabled
                    });

                    _featureCollection_polygons = response.Resource;
                }

                #endregion

                _spatialReference = SpatialReference.FromID("epsg:4326");
            }
            catch (Exception ex)
            {
                this.LastErrorMessage = ex.Message;
                return(false);
            }
            return(true);
        }
示例#18
0
        public async Task CreateContainerIfNotExistsAsyncTest()
        {
            string containerName     = Guid.NewGuid().ToString();
            string partitionKeyPath1 = "/users";

            ContainerProperties settings          = new ContainerProperties(containerName, partitionKeyPath1);
            ContainerResponse   containerResponse = await this.cosmosDatabase.CreateContainerIfNotExistsAsync(settings);

            Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode);
            Assert.AreEqual(containerName, containerResponse.Resource.Id);
            Assert.AreEqual(partitionKeyPath1, containerResponse.Resource.PartitionKey.Paths.First());

            //Creating container with same partition key path
            containerResponse = await this.cosmosDatabase.CreateContainerIfNotExistsAsync(settings);

            Assert.AreEqual(HttpStatusCode.OK, containerResponse.StatusCode);
            Assert.AreEqual(containerName, containerResponse.Resource.Id);
            Assert.AreEqual(partitionKeyPath1, containerResponse.Resource.PartitionKey.Paths.First());

            //Creating container with different partition key path
            string partitionKeyPath2 = "/users2";

            try
            {
                settings          = new ContainerProperties(containerName, partitionKeyPath2);
                containerResponse = await this.cosmosDatabase.CreateContainerIfNotExistsAsync(settings);

                Assert.Fail("Should through ArgumentException on partition key path");
            }
            catch (ArgumentException ex)
            {
                Assert.AreEqual(nameof(settings.PartitionKey), ex.ParamName);
                Assert.IsTrue(ex.Message.Contains(string.Format(
                                                      ClientResources.PartitionKeyPathConflict,
                                                      partitionKeyPath2,
                                                      containerName,
                                                      partitionKeyPath1)));
            }

            containerResponse = await containerResponse.Container.DeleteContainerAsync();

            Assert.AreEqual(HttpStatusCode.NoContent, containerResponse.StatusCode);


            //Creating existing container with partition key having value for SystemKey
            //https://github.com/Azure/azure-cosmos-dotnet-v3/issues/623
            string v2ContainerName = "V2Container";
            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();

            partitionKeyDefinition.Paths.Add("/test");
            partitionKeyDefinition.IsSystemKey = false;
            ContainerProperties containerPropertiesWithSystemKey = new ContainerProperties()
            {
                Id           = v2ContainerName,
                PartitionKey = partitionKeyDefinition,
            };

            await this.cosmosDatabase.CreateContainerAsync(containerPropertiesWithSystemKey);

            ContainerProperties containerProperties = new ContainerProperties(v2ContainerName, "/test");

            containerResponse = await this.cosmosDatabase.CreateContainerIfNotExistsAsync(containerProperties);

            Assert.AreEqual(HttpStatusCode.OK, containerResponse.StatusCode);
            Assert.AreEqual(v2ContainerName, containerResponse.Resource.Id);
            Assert.AreEqual("/test", containerResponse.Resource.PartitionKey.Paths.First());

            containerResponse = await containerResponse.Container.DeleteContainerAsync();

            Assert.AreEqual(HttpStatusCode.NoContent, containerResponse.StatusCode);

            containerPropertiesWithSystemKey.PartitionKey.IsSystemKey = true;
            await this.cosmosDatabase.CreateContainerAsync(containerPropertiesWithSystemKey);

            containerProperties = new ContainerProperties(v2ContainerName, "/test");
            containerResponse   = await this.cosmosDatabase.CreateContainerIfNotExistsAsync(containerProperties);

            Assert.AreEqual(HttpStatusCode.OK, containerResponse.StatusCode);
            Assert.AreEqual(v2ContainerName, containerResponse.Resource.Id);
            Assert.AreEqual("/test", containerResponse.Resource.PartitionKey.Paths.First());

            containerResponse = await containerResponse.Container.DeleteContainerAsync();

            Assert.AreEqual(HttpStatusCode.NoContent, containerResponse.StatusCode);
        }
        // Extracted partition key might be invalid as CollectionCache might be stale.
        // Stale collection cache is refreshed through PartitionKeyMismatchRetryPolicy
        // and partition-key is extracted again.
        private async Task <ResponseMessage> ExtractPartitionKeyAndProcessItemStreamAsync <T>(
            PartitionKey?partitionKey,
            string itemId,
            T item,
            OperationType operationType,
            ItemRequestOptions requestOptions,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            if (diagnosticsContext == null)
            {
                throw new ArgumentNullException(nameof(diagnosticsContext));
            }

            Stream itemStream;

            using (diagnosticsContext.CreateScope("ItemSerialize"))
            {
                itemStream = this.ClientContext.SerializerCore.ToStream <T>(item);
            }

            // User specified PK value, no need to extract it
            if (partitionKey.HasValue)
            {
                PartitionKeyDefinition pKeyDefinition = await this.GetPartitionKeyDefinitionAsync();

                if (partitionKey.HasValue && partitionKey.Value != PartitionKey.None && partitionKey.Value.InternalKey.Components.Count != pKeyDefinition.Paths.Count)
                {
                    throw new ArgumentException(RMResources.MissingPartitionKeyValue);
                }

                return(await this.ProcessItemStreamAsync(
                           partitionKey,
                           itemId,
                           itemStream,
                           operationType,
                           requestOptions,
                           diagnosticsContext : diagnosticsContext,
                           cancellationToken : cancellationToken));
            }

            PartitionKeyMismatchRetryPolicy requestRetryPolicy = null;

            while (true)
            {
                using (diagnosticsContext.CreateScope("ExtractPkValue"))
                {
                    partitionKey = await this.GetPartitionKeyValueFromStreamAsync(itemStream, cancellationToken);
                }

                ResponseMessage responseMessage = await this.ProcessItemStreamAsync(
                    partitionKey,
                    itemId,
                    itemStream,
                    operationType,
                    requestOptions,
                    diagnosticsContext : diagnosticsContext,
                    cancellationToken : cancellationToken);

                if (responseMessage.IsSuccessStatusCode)
                {
                    return(responseMessage);
                }

                if (requestRetryPolicy == null)
                {
                    requestRetryPolicy = new PartitionKeyMismatchRetryPolicy(await this.ClientContext.DocumentClient.GetCollectionCacheAsync(), null);
                }

                ShouldRetryResult retryResult = await requestRetryPolicy.ShouldRetryAsync(responseMessage, cancellationToken);

                if (!retryResult.ShouldRetry)
                {
                    return(responseMessage);
                }
            }
        }
示例#20
0
        private static async Task ManualIndexing(IDocumentClient client)
        {
            Console.WriteLine(">>> Manual Indexing <<<");

            // Create collection with manual indexing
            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();

            partitionKeyDefinition.Paths.Add("/id");
            DocumentCollection collectionDefinition = new DocumentCollection
            {
                Id             = "manualindexing",
                PartitionKey   = partitionKeyDefinition,
                IndexingPolicy = new IndexingPolicy
                {
                    Automatic = false
                }
            };
            RequestOptions options = new RequestOptions {
                OfferThroughput = 1000
            };
            ResourceResponse <DocumentCollection> collection = await client.CreateDocumentCollectionAsync(MyDbDatabaseUri, collectionDefinition, options);

            Uri collectionUri = UriFactory.CreateDocumentCollectionUri("mydb", "manualindexing");

            // Add a document (unindexed)
            dynamic unindexedDocumentDefinition = new
            {
                id          = "JOHN",
                firstName   = "John",
                lastName    = "Doe",
                addressLine = "123 Main Street",
                city        = "Brooklyn",
                state       = "New York",
                zip         = "11229"
            };
            Document unindexedDocument = await client.CreateDocumentAsync(collectionUri, unindexedDocumentDefinition);

            // Add another document (request indexing)
            dynamic indexedDocumentDefinition = new
            {
                id          = "JANE",
                firstName   = "Jane",
                lastName    = "Doe",
                addressLine = "123 Main Street",
                city        = "Brooklyn",
                state       = "New York",
                zip         = "11229"
            };
            RequestOptions requestOptions = new RequestOptions {
                IndexingDirective = IndexingDirective.Include
            };
            Document indexedDocument = await client.CreateDocumentAsync(collectionUri, indexedDocumentDefinition, requestOptions);

            FeedOptions feedOptions = new FeedOptions {
                EnableCrossPartitionQuery = true
            };

            // Unindexed document won't get returned when querying on non-ID (or self-link) property
            List <dynamic> doeDocs = client.CreateDocumentQuery(collectionUri, "SELECT * FROM c WHERE c.lastName = 'Doe'", feedOptions).ToList();

            Console.WriteLine($"Documents WHERE lastName = 'Doe': {doeDocs.Count}");
            foreach (dynamic doeDoc in doeDocs)
            {
                Console.WriteLine($" ID: {doeDoc.id}, Name: {doeDoc.firstName} {doeDoc.lastName}");
            }
            Console.WriteLine();

            // Unindexed document will get returned when using no WHERE clause
            List <dynamic> allDocs = client.CreateDocumentQuery(collectionUri, "SELECT * FROM c", feedOptions).ToList();

            Console.WriteLine($"All documents: {allDocs.Count}");
            foreach (dynamic doc in allDocs)
            {
                Console.WriteLine($" ID: {doc.id}, Name: {doc.firstName} {doc.lastName}");
            }
            Console.WriteLine();

            // Unindexed document will get returned when querying by ID (or self-link) property
            dynamic johnDoc = client
                              .CreateDocumentQuery(collectionUri, "SELECT * FROM c WHERE c.id = 'JOHN'")
                              .AsEnumerable()
                              .FirstOrDefault();

            Console.WriteLine("Unindexed document:");
            Console.WriteLine($" ID: {johnDoc.id}, Name: {johnDoc.firstName} {johnDoc.lastName}");

            // Delete the collection
            await client.DeleteDocumentCollectionAsync(collectionUri);
        }
 static PartitionScheme()
 {
     PartitionKeyPaths = new PartitionKeyDefinition();
     PartitionKeyPaths.Paths.Add("/PartitionKey");
 }
示例#22
0
        private static void InitializeDirectContainers()
        {
            BatchTestBase.Client   = TestCommon.CreateCosmosClient();
            BatchTestBase.Database = BatchTestBase.Client.CreateDatabaseAsync(Guid.NewGuid().ToString())
                                     .GetAwaiter().GetResult().Database;

            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();

            partitionKeyDefinition.Paths.Add("/Status");

            BatchTestBase.LowThroughputJsonContainer = BatchTestBase.Database.CreateContainerAsync(
                new ContainerProperties()
            {
                Id           = Guid.NewGuid().ToString(),
                PartitionKey = partitionKeyDefinition
            },
                throughput: 400).GetAwaiter().GetResult().Container;

            BatchTestBase.PartitionKeyDefinition = ((ContainerCore)BatchTestBase.LowThroughputJsonContainer).GetPartitionKeyDefinitionAsync(CancellationToken.None).GetAwaiter().GetResult();

            // Create a container with at least 2 physical partitions for effective cross-partition testing
            BatchTestBase.JsonContainer = BatchTestBase.Database.CreateContainerAsync(
                new ContainerProperties()
            {
                Id           = Guid.NewGuid().ToString(),
                PartitionKey = BatchTestBase.PartitionKeyDefinition
            },
                throughput: 12000).GetAwaiter().GetResult().Container;

            Serialization.HybridRow.Schemas.Schema testSchema = TestDoc.GetSchema();
            Namespace testNamespace = new Namespace()
            {
                Name    = "Test",
                Version = SchemaLanguageVersion.V1,
                Schemas = new List <Serialization.HybridRow.Schemas.Schema>()
                {
                    testSchema
                }
            };

            BatchTestBase.LayoutResolver = new LayoutResolverNamespace(testNamespace);
            BatchTestBase.TestDocLayout  = BatchTestBase.LayoutResolver.Resolve(testSchema.SchemaId);

            BatchContainerProperties schematizedContainerProperties = new BatchContainerProperties()
            {
                Id                = Guid.NewGuid().ToString(),
                PartitionKey      = BatchTestBase.PartitionKeyDefinition,
                DefaultTimeToLive = (int)TimeSpan.FromDays(1).TotalSeconds // allow for TTL testing
            };

            SchemaPolicy schemaPolicy = new SchemaPolicy()
            {
                TableSchema = testNamespace,
            };

            schematizedContainerProperties.SchemaPolicy = schemaPolicy;

            BatchTestBase.SchematizedContainer = BatchTestBase.Database.CreateContainerAsync(
                schematizedContainerProperties,
                throughput: 12000).GetAwaiter().GetResult().Container;
        }
示例#23
0
        public void TestExtractValidStringPartitionKey()
        {
            dynamic address = new JObject();

            address.Country = "USA";

            dynamic document = new Document();

            document.address = address;

            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition {
                Kind = PartitionKind.Hash, Paths = new Collection <string> {
                    "/address/Country"
                }
            };

            PartitionKeyInternal partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(document, partitionKeyDefinition);

            Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { "USA" }, true), partitionKeyValue);

            partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(document), partitionKeyDefinition);
            Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { "USA" }, true), partitionKeyValue);

            partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(Document.FromObject(new Entity {
                Address = new Address {
                    Country = "USA"
                }
            }), partitionKeyDefinition);
            Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { "USA" }, true), partitionKeyValue);

            partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(Document.FromObject(new Entity {
                Address = new Address {
                    Country = "USA"
                }
            })), partitionKeyDefinition);
            Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { "USA" }, true), partitionKeyValue);

            partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(Document.FromObject(new DocumentEntity {
                Address = new Address {
                    Country = "USA"
                }
            }), partitionKeyDefinition);
            Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { "USA" }, true), partitionKeyValue);

            partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(Document.FromObject(new DocumentEntity {
                Address = new Address {
                    Country = "USA"
                }
            })), partitionKeyDefinition);
            Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { "USA" }, true), partitionKeyValue);

            dynamic country = new JObject();

            country.something = "foo";

            address         = new JObject();
            address.Country = country;

            document         = new Document();
            document.address = address;

            partitionKeyDefinition = new PartitionKeyDefinition {
                Kind = PartitionKind.Hash, Paths = new Collection <string> {
                    "/address/Country/something"
                }
            };

            partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(document, partitionKeyDefinition);
            Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { "foo" }, true), partitionKeyValue);

            partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(document), partitionKeyDefinition);
            Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { "foo" }, true), partitionKeyValue);
        }
示例#24
0
 /// <summary>
 /// Validates the partition key.
 /// </summary>
 /// <param name="destinationPartitionKey">The destination partition key.</param>
 /// <param name="sourcePartitionKey">The source partition key.</param>
 /// <returns>The boolean</returns>
 private static bool ValidatePartitionKey(PartitionKeyDefinition destinationPartitionKey, PartitionKeyDefinition sourcePartitionKey)
 {
     return(sourcePartitionKey.Paths.SequenceEqual(destinationPartitionKey.Paths));
 }
示例#25
0
        public void TestExtractUndefinedPartitionKey()
        {
            dynamic document = new Document();

            PartitionKeyDefinition[] partitionKeyDefinitions = new PartitionKeyDefinition[]
            {
                new PartitionKeyDefinition {
                    Paths = new Collection <string> {
                        "/address/Country",
                    },
                    Kind = PartitionKind.Range
                },
                new PartitionKeyDefinition {
                    Paths = new Collection <string> {
                        "/address/Country/something",
                    },
                    Kind = PartitionKind.Range
                },
                new PartitionKeyDefinition {
                    Paths = new Collection <string> {
                        "/address",
                    },
                    Kind = PartitionKind.Range
                },
            };

            foreach (PartitionKeyDefinition definition in partitionKeyDefinitions)
            {
                PartitionKeyInternal partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(document, definition);
                Assert.AreEqual(
                    PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true),
                    partitionKeyValue);

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(document), definition);
                Assert.AreEqual(
                    PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true),
                    partitionKeyValue);

                document         = new Document();
                document.address = new JObject();

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(document, definition);
                Assert.AreEqual(
                    PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true),
                    partitionKeyValue);

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(document), definition);
                Assert.AreEqual(
                    PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true),
                    partitionKeyValue);

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(Document.FromObject(new Entity {
                    Address = new Address {
                        Country = new object()
                    }
                }), definition);
                Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true), partitionKeyValue);

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(Document.FromObject(new Entity {
                    Address = new Address {
                        Country = new object()
                    }
                })), definition);
                Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true), partitionKeyValue);

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(Document.FromObject(new DocumentEntity {
                    Address = new Address {
                        Country = new object()
                    }
                }), definition);
                Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true), partitionKeyValue);

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(Document.FromObject(new DocumentEntity {
                    Address = new Address {
                        Country = new object()
                    }
                })), definition);
                Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true), partitionKeyValue);

                dynamic address = new JObject();
                address.Country = new JObject();

                document         = new Document();
                document.address = address;

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(document, definition);
                Assert.AreEqual(
                    PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true),
                    partitionKeyValue);

                partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(JsonConvert.SerializeObject(document), definition);
                Assert.AreEqual(
                    PartitionKeyInternal.FromObjectArray(new object[] { Undefined.Value }, true),
                    partitionKeyValue);
            }
        }
示例#26
0
        private async static Task SetIndexPaths(DocumentClient client)
        {
            Console.WriteLine();
            Console.WriteLine(">>> Set Custom Index Paths <<<");

            // Create collection with custom indexing paths
            var partitionKeyDefinition = new PartitionKeyDefinition();

            partitionKeyDefinition.Paths.Add("/id");
            var collectionDefinition = new DocumentCollection
            {
                Id             = "customindexing",
                PartitionKey   = partitionKeyDefinition,
                IndexingPolicy = new IndexingPolicy
                {
                    IncludedPaths = new Collection <IncludedPath>
                    {
                        // The Title property in the root is the only string property we need to sort on
                        new IncludedPath
                        {
                            Path    = "/title/?",
                            Indexes = new Collection <Index>
                            {
                                new RangeIndex(DataType.String)
                            }
                        },
                        // Every property (also the Title) gets a hash index on strings, and a range index on numbers
                        new IncludedPath
                        {
                            Path    = "/*",
                            Indexes = new Collection <Index>
                            {
                                new HashIndex(DataType.String),
                                new RangeIndex(DataType.Number),
                            }
                        }
                    },
                    ExcludedPaths = new Collection <ExcludedPath>
                    {
                        new ExcludedPath
                        {
                            Path = "/misc/*",
                        }
                    }
                },
            };
            var options = new RequestOptions {
                OfferThroughput = 1000
            };
            var collection = await client.CreateDocumentCollectionAsync(MyDbDatabaseUri, collectionDefinition, options);

            var collectionUri = UriFactory.CreateDocumentCollectionUri("mydb", "customindexing");

            // Add some documents
            dynamic doc1Definition = new
            {
                id       = "SW4",
                title    = "Star Wars IV - A New Hope",
                rank     = 600,
                category = "Sci-Fi",
                misc     = new
                {
                    year   = 1977,
                    length = "2hr 1min"
                }
            };
            Document doc1 = await client.CreateDocumentAsync(collectionUri, doc1Definition);

            dynamic doc2Definition = new
            {
                id       = "GF",
                title    = "Godfather",
                rank     = 500,
                category = "Crime Drama",
                misc     = new
                {
                    year   = 1972,
                    length = "2hr 55min"
                }
            };
            Document doc2 = await client.CreateDocumentAsync(collectionUri, doc2Definition);

            dynamic doc3Definition = new
            {
                id       = "LOTR1",
                title    = "Lord Of The Rings - Fellowship of the Ring",
                rank     = 700,
                category = "Fantasy",
                misc     = new
                {
                    year   = 2001,
                    length = "2hr 58min"
                }
            };
            Document doc3 = await client.CreateDocumentAsync(collectionUri, doc3Definition);

            // All the queries in this demo are cross-partition queries
            var allowCrossPartitionQuery = new FeedOptions {
                EnableCrossPartitionQuery = true
            };

            // When trying a range query when a range index is not availalbe, must also explicitly enable scan in query
            var allowCrossPartitionAndScanQuery = new FeedOptions {
                EnableCrossPartitionQuery = true, EnableScanInQuery = true
            };


            // *** Querying (WHERE) ***

            // Equality on title string property (range and hash index available)
            var sql          = "SELECT * FROM c WHERE c.title = 'Godfather'";
            var queryByTitle = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();

            // Equality on category string property (hash index available)
            sql = "SELECT * FROM c WHERE c.category = 'Fantasy'";
            var queryByCategory = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();

            // Range on category string property (hash index can't be used, no range index available)
            sql = "SELECT * FROM c WHERE c.category >= 'Fantasy'";
            try
            {
                var queryByCategoryRange = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();
            }
            catch
            {
                var queryByCategoryRange = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionAndScanQuery).ToList();
            }

            // Equality on rank number property (range index available)
            sql = "SELECT * FROM c WHERE c.rank = 500";
            var queryByRank = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();

            // Range on rank number property (range index available)
            sql = "SELECT * FROM c WHERE c.rank > 500";
            var queryByRankRange = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();

            // Equality on year number property (no index available; scan required)
            sql = "SELECT * FROM c WHERE c.misc.year = 2001";
            try
            {
                var queryByYear = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();
            }
            catch
            {
                var queryByYear = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionAndScanQuery).ToList();
            }

            // Equality on length string property (no index available; scan required)
            sql = "SELECT * FROM c WHERE c.misc.length = '2hr 58min'";
            try
            {
                var queryByLength = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();
            }
            catch
            {
                var queryByLength = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionAndScanQuery).ToList();
            }


            // *** Sorting (ORDER BY) ***

            // Works with range index on title property strings
            sql = "SELECT * FROM c ORDER BY c.title";
            var sortByTitle = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();

            // Doesn't works without range index on category property strings (returns 0 documents, but doesn't throw error!)
            sql = "SELECT * FROM c ORDER BY c.category";
            var sortByCategory = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();

            // Works with range index on rank property numbers
            sql = "SELECT * FROM c ORDER BY c.rank";
            var sortByRank = client.CreateDocumentQuery(collectionUri, sql, allowCrossPartitionQuery).ToList();

            // Delete the collection
            await client.DeleteDocumentCollectionAsync(collectionUri);
        }
示例#27
0
        public async Task TestCosmosQueryPartitionKeyDefinition()
        {
            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();
            QueryRequestOptions    queryRequestOptions    = new QueryRequestOptions
            {
                Properties = new Dictionary <string, object>()
                {
                    { "x-ms-query-partitionkey-definition", partitionKeyDefinition }
                }
            };

            SqlQuerySpec            sqlQuerySpec = new SqlQuerySpec(@"select * from t where t.something = 42 ");
            bool                    allowNonValueAggregateQuery = true;
            bool                    isContinuationExpected      = true;
            CancellationTokenSource cancellationTokenSource     = new CancellationTokenSource();
            CancellationToken       cancellationtoken           = cancellationTokenSource.Token;

            Mock <CosmosQueryClient> client = new Mock <CosmosQueryClient>();
            string exceptionMessage         = "Verified that the PartitionKeyDefinition was correctly set. Cancel the rest of the query";

            client
            .Setup(x => x.GetCachedContainerQueryPropertiesAsync(It.IsAny <string>(), It.IsAny <Cosmos.PartitionKey?>(), NoOpTrace.Singleton, cancellationtoken))
            .ReturnsAsync(new ContainerQueryProperties("mockContainer", null, partitionKeyDefinition));
            client
            .Setup(x => x.ByPassQueryParsing())
            .Returns(false);
            client
            .Setup(x => x.TryGetPartitionedQueryExecutionInfoAsync(
                       It.IsAny <SqlQuerySpec>(),
                       It.IsAny <PartitionKeyDefinition>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <CancellationToken>()))
            .ReturnsAsync(TryCatch <PartitionedQueryExecutionInfo> .FromException(
                              new InvalidOperationException(
                                  exceptionMessage)));

            CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters(
                sqlQuerySpec: sqlQuerySpec,
                initialUserContinuationToken: null,
                initialFeedRange: null,
                maxConcurrency: queryRequestOptions?.MaxConcurrency,
                maxItemCount: queryRequestOptions?.MaxItemCount,
                maxBufferedItemCount: queryRequestOptions?.MaxBufferedItemCount,
                partitionKey: queryRequestOptions?.PartitionKey,
                properties: queryRequestOptions?.Properties,
                partitionedQueryExecutionInfo: null,
                executionEnvironment: queryRequestOptions?.ExecutionEnvironment,
                returnResultsInDeterministicOrder: true,
                forcePassthrough: false,
                testInjections: queryRequestOptions?.TestSettings);

            CosmosQueryContext cosmosQueryContext = new CosmosQueryContextCore(
                client: client.Object,
                resourceTypeEnum: ResourceType.Document,
                operationType: OperationType.Query,
                resourceType: typeof(QueryResponse),
                resourceLink: "dbs/mockdb/colls/mockColl",
                isContinuationExpected: isContinuationExpected,
                allowNonValueAggregateQuery: allowNonValueAggregateQuery,
                diagnosticsContext: new CosmosDiagnosticsContextCore(),
                correlatedActivityId: new Guid("221FC86C-1825-4284-B10E-A6029652CCA6"));

            IQueryPipelineStage pipelineStage = CosmosQueryExecutionContextFactory.Create(
                documentContainer: null,
                cosmosQueryContext,
                inputParameters,
                trace: NoOpTrace.Singleton);

            Assert.IsTrue(await pipelineStage.MoveNextAsync());
            TryCatch <QueryPage> tryGetPage = pipelineStage.Current;

            Assert.IsTrue(tryGetPage.Failed);
            Assert.AreEqual(HttpStatusCode.BadRequest, (tryGetPage.InnerMostException as CosmosException).StatusCode);
            Assert.IsTrue(
                (tryGetPage.InnerMostException as CosmosException).ToString().Contains(exceptionMessage),
                "response error message did not contain the proper substring.");
        }
        internal static async Task PartitionedCollectionSmokeTest(DocumentClient client, bool sharedOffer = false, bool sharedThroughputCollections = false, int numberOfCollections = 1)
        {
            if (!sharedOffer && sharedThroughputCollections)
            {
                throw new ArgumentException("Shared throughput collections are not supported without shared offer");
            }

            string         uniqDatabaseName = string.Format("SmokeTest_{0}", Guid.NewGuid().ToString("N"));
            RequestOptions options          = new RequestOptions {
                OfferThroughput = 50000
            };
            CosmosDatabaseSettings database = sharedOffer ? await client.CreateDatabaseAsync(new CosmosDatabaseSettings { Id = uniqDatabaseName }, options) : await client.CreateDatabaseAsync(new CosmosDatabaseSettings { Id = uniqDatabaseName });

            Assert.AreEqual(database.AltLink, ClientTestsUtils.GenerateAltLink(uniqDatabaseName));
            CosmosDatabaseSettings readbackdatabase = await client.ReadDatabaseAsync(database.SelfLink);

            List <dynamic> results = await ClientTestsUtils.SqlQueryDatabases(client, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqDatabaseName), 10);

            Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");
            Assert.AreEqual(database.ResourceId, ((QueryResult)results[0]).ResourceId);
            Assert.IsTrue((await ClientTestsUtils.ReadFeedDatabases(client)).Any((db) => db.Id == uniqDatabaseName));
            results = await ClientTestsUtils.SqlQueryDatabases(client, string.Format(@"select r._rid, r.id from root r where r.id = ""{0}""", uniqDatabaseName), 10);

            Assert.AreEqual(1, results.Count, "Should have queried and found 1 database");
            Assert.AreEqual(database.ResourceId, ((QueryResult)results[0]).ResourceId);
            Assert.AreEqual(database.ResourceId, (await client.ReadDatabaseAsync(database.SelfLink)).Resource.ResourceId);
            Assert.AreEqual(((CosmosDatabaseSettings)results[0]).AltLink, ClientTestsUtils.GenerateAltLink(uniqDatabaseName));

            ArrayList testCollections = new ArrayList();

            for (int i = 0; i < numberOfCollections; i++)
            {
                string uniqCollectionName     = "SmokeTestCollection" + Guid.NewGuid().ToString("N");
                var    partitionKeyDefinition = new PartitionKeyDefinition
                {
                    Paths = new System.Collections.ObjectModel.Collection <string> {
                        "/id"
                    },
                    Kind = PartitionKind.Hash
                };

                CosmosContainerSettings collection;
                if (sharedThroughputCollections)
                {
                    collection = await TestCommon.CreateCollectionAsync(client, database.SelfLink, new CosmosContainerSettings { Id = uniqCollectionName, PartitionKey = partitionKeyDefinition });
                }
                else
                {
                    collection = await TestCommon.CreateCollectionAsync(client, database.SelfLink, new CosmosContainerSettings { Id = uniqCollectionName, PartitionKey = partitionKeyDefinition }, options);
                }

                Assert.AreEqual(collection.AltLink, ClientTestsUtils.GenerateAltLink(uniqDatabaseName, uniqCollectionName, typeof(CosmosContainerSettings)));
                results = await SqlQueryCollections(client, database.SelfLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqCollectionName), 10);  // query through database link

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 collection");
                Assert.AreEqual(collection.ResourceId, ((QueryResult)results[0]).ResourceId);
                results = await SqlQueryCollections(client, database.CollectionsLink, string.Format(@"select r._rid, r.id from root r where r.id = ""{0}""", uniqCollectionName), 10);  // query through CollectionsLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 collection");
                Assert.AreEqual(collection.ResourceId, ((QueryResult)results[0]).ResourceId);
                Assert.AreEqual(1, (await ReadFeedCollections(client, database.SelfLink)).Count(item => item.Id == uniqCollectionName));        // read through database link
                Assert.AreEqual(1, (await ReadFeedCollections(client, database.CollectionsLink)).Count(item => item.Id == uniqCollectionName)); // read through CollectionsLink
                Assert.AreEqual(collection.ResourceId, (await client.ReadDocumentCollectionAsync(collection.SelfLink)).Resource.ResourceId);
                Assert.AreEqual(((CosmosContainerSettings)results[0]).AltLink, ClientTestsUtils.GenerateAltLink(uniqDatabaseName, uniqCollectionName, typeof(CosmosContainerSettings)));
                testCollections.Add(collection);

                string uniqDocumentName = "SmokeTestDocument" + Guid.NewGuid().ToString("N");
                LinqGeneralBaselineTests.Book myDocument = new LinqGeneralBaselineTests.Book();
                myDocument.Id        = uniqDocumentName;
                myDocument.Title     = "My Book"; //Simple Property.
                myDocument.Languages = new LinqGeneralBaselineTests.Language[] { new LinqGeneralBaselineTests.Language {
                                                                                     Name = "English", Copyright = "London Publication"
                                                                                 }, new LinqGeneralBaselineTests.Language {
                                                                                     Name = "French", Copyright = "Paris Publication"
                                                                                 } };                                                                                                                                                                                        //Array Property
                myDocument.Author = new LinqGeneralBaselineTests.Author {
                    Name = "Don", Location = "France"
                };                                                                                             //Complex Property
                myDocument.Price    = 9.99;
                myDocument.Editions = new List <LinqGeneralBaselineTests.Edition>()
                {
                    new LinqGeneralBaselineTests.Edition()
                    {
                        Name = "First", Year = 2001
                    }, new LinqGeneralBaselineTests.Edition()
                    {
                        Name = "Second", Year = 2005
                    }
                };
                Document document = await client.CreateDocumentAsync(collection.SelfLink, myDocument);

                Assert.AreEqual(document.AltLink, ClientTestsUtils.GenerateAltLink(uniqDatabaseName, uniqCollectionName, uniqDocumentName, typeof(Document)));
                results = await SqlQueryDocuments(client, collection.SelfLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqDocumentName), 10);  // query through collection link

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");
                Assert.AreEqual(document.ResourceId, ((QueryResult)results[0]).ResourceId);
                results = await SqlQueryDocuments(client, collection.DocumentsLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqDocumentName), 10);  // query through DocumentsLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");
                Assert.AreEqual(document.ResourceId, ((QueryResult)results[0]).ResourceId);
                Assert.AreEqual(1, (await ReadFeedDocuments(client, collection.SelfLink)).Count(item => item.Id == uniqDocumentName));      // read through collection link
                Assert.AreEqual(1, (await ReadFeedDocuments(client, collection.DocumentsLink)).Count(item => item.Id == uniqDocumentName)); // read through DocumentsLink

                if (client.QueryCompatibilityMode != QueryCompatibilityMode.SqlQuery)
                {
                    //Test query with parameters
                    results = await SqlQueryDocuments(client, collection.SelfLink,
                                                      new SqlQuerySpec
                    {
                        QueryText  = @"select r._rid from root r where r.id = @id",
                        Parameters = new SqlParameterCollection()
                        {
                            new SqlParameter("@id", uniqDocumentName)
                        }
                    }, 10);      // query through collection link

                    Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");
                    Assert.AreEqual(document.ResourceId, ((QueryResult)results[0]).ResourceId);
                }

                RequestOptions docReplaceRequestOptions = new RequestOptions {
                    PartitionKey = new PartitionKey(document.Id)
                };
                FeedOptions docReplaceFeedOptions = new FeedOptions {
                    EnableCrossPartitionQuery = true, PartitionKey = new PartitionKey(document.Id)
                };

                myDocument.Title = "My_Book_v2";

                document = await client.ReplaceDocumentAsync(document.AltLink, myDocument);

                results = await SqlQueryDocuments(client, collection.SelfLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqDocumentName), 10, docReplaceFeedOptions);

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");
                Assert.AreEqual(document.ResourceId, ((QueryResult)results[0]).ResourceId);
                results = await SqlQueryDocuments(client, collection.SelfLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id=""{0}""", uniqDocumentName), 10);  // query through collection

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");
                results = await SqlQueryDocuments(client, collection.DocumentsLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id=""{0}""", uniqDocumentName), 10);  // query through DocumentsLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");
                Assert.AreEqual(((Document)results[0]).AltLink, ClientTestsUtils.GenerateAltLink(uniqDatabaseName, uniqCollectionName, uniqDocumentName, typeof(Document)));


                // No Range Index on ts - override with scan
                FeedOptions queryFeedOptions1 = new FeedOptions()
                {
                    EnableScanInQuery = true, EnableCrossPartitionQuery = true
                };
                results = await SqlQueryDocuments(client, collection.SelfLink, string.Format(@"SELECT r.name FROM root r WHERE r.Price>0"), 10, queryFeedOptions1);

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");

                FeedOptions queryFeedOptions2 = new FeedOptions()
                {
                    EmitVerboseTracesInQuery = true, EnableCrossPartitionQuery = true
                };
                results = await SqlQueryDocuments(client, collection.SelfLink, string.Format(@"SELECT r.name FROM root r WHERE r.Price=9.99"), 10, queryFeedOptions2);

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");

                FeedOptions queryFeedOptions3 = new FeedOptions()
                {
                    EmitVerboseTracesInQuery = false, EnableCrossPartitionQuery = true
                };
                results = await SqlQueryDocuments(client, collection.SelfLink, string.Format(@"SELECT r.name FROM root r WHERE r.Price=9.99"), 10, queryFeedOptions3);

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 document");

                string uniqStoredProcedureName = "SmokeTestStoredProcedure" + Guid.NewGuid().ToString();
                CosmosStoredProcedureSettings storedProcedure = await client.CreateStoredProcedureAsync(collection.SelfLink, new CosmosStoredProcedureSettings { Id = uniqStoredProcedureName, Body = "function f() {var x = 10;}" });

                results = await SqlQueryStoredProcedures(client, collection.SelfLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id = ""{0}""", uniqStoredProcedureName), 10);  // query through collection link

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 storedProcedure");
                Assert.AreEqual(storedProcedure.ResourceId, ((QueryResult)results[0]).ResourceId);
                results = await SqlQueryStoredProcedures(client, collection.StoredProceduresLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id = ""{0}""", uniqStoredProcedureName), 10);  // query through StoredProceduresLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 storedProcedure");
                Assert.AreEqual(storedProcedure.ResourceId, ((QueryResult)results[0]).ResourceId);
                Assert.AreEqual(1, (await ReadFeedStoredProcedures(client, collection.SelfLink)).Count(item => item.Id == uniqStoredProcedureName));             // read through collection link
                Assert.AreEqual(1, (await ReadFeedStoredProcedures(client, collection.StoredProceduresLink)).Count(item => item.Id == uniqStoredProcedureName)); // read through StoredProceduresLink


                storedProcedure.Body = "function f() {var x= 20;}";
                storedProcedure      = await client.ReplaceStoredProcedureAsync(storedProcedure);

                results = await SqlQueryStoredProcedures(client, collection.StoredProceduresLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id=""{0}""", storedProcedure.Id), 10);  // query through StoredProceduresLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 storedProcedure");
                Assert.AreEqual(storedProcedure.ResourceId, ((QueryResult)results[0]).ResourceId);
                Assert.AreEqual(storedProcedure.ResourceId, (await client.ReadStoredProcedureAsync(storedProcedure.SelfLink)).Resource.ResourceId);
                Assert.AreEqual(1, results.Count, "Should have queried and found 1 storedProcedure");

                string uniqTriggerName        = "SmokeTestTrigger" + Guid.NewGuid().ToString("N");
                CosmosTriggerSettings trigger = await client.CreateTriggerAsync(collection.SelfLink, new CosmosTriggerSettings { Id = uniqTriggerName, Body = "function f() {var x = 10;}", TriggerOperation = TriggerOperation.All, TriggerType = TriggerType.Pre });

                results = await SqlQueryTriggers(client, collection.SelfLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqTriggerName), 10);  // query through collection link

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 trigger");
                Assert.AreEqual(trigger.ResourceId, ((QueryResult)results[0]).ResourceId);
                results = await SqlQueryTriggers(client, collection.TriggersLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqTriggerName), 10);  // query through TriggersLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 trigger");
                Assert.AreEqual(trigger.ResourceId, ((QueryResult)results[0]).ResourceId);
                Assert.AreEqual(1, (await ReadFeedTriggers(client, collection.SelfLink)).Count(item => item.Id == uniqTriggerName));     // read through collection link
                Assert.AreEqual(1, (await ReadFeedTriggers(client, collection.TriggersLink)).Count(item => item.Id == uniqTriggerName)); // read through TriggersLink

                trigger.Body = "function f() {var x = 10;}";
                trigger      = await client.ReplaceTriggerAsync(trigger);

                results = await SqlQueryTriggers(client, collection.SelfLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqTriggerName), 10);

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 trigger");
                Assert.AreEqual(trigger.ResourceId, ((QueryResult)results[0]).ResourceId);
                Assert.AreEqual(trigger.ResourceId, (await client.ReadTriggerAsync(trigger.SelfLink)).Resource.ResourceId);
                results = await SqlQueryTriggers(client, collection.SelfLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id=""{0}""", uniqTriggerName), 10);  // query through collection link

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 trigger");
                results = await SqlQueryTriggers(client, collection.TriggersLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id=""{0}""", uniqTriggerName), 10);  // query through TriggersLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 trigger");

                string uniqUserDefinedFunctionName = "SmokeTestUserDefinedFunction" + Guid.NewGuid().ToString("N");
                CosmosUserDefinedFunctionSettings userDefinedFunction = await client.CreateUserDefinedFunctionAsync(collection.SelfLink, new CosmosUserDefinedFunctionSettings { Id = uniqUserDefinedFunctionName, Body = "function (){ var x = 10;}" });

                results = await SqlQueryUserDefinedFunctions(client, collection.SelfLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqUserDefinedFunctionName), 10);  // query through collection link

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 userDefinedFunction");
                Assert.AreEqual(userDefinedFunction.ResourceId, ((QueryResult)results[0]).ResourceId);
                results = await SqlQueryUserDefinedFunctions(client, collection.UserDefinedFunctionsLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqUserDefinedFunctionName), 10);  // query through UserDefinedFunctionsLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 userDefinedFunction");
                Assert.AreEqual(userDefinedFunction.ResourceId, ((QueryResult)results[0]).ResourceId);
                Assert.AreEqual(1, (await ReadFeedUserDefinedFunctions(client, collection.SelfLink)).Count(item => item.Id == uniqUserDefinedFunctionName));                 // read through collection link
                Assert.AreEqual(1, (await ReadFeedUserDefinedFunctions(client, collection.UserDefinedFunctionsLink)).Count(item => item.Id == uniqUserDefinedFunctionName)); // read through UserDefinedFunctionsLink
                userDefinedFunction.Body = "function (){ var x = 10;}";
                userDefinedFunction      = await client.ReplaceUserDefinedFunctionAsync(userDefinedFunction);

                results = await SqlQueryUserDefinedFunctions(client, collection.SelfLink, string.Format(@"select r._rid from root r where r.id = ""{0}""", uniqUserDefinedFunctionName), 10);

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 userDefinedFunction");
                Assert.AreEqual(userDefinedFunction.ResourceId, ((QueryResult)results[0]).ResourceId);
                Assert.AreEqual(userDefinedFunction.ResourceId, (await client.ReadUserDefinedFunctionAsync(userDefinedFunction.SelfLink)).Resource.ResourceId);
                results = await SqlQueryUserDefinedFunctions(client, collection.SelfLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id=""{0}""", uniqUserDefinedFunctionName), 10);  // query through collection link

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 userDefinedFunction");
                results = await SqlQueryUserDefinedFunctions(client, collection.UserDefinedFunctionsLink, string.Format(@"SELECT r.id, r._rid FROM root r WHERE r.id=""{0}""", uniqUserDefinedFunctionName), 10);  // query through UserDefinedFunctionsLink

                Assert.AreEqual(1, results.Count, "Should have queried and found 1 userDefinedFunction");

                //Test select array
                var    queryArray = client.CreateDocumentQuery(collection.SelfLink, "SELECT VALUE [1, 2, 3, 4]").AsDocumentQuery();
                JArray result     = queryArray.ExecuteNextAsync().Result.FirstOrDefault();

                Assert.AreEqual(result[0], 1);
                Assert.AreEqual(result[1], 2);
                Assert.AreEqual(result[2], 3);
                Assert.AreEqual(result[3], 4);

                RequestOptions requestOptions = new RequestOptions {
                    PartitionKey = new PartitionKey(document.Id)
                };
                await client.DeleteDocumentAsync(document.SelfLink, requestOptions);
            }

            foreach (CosmosContainerSettings collection in testCollections)
            {
                await client.DeleteDocumentCollectionAsync(collection.SelfLink);
            }
            await client.DeleteDatabaseAsync(database.SelfLink);
        }
示例#29
0
        /// <summary>
        /// Extracts effective <see cref="PartitionKeyInternal"/> from deserialized document.
        /// </summary>
        /// <remarks>
        /// This code doesn't do any validation, as it assumes that IndexingPolicy is valid, as it is coming from the backend.
        /// Expected format is "/prop1/prop2/?". No array expressions are expected.
        /// </remarks>
        /// <param name="document">Deserialized document to extract partition key value from.</param>
        /// <param name="partitionKeyDefinition">Information about partition key.</param>
        /// <returns>Instance of <see cref="PartitionKeyInternal"/>.</returns>
        public static PartitionKeyInternal ExtractPartitionKeyValue(Document document, PartitionKeyDefinition partitionKeyDefinition)
        {
            if (partitionKeyDefinition == null || partitionKeyDefinition.Paths.Count == 0)
            {
                return(PartitionKeyInternal.Empty);
            }

            if (document.GetType().IsSubclassOf(typeof(Document)))
            {
                return(DocumentAnalyzer.ExtractPartitionKeyValue(document, partitionKeyDefinition, (doc) => JToken.FromObject(doc)));
            }
            else
            {
                return(PartitionKeyInternal.FromObjectArray(
                           partitionKeyDefinition.Paths.Select(path =>
                {
                    string[] parts = PathParser.GetPathParts(path);
                    Debug.Assert(parts.Length >= 1, "Partition key component definition path is invalid.");

                    return document.GetValueByPath <object>(parts, Undefined.Value);
                }).ToArray(),
                           false));
            }
        }
        public ResourceNode(DocumentClient client, dynamic document, ResourceType resoureType, PartitionKeyDefinition partitionKey = null)
        {
            this.resourceType = resoureType;
            if (this.resourceType == ResourceType.Document)
            {
                string prefix = string.Empty;
                if (partitionKey !=null)
                {
                    if (partitionKey.Paths.Count > 0)
                    {
                        string path = partitionKey.Paths[0];
                        prefix = document.GetPropertyValue<String>(path.Substring(1));
                        prefix = prefix + "_";
                    }
                }
                this.Text = prefix  + (document as Resource).Id;
            }
            else if (this.resourceType == ResourceType.Offer)
            {
                string version = document.GetPropertyValue<String>("offerVersion");
                if (string.IsNullOrEmpty(version))
                {
                    Offer offer = document as Offer;
                    this.Text = offer.OfferType + "_" + offer.GetPropertyValue<String>("offerResourceId");
                }
                else
                {
                    OfferV2 offer = document as OfferV2;
                    this.Text = offer.Content.OfferThroughput + "_" + offer.GetPropertyValue<String>("offerResourceId");
                }
            }
            else
            {
                this.Text = (document as Resource).Id;
            }

            this.Tag = document;
            this.client = client;

            {
                MenuItem menuItem = new MenuItem("Read " + this.resourceType.ToString());
                menuItem.Click += new EventHandler(myMenuItemRead_Click);
                this.contextMenu.MenuItems.Add(menuItem);
            }

            if (this.resourceType != ResourceType.Conflict && this.resourceType != ResourceType.Offer)
            {
                MenuItem menuItem = new MenuItem("Replace " + this.resourceType.ToString());
                menuItem.Click += new EventHandler(myMenuItemUpdate_Click);
                this.contextMenu.MenuItems.Add(menuItem);
            }
            if (this.resourceType != ResourceType.Offer)
            {
                MenuItem menuItem = new MenuItem("Delete " + this.resourceType.ToString());
                menuItem.Click += new EventHandler(myMenuItemDelete_Click);
                this.contextMenu.MenuItems.Add(menuItem);
            }

            if (this.resourceType == ResourceType.Permission)
            {
                this.ImageKey = "Permission";
                this.SelectedImageKey = "Permission";
            }
            else if (this.resourceType == ResourceType.Attachment)
            {
                this.ImageKey = "Attachment";
                this.SelectedImageKey = "Attachment";

                {
                    MenuItem menuItem = new MenuItem("Download media");
                    menuItem.Click += new EventHandler(myMenuItemDownloadMedia_Click);
                    this.contextMenu.MenuItems.Add(menuItem);
                }
                {
                    MenuItem menuItem = new MenuItem("Render media");
                    menuItem.Click += new EventHandler(myMenuItemRenderMedia_Click);
                    this.contextMenu.MenuItems.Add(menuItem);
                }
            }
            else if (this.resourceType == ResourceType.StoredProcedure || this.resourceType == ResourceType.Trigger || this.resourceType == ResourceType.UserDefinedFunction)
            {
                this.ImageKey = "Javascript";
                this.SelectedImageKey = "Javascript";
                if (this.resourceType == ResourceType.StoredProcedure)
                {
                    MenuItem menuItem = new MenuItem("Execute " + this.resourceType.ToString());
                    menuItem.Click += new EventHandler(myMenuItemExecuteStoredProcedure_Click);
                    this.contextMenu.MenuItems.Add(menuItem);
                }
            }
            else if (this.resourceType == ResourceType.User)
            {
                this.ImageKey = "User";
                this.SelectedImageKey = "User";

                this.Nodes.Add(new PermissionNode(this.client));
            }
            else if (this.resourceType == ResourceType.Document)
            {
                this.Nodes.Add(new TreeNode("Fake"));

                this.contextMenu.MenuItems.Add("-");

                {
                    MenuItem menuItem = new MenuItem("Create attachment");
                    menuItem.Click += new EventHandler(myMenuItemCreateAttachment_Click);
                    this.contextMenu.MenuItems.Add(menuItem);
                }
                {
                    MenuItem menuItem = new MenuItem("Create attachment from file");
                    menuItem.Click += new EventHandler(myMenuItemAttachmentFromFile_Click);
                    this.contextMenu.MenuItems.Add(menuItem);
                }
            }
            else if (this.resourceType == ResourceType.Conflict)
            {
                this.ImageKey = "Conflict";
                this.SelectedImageKey = "Conflict";
            }
            else if (this.resourceType == ResourceType.Offer)
            {
                this.ImageKey = "Offer";
                this.SelectedImageKey = "Offer";
            }
        }
示例#31
0
        public static async Task Main(string[] args)
        {
            //use below code only once to connect or to create a db
            using (DocumentClient client = new DocumentClient(_endpointUri, _primaryKey))
            {
                // creating new database instance
                Database targetDB = new Database {
                    Id = "EntertainmentDatabase"
                };
                // create if targetDB doesnot exist
                targetDB = await client.CreateDatabaseIfNotExistsAsync(targetDB);

                await Console.Out.WriteLineAsync($"Database Self-link:\t{targetDB.SelfLink}");
            }


            //Fixed Collection creation
            using (DocumentClient client = new DocumentClient(_endpointUri, _primaryKey))
            {
                await client.OpenAsync();

                Uri databaseLink = UriFactory.CreateDatabaseUri("EntertainmentDatabase");
                DocumentCollection defaultCollection = new DocumentCollection {
                    Id = "DefaultCollection"
                };
                defaultCollection = await client.CreateDocumentCollectionAsync(databaseLink, defaultCollection);

                await Console.Out.WriteLineAsync($"Default Collection Self-Link\t{defaultCollection.SelfLink}");
            }


            //Unlimited Collection or Custome Collection
            using (DocumentClient client = new DocumentClient(_endpointUri, _primaryKey))
            {
                await client.OpenAsync();

                Uri            databaseLink   = UriFactory.CreateDatabaseUri("EntertainmentDatabase");
                IndexingPolicy indexingPolicy = new IndexingPolicy
                {
                    IndexingMode  = IndexingMode.Consistent,
                    Automatic     = true,
                    IncludedPaths = new Collection <IncludedPath> {
                        new IncludedPath {
                            Path    = "/*",
                            Indexes = new Collection <Index> {
                                new RangeIndex(DataType.Number, -1),
                                new RangeIndex(DataType.String, -1)
                            }
                        }
                    }
                };
                PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition
                {
                    Paths = new Collection <string> {
                        "/type"
                    }
                };
                DocumentCollection customCollection = new DocumentCollection
                {
                    Id             = "CustomCollection",
                    PartitionKey   = partitionKeyDefinition,
                    IndexingPolicy = indexingPolicy
                };
                RequestOptions requestOptions = new RequestOptions
                {
                    OfferThroughput = 10000
                };
                customCollection = await client.CreateDocumentCollectionIfNotExistsAsync(databaseLink, customCollection, requestOptions);

                await Console.Out.WriteLineAsync($"Custom Collection Self-Link:\t{customCollection.SelfLink}");
            }

            //populating foodInteractions
            using (DocumentClient client = new DocumentClient(_endpointUri, _primaryKey))
            {
                await client.OpenAsync();

                Uri collectionLink   = UriFactory.CreateDocumentCollectionUri("EntertainmentDatabase", "CustomCollection");
                var foodInteractions = new Bogus.Faker <PurchaseFoodOrBeverage>()
                                       .RuleFor(i => i.type, (fake) => nameof(PurchaseFoodOrBeverage))
                                       .RuleFor(i => i.unitPrice, (fake) => Math.Round(fake.Random.Decimal(1.99m, 15.9m), 2))
                                       .RuleFor(i => i.quantity, (fake) => fake.Random.Number(1, 5))
                                       .RuleFor(i => i.totalPrice, (fake, user) => Math.Round(user.unitPrice * user.quantity, 2))
                                       .Generate(500);
                foreach (var interaction in foodInteractions)
                {
                    ResourceResponse <Document> result = await client.CreateDocumentAsync(collectionLink, interaction);

                    await Console.Out.WriteLineAsync($"Document #{foodInteractions.IndexOf(interaction):000} Created\t{result.Resource.Id}");
                }
                ;
            }

            //populating tv interactions
            using (DocumentClient client = new DocumentClient(_endpointUri, _primaryKey))
            {
                await client.OpenAsync();

                Uri collectionLink = UriFactory.CreateDocumentCollectionUri("EntertainmentDatabase", "CustomCollection");
                var tvInteractions = new Bogus.Faker <WatchLiveTelevisionChannel>()
                                     .RuleFor(i => i.type, (fake) => nameof(WatchLiveTelevisionChannel))
                                     .RuleFor(i => i.minutesViewed, (fake) => fake.Random.Number(1, 45))
                                     .RuleFor(i => i.channelName, (fake) => fake.PickRandom(new List <string> {
                    "NEWS-6", "DRAMA-15", "ACTION-12", "DOCUMENTARY-4", "SPORTS-8"
                }))
                                     .Generate(500);
                foreach (var interaction in tvInteractions)
                {
                    ResourceResponse <Document> result = await client.CreateDocumentAsync(collectionLink, interaction);

                    await Console.Out.WriteLineAsync($"Document #{tvInteractions.IndexOf(interaction):000} Created\t{result.Resource.Id}");
                }
            }

            //populating Map interactions
            using (DocumentClient client = new DocumentClient(_endpointUri, _primaryKey))
            {
                await client.OpenAsync();

                Uri collectionLink  = UriFactory.CreateDocumentCollectionUri("EntertainmentDatabase", "CustomCollection");
                var mapInteractions = new Bogus.Faker <ViewMap>()
                                      .RuleFor(i => i.type, (fake) => nameof(ViewMap))
                                      .RuleFor(i => i.minutesViewed, (fake) => fake.Random.Number(1, 45))
                                      .Generate(500);
                foreach (var interaction in mapInteractions)
                {
                    ResourceResponse <Document> result = await client.CreateDocumentAsync(collectionLink, interaction);

                    await Console.Out.WriteLineAsync($"Document #{mapInteractions.IndexOf(interaction):000} Created\t{result.Resource.Id}");
                }
            }
        }