private async Task CompositeIndexImplementation() { Cosmos.IndexingPolicy indexingPolicy = new Cosmos.IndexingPolicy() { Automatic = true, IncludedPaths = new Collection <Cosmos.IncludedPath>() { new Cosmos.IncludedPath() { Path = DefaultPath, } }, ExcludedPaths = new Collection <Cosmos.ExcludedPath>(), IndexingMode = Cosmos.IndexingMode.Consistent, CompositeIndexes = new Collection <Collection <Cosmos.CompositePath> >() { new Collection <Cosmos.CompositePath>() { new Cosmos.CompositePath() { Path = "/name", Order = Cosmos.CompositePathSortOrder.Ascending }, new Cosmos.CompositePath() { Path = "/age", Order = Cosmos.CompositePathSortOrder.Descending } } } }; await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy); }
private async Task SpatialBoundingBoxImplementation() { Cosmos.IndexingPolicy indexingPolicy = new Cosmos.IndexingPolicy() { Automatic = true, IncludedPaths = new Collection <Cosmos.IncludedPath>() { new Cosmos.IncludedPath() { Path = DefaultPath, } }, ExcludedPaths = new Collection <Cosmos.ExcludedPath>(), IndexingMode = Cosmos.IndexingMode.Consistent, SpatialIndexes = new Collection <Cosmos.SpatialPath>() { new Cosmos.SpatialPath { Path = "/location/?", SpatialTypes = new Collection <Cosmos.SpatialType>() { Cosmos.SpatialType.LineString, Cosmos.SpatialType.MultiPolygon, Cosmos.SpatialType.Point, Cosmos.SpatialType.Polygon, }, BoundingBox = new Cosmos.BoundingBoxProperties() { Xmin = 0, Ymin = 0, Xmax = 10, Ymax = 10, } }, new Cosmos.SpatialPath { Path = "/spatial/*", SpatialTypes = new Collection <Cosmos.SpatialType>() { Cosmos.SpatialType.Point }, BoundingBox = new Cosmos.BoundingBoxProperties() { Xmin = 0, Ymin = 0, Xmax = 10, Ymax = 10, } } } }; Cosmos.GeospatialConfig geospatialConfig = new Cosmos.GeospatialConfig(); geospatialConfig.GeospatialType = Cosmos.GeospatialType.Geometry; await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy, geospatialConfig); }
private Task <(Container, IReadOnlyList <CosmosObject>)> CreateNonPartitionedContainerAndIngestDocumentsAsync( IEnumerable <string> documents, Cosmos.IndexingPolicy indexingPolicy = null) { return(this.CreateContainerAndIngestDocumentsAsync( CollectionTypes.NonPartitioned, documents, partitionKey: null, indexingPolicy: indexingPolicy)); }
private Task <(Container, IReadOnlyList <CosmosObject>)> CreateMultiPartitionContainerAndIngestDocumentsAsync( IEnumerable <string> documents, string partitionKey = "/id", Cosmos.IndexingPolicy indexingPolicy = null) { return(this.CreateContainerAndIngestDocumentsAsync( CollectionTypes.MultiPartition, documents, partitionKey, indexingPolicy)); }
public async Task DoubleRoundTrip() { await cosmosClient.Databases.CreateDatabaseIfNotExistsAsync(database.Id); Cosmos.IndexingPolicy indexingPolicy = IndexingPolicyTests.CreateDefaultIndexingPolicy(); CosmosContainerSettings cosmosContainerSettings = new CosmosContainerSettings() { Id = Guid.NewGuid().ToString(), IndexingPolicy = indexingPolicy, }; await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy); }
public async Task ExcludeAll() { Cosmos.IndexingPolicy indexingPolicy = IndexingPolicyTests.CreateDefaultIndexingPolicy(); indexingPolicy.IncludedPaths = new Collection <Cosmos.IncludedPath>(); indexingPolicy.ExcludedPaths = new Collection <Cosmos.ExcludedPath>() { new Cosmos.ExcludedPath() { Path = "/*", } }; await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy); }
public async Task SpatialIndex() { Cosmos.IndexingPolicy indexingPolicy = IndexingPolicyTests.CreateDefaultIndexingPolicy(); indexingPolicy.IncludedPaths = new Collection <Cosmos.IncludedPath>() { new Cosmos.IncludedPath() { Path = DefaultPath, Indexes = new Collection <Cosmos.Index>() { new Cosmos.SpatialIndex(Cosmos.DataType.Point), } } }; await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy); }
private static async Task RoundTripWithLocal(Cosmos.IndexingPolicy indexingPolicy) { PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition { Paths = new System.Collections.ObjectModel.Collection <string>(new[] { "/id" }), Kind = PartitionKind.Hash }; CosmosContainerSettings containerSetting = new CosmosContainerSettings() { Id = Guid.NewGuid().ToString(), IndexingPolicy = indexingPolicy, PartitionKey = partitionKeyDefinition }; CosmosDatabase cosmosDatabase = await cosmosClient.Databases.CreateDatabaseIfNotExistsAsync(IndexingPolicyTests.database.Id); CosmosContainerResponse cosmosContainerResponse = await cosmosDatabase.Containers.CreateContainerAsync(containerSetting); Assert.IsTrue(IndexingPolicyTests.indexingPolicyEqualityComparer.Equals(indexingPolicy, containerSetting.IndexingPolicy)); }
public async Task HashRange() { Cosmos.IndexingPolicy indexingPolicy = IndexingPolicyTests.CreateDefaultIndexingPolicy(); indexingPolicy.IncludedPaths = new Collection <Cosmos.IncludedPath>() { new Cosmos.IncludedPath() { Path = DefaultPath, Indexes = new Collection <Cosmos.Index>() { new Cosmos.HashIndex(Cosmos.DataType.Number, 3), new Cosmos.RangeIndex(Cosmos.DataType.String, -1), } } }; await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy); }
internal Task CreateIngestQueryDeleteAsync <T>( ConnectionModes connectionModes, CollectionTypes collectionTypes, IEnumerable <string> documents, Query <T> query, T testArgs, string partitionKey = "/id", Cosmos.IndexingPolicy indexingPolicy = null, CosmosClientFactory cosmosClientFactory = null) { return(this.CreateIngestQueryDeleteAsync( connectionModes, collectionTypes, documents, query, cosmosClientFactory ?? this.CreateDefaultCosmosClient, testArgs, partitionKey, indexingPolicy)); }
internal Task CreateIngestQueryDeleteAsync( ConnectionModes connectionModes, CollectionTypes collectionTypes, IEnumerable <string> documents, Query query, string partitionKey = "/id", Cosmos.IndexingPolicy indexingPolicy = null, CosmosClientFactory cosmosClientFactory = null) { Task queryWrapper(Container container, IReadOnlyList <CosmosObject> inputDocuments, object throwaway) { return(query(container, inputDocuments)); } return(this.CreateIngestQueryDeleteAsync <object>( connectionModes, collectionTypes, documents, queryWrapper, null, partitionKey, indexingPolicy, cosmosClientFactory)); }
public async Task DefaultIndexingPolicy() { Cosmos.IndexingPolicy indexingPolicy = IndexingPolicyTests.CreateDefaultIndexingPolicy(); await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy); }
/// <summary> /// Task that wraps boiler plate code for query tests (container create -> ingest documents -> query documents -> delete collections). /// Note that this function will take the cross product connectionModes /// </summary> /// <param name="connectionModes">The connection modes to use.</param> /// <param name="documents">The documents to ingest</param> /// <param name="query"> /// The callback for the queries. /// All the standard arguments will be passed in. /// Please make sure that this function is idempotent, since a container will be reused for each connection mode. /// </param> /// <param name="cosmosClientFactory"> /// The callback for the create CosmosClient. This is invoked for the different ConnectionModes that the query is targeting. /// If CosmosClient instantiated by this does not apply the expected ConnectionMode, an assert is thrown. /// </param> /// <param name="partitionKey">The partition key for the partition container.</param> /// <param name="testArgs">The optional args that you want passed in to the query.</param> /// <returns>A task to await on.</returns> internal async Task CreateIngestQueryDeleteAsync <T>( ConnectionModes connectionModes, CollectionTypes collectionTypes, IEnumerable <string> documents, Query <T> query, CosmosClientFactory cosmosClientFactory, T testArgs, string partitionKey = "/id", Cosmos.IndexingPolicy indexingPolicy = null) { try { IList <(Container, IReadOnlyList <CosmosObject>)> collectionsAndDocuments = new List <(Container, IReadOnlyList <CosmosObject>)>(); foreach (CollectionTypes collectionType in Enum.GetValues(collectionTypes.GetType()).Cast <Enum>().Where(collectionTypes.HasFlag)) { if (collectionType == CollectionTypes.None) { continue; } Task <(Container, IReadOnlyList <CosmosObject>)> createContainerTask = collectionType switch { CollectionTypes.NonPartitioned => this.CreateNonPartitionedContainerAndIngestDocumentsAsync( documents, indexingPolicy), CollectionTypes.SinglePartition => this.CreateSinglePartitionContainerAndIngestDocumentsAsync( documents, partitionKey, indexingPolicy), CollectionTypes.MultiPartition => this.CreateMultiPartitionContainerAndIngestDocumentsAsync( documents, partitionKey, indexingPolicy), _ => throw new ArgumentException($"Unknown {nameof(CollectionTypes)} : {collectionType}"), }; collectionsAndDocuments.Add(await createContainerTask); } List <CosmosClient> cosmosClients = new List <CosmosClient>(); foreach (ConnectionModes connectionMode in Enum.GetValues(connectionModes.GetType()).Cast <Enum>().Where(connectionModes.HasFlag)) { if (connectionMode == ConnectionModes.None) { continue; } ConnectionMode targetConnectionMode = GetTargetConnectionMode(connectionMode); CosmosClient cosmosClient = cosmosClientFactory(targetConnectionMode); Assert.AreEqual( targetConnectionMode, cosmosClient.ClientOptions.ConnectionMode, "Test setup: Invalid connection policy applied to CosmosClient"); cosmosClients.Add(cosmosClient); } List <Task> queryTasks = new List <Task>(); foreach (CosmosClient cosmosClient in cosmosClients) { foreach ((Container container, IReadOnlyList <CosmosObject> insertedDocuments) in collectionsAndDocuments) { Task queryTask = Task.Run(() => query(container, insertedDocuments, testArgs)); queryTasks.Add(queryTask); } } await Task.WhenAll(queryTasks); List <Task <ContainerResponse> > deleteContainerTasks = new List <Task <ContainerResponse> >(); foreach (Container container in collectionsAndDocuments.Select(tuple => tuple.Item1)) { deleteContainerTasks.Add(container.DeleteContainerAsync()); } await Task.WhenAll(deleteContainerTasks); } catch (Exception ex) when(ex.GetType() != typeof(AssertFailedException)) { while (ex.InnerException != null) { ex = ex.InnerException; } ExceptionDispatchInfo.Capture(ex).Throw(); } }
private async Task <(Container, IReadOnlyList <CosmosObject>)> CreateContainerAndIngestDocumentsAsync( CollectionTypes collectionType, IEnumerable <string> documents, string partitionKey = "/id", Cosmos.IndexingPolicy indexingPolicy = null) { Container container = collectionType switch { CollectionTypes.NonPartitioned => await this.CreateNonPartitionedContainerAsync(indexingPolicy), CollectionTypes.SinglePartition => await this.CreateSinglePartitionContainer(partitionKey, indexingPolicy), CollectionTypes.MultiPartition => await this.CreateMultiPartitionContainer(partitionKey, indexingPolicy), _ => throw new ArgumentException($"Unknown {nameof(CollectionTypes)} : {collectionType}"), }; List <CosmosObject> insertedDocuments = new List <CosmosObject>(); foreach (string document in documents) { JObject documentObject = JsonConvert.DeserializeObject <JObject>(document); // Add an id if (documentObject["id"] == null) { documentObject["id"] = Guid.NewGuid().ToString(); } // Get partition key value. Cosmos.PartitionKey pkValue; if (partitionKey != null) { string jObjectPartitionKey = partitionKey.Remove(0, 1); JValue pkToken = (JValue)documentObject[jObjectPartitionKey]; if (pkToken == null) { pkValue = Cosmos.PartitionKey.None; } else { switch (pkToken.Type) { case JTokenType.Integer: case JTokenType.Float: pkValue = new Cosmos.PartitionKey(pkToken.Value <double>()); break; case JTokenType.String: pkValue = new Cosmos.PartitionKey(pkToken.Value <string>()); break; case JTokenType.Boolean: pkValue = new Cosmos.PartitionKey(pkToken.Value <bool>()); break; case JTokenType.Null: pkValue = Cosmos.PartitionKey.Null; break; default: throw new ArgumentException("Unknown partition key type"); } } } else { pkValue = Cosmos.PartitionKey.None; } JObject createdDocument = await container.CreateItemAsync(documentObject, pkValue); CosmosObject insertedDocument = CosmosObject.Parse <CosmosObject>(createdDocument.ToString()); insertedDocuments.Add(insertedDocument); } return(container, insertedDocuments); }