public void ValidateItemRequestOptionsMultipleTriggers() { CosmosItemRequestOptions options = new CosmosItemRequestOptions { PreTriggers = new List <string>() { "preTrigger", "preTrigger2", "preTrigger3", "preTrigger4" }, PostTriggers = new List <string>() { "postTrigger", "postTrigger2", "postTrigger3", "postTrigger4", "postTrigger5" } }; CosmosRequestMessage httpRequest = new CosmosRequestMessage( HttpMethod.Post, new Uri("/dbs/testdb/colls/testcontainer/docs/testId", UriKind.Relative)); options.FillRequestOptions(httpRequest); Assert.IsTrue(httpRequest.Headers.TryGetValue(HttpConstants.HttpHeaders.PreTriggerInclude, out string preTriggerHeader)); Assert.IsTrue(httpRequest.Headers.TryGetValue(HttpConstants.HttpHeaders.PostTriggerInclude, out string postTriggerHeader)); }
public async Task RequestOptionsHandlerCanHandleDataPlaneRequestOptions() { const string Condition = "*"; const string SessionToken = "test"; CosmosItemRequestOptions options = new CosmosItemRequestOptions { AccessCondition = new AccessCondition { Type = AccessConditionType.IfNoneMatch, Condition = Condition }, ConsistencyLevel = (Cosmos.ConsistencyLevel)ConsistencyLevel.Eventual, SessionToken = SessionToken }; TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.AreEqual(Condition, request.Headers.GetValues(HttpConstants.HttpHeaders.IfNoneMatch).First()); Assert.AreEqual(ConsistencyLevel.Eventual.ToString(), request.Headers.GetValues(HttpConstants.HttpHeaders.ConsistencyLevel).First()); Assert.AreEqual(SessionToken, request.Headers.GetValues(HttpConstants.HttpHeaders.SessionToken).First()); return(TestHandler.ReturnSuccess()); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = testHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Get, new System.Uri("https://dummy.documents.azure.com:443/dbs")); requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]"); requestMessage.ResourceType = ResourceType.Document; requestMessage.OperationType = OperationType.Read; requestMessage.RequestOptions = options; await invoker.SendAsync(requestMessage, new CancellationToken()); }
public async Task TestNullItemPartitionKeyIsBlocked() { dynamic testItem = new { id = Guid.NewGuid().ToString() }; await VerifyItemNullExceptions(testItem, null); CosmosItemRequestOptions requestOptions = new CosmosItemRequestOptions(); await VerifyItemNullExceptions(testItem, requestOptions); }
public static async Task <T> TryDeleteItemAsync <T>( this CosmosContainer container, object partitionKey, string itemId, CosmosItemRequestOptions cosmosItemRequestOptions = null) { var response = await container.Items.DeleteItemAsync <T>(partitionKey, itemId, cosmosItemRequestOptions).ConfigureAwait(false); if (response.StatusCode == HttpStatusCode.NotFound) { return(default(T)); } return(response.Resource); }
public async Task TestPreProcessingHandler() { CosmosRequestHandler preProcessHandler = new PreProcessingTestHandler(); CosmosClient client = MockDocumentClient.CreateMockCosmosClient((builder) => builder.AddCustomHandlers(preProcessHandler)); Assert.IsTrue(typeof(RequestInvokerHandler).Equals(client.RequestHandler.GetType())); Assert.IsTrue(typeof(PreProcessingTestHandler).Equals(client.RequestHandler.InnerHandler.GetType())); CosmosContainer container = client.Databases["testdb"] .Containers["testcontainer"]; HttpStatusCode[] testHttpStatusCodes = new HttpStatusCode[] { HttpStatusCode.OK, HttpStatusCode.NotFound }; // User operations foreach (HttpStatusCode code in testHttpStatusCodes) { CosmosItemRequestOptions options = new CosmosItemRequestOptions(); options.Properties = new Dictionary <string, object>(); options.Properties.Add(PreProcessingTestHandler.StatusCodeName, code); CosmosItemResponse <object> response = await container.Items.ReadItemAsync <object>("pk1", "id1", options); Console.WriteLine($"Got status code {response.StatusCode}"); Assert.AreEqual(code, response.StatusCode); } // Meta-data operations foreach (HttpStatusCode code in testHttpStatusCodes) { CosmosContainerRequestOptions options = new CosmosContainerRequestOptions(); options.Properties = new Dictionary <string, object>(); options.Properties.Add(PreProcessingTestHandler.StatusCodeName, code); CosmosContainerResponse response = await container.DeleteAsync(options); Console.WriteLine($"Got status code {response.StatusCode}"); Assert.AreEqual(code, response.StatusCode); } }
public async Task ItemRequestOptionAccessConditionTest() { // Create an item ToDoActivity testItem = (await this.CreateRandomItems(1, randomPartitionKey: true)).First(); // Create an access condition that will fail because the etag will be different AccessCondition accessCondition = new AccessCondition { // Random etag Condition = Guid.NewGuid().ToString(), Type = AccessConditionType.IfMatch }; CosmosItemRequestOptions itemRequestOptions = new CosmosItemRequestOptions() { AccessCondition = accessCondition }; try { CosmosItemResponse <ToDoActivity> response = await this.Container.Items.ReplaceItemAsync <ToDoActivity>( partitionKey : testItem.status, id : testItem.id, item : testItem, requestOptions : itemRequestOptions); Assert.Fail("Access condition should have failed"); } catch (CosmosException e) { Assert.IsNotNull(e); Assert.AreEqual(HttpStatusCode.PreconditionFailed, e.StatusCode, e.Message); Assert.IsNotNull(e.ActivityId); Assert.IsTrue(e.RequestCharge > 0); } finally { CosmosItemResponse <ToDoActivity> deleteResponse = await this.Container.Items.DeleteItemAsync <ToDoActivity>(partitionKey : testItem.status, id : testItem.id); Assert.IsNotNull(deleteResponse); } }
public async Task EpkPointReadTest() { string pk = Guid.NewGuid().ToString(); string epk = new PartitionKey(pk) .InternalKey .GetEffectivePartitionKeyString(this.containerSettings.PartitionKey); CosmosItemRequestOptions itemRequestOptions = new CosmosItemRequestOptions(); itemRequestOptions.Properties = new Dictionary <string, object>(); itemRequestOptions.Properties.Add(WFConstants.BackendHeaders.EffectivePartitionKeyString, epk); CosmosResponseMessage response = await this.Container.Items.ReadItemStreamAsync( null, Guid.NewGuid().ToString(), itemRequestOptions); // Ideally it should be NotFound // BadReqeust bcoz collection is regular and not binary Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); }
public async Task ValidateTriggersTest() { // Prevent failures if previous test did not clean up correctly await this.container.Triggers["addTax"].DeleteAsync(); ToDoActivity item = new ToDoActivity() { id = Guid.NewGuid().ToString(), cost = 9001, description = "trigger_test_item", status = "Done", taskNum = 1 }; CosmosTrigger cosmosTrigger = await this.container.Triggers.CreateTriggerAsync( new CosmosTriggerSettings { Id = "addTax", Body = TriggersTests.GetTriggerFunction(".20"), TriggerOperation = TriggerOperation.All, TriggerType = Cosmos.TriggerType.Pre }); CosmosItemRequestOptions options = new CosmosItemRequestOptions() { PreTriggers = new List <string>() { cosmosTrigger.Id }, }; CosmosItemResponse <dynamic> createdItem = await this.container.Items.CreateItemAsync <dynamic>(item.status, item, options); double itemTax = createdItem.Resource.tax; Assert.AreEqual(item.cost * .20, itemTax); // Delete existing user defined functions. await cosmosTrigger.DeleteAsync(); }
public async Task ItemStreamIterator(bool useStatelessIterator) { IList <ToDoActivity> deleteList = await this.CreateRandomItems(3, randomPartitionKey : true); HashSet <string> itemIds = deleteList.Select(x => x.id).ToHashSet <string>(); string lastContinuationToken = null; int pageSize = 1; CosmosItemRequestOptions requestOptions = new CosmosItemRequestOptions(); CosmosFeedResultSetIterator setIterator = this.Container.Items.GetItemStreamIterator(maxItemCount: pageSize, continuationToken: lastContinuationToken, requestOptions: requestOptions); while (setIterator.HasMoreResults) { if (useStatelessIterator) { setIterator = this.Container.Items.GetItemStreamIterator(maxItemCount: pageSize, continuationToken: lastContinuationToken, requestOptions: requestOptions); } using (CosmosResponseMessage responseMessage = await setIterator.FetchNextSetAsync(this.cancellationToken)) { lastContinuationToken = responseMessage.Headers.Continuation; Collection <ToDoActivity> response = new CosmosDefaultJsonSerializer().FromStream <CosmosFeedResponse <ToDoActivity> >(responseMessage.Content).Data; foreach (ToDoActivity toDoActivity in response) { if (itemIds.Contains(toDoActivity.id)) { itemIds.Remove(toDoActivity.id); } } } } Assert.IsNull(lastContinuationToken); Assert.AreEqual(itemIds.Count, 0); }
public override async Task <bool> ReleaseInitializationLockAsync() { string lockId = this.GetStoreLockName(); var requestOptions = new CosmosItemRequestOptions() { AccessCondition = new AccessCondition { Type = AccessConditionType.IfMatch, Condition = this.lockETag } }; var document = await this.container.TryDeleteItemAsync <LockDocument>( this.requestOptionsFactory.GetPartitionKey(lockId), lockId, requestOptions).ConfigureAwait(false); if (document != null) { this.lockETag = null; return(true); } return(false); }
public async Task RequestOptionsHandlerCanHandleRequestOptions() { const string PropertyKey = "propkey"; const string Condition = "*"; object propertyValue = Encoding.UTF8.GetBytes("test"); CosmosRequestOptions options = new CosmosItemRequestOptions { Properties = new Dictionary <string, object>(new List <KeyValuePair <string, object> > { new KeyValuePair <string, object>(PropertyKey, propertyValue) }), AccessCondition = new AccessCondition { Type = AccessConditionType.IfMatch, Condition = Condition } }; TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.AreEqual(propertyValue, request.Properties[PropertyKey]); Assert.AreEqual(Condition, request.Headers.GetValues(HttpConstants.HttpHeaders.IfMatch).First()); return(TestHandler.ReturnSuccess()); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = testHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Get, new System.Uri("https://dummy.documents.azure.com:443/dbs")); requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]"); requestMessage.ResourceType = ResourceType.Document; requestMessage.OperationType = OperationType.Read; requestMessage.RequestOptions = options; await invoker.SendAsync(requestMessage, new CancellationToken()); }
public async Task Delete(string partitionKey, string id, CosmosItemRequestOptions requestOptions = default(CosmosItemRequestOptions), CancellationToken cancellationToken = default(CancellationToken)) { await Container.Items.DeleteItemAsync <T>(partitionKey, id, requestOptions : requestOptions, cancellationToken : cancellationToken); }
public async Task <T> Replace(T item, string partitionKey, string id, CosmosItemRequestOptions requestOptions = default(CosmosItemRequestOptions), CancellationToken cancellationToken = default(CancellationToken)) { var response = await Container.Items.ReplaceItemAsync(partitionKey, id, item, requestOptions : requestOptions, cancellationToken : cancellationToken); return(response.Resource); }
public async Task CrossPartitionBiDirectionalItemReadFeedTest(bool useStatelessIteration) { //create items const int total = 30; const int maxItemCount = 10; List <string> items = new List <string>(); for (int i = 0; i < total; i++) { string item = $@" {{ ""id"": ""{i}"" }}"; using (CosmosResponseMessage createResponse = await this.Container.Items.CreateItemStreamAsync( i.ToString(), CosmosReadFeedTests.GenerateStreamFromString(item), requestOptions: new CosmosItemRequestOptions())) { Assert.IsTrue(createResponse.IsSuccessStatusCode); } } string lastKnownContinuationToken = null; CosmosFeedResultSetIterator iter = this.Container.Database.Containers[this.Container.Id].Items .GetItemStreamIterator(maxItemCount, continuationToken: lastKnownContinuationToken); int count = 0; List <string> forwardOrder = new List <string>(); while (iter.HasMoreResults) { if (useStatelessIteration) { iter = this.Container.Database.Containers[this.Container.Id].Items .GetItemStreamIterator(maxItemCount, continuationToken: lastKnownContinuationToken); } using (CosmosResponseMessage response = await iter.FetchNextSetAsync()) { lastKnownContinuationToken = response.Headers.Continuation; Assert.IsNotNull(response); using (StreamReader reader = new StreamReader(response.Content)) { string json = await reader.ReadToEndAsync(); JArray documents = (JArray)JObject.Parse(json).SelectToken("Documents"); count += documents.Count; if (documents.Any()) { forwardOrder.Add(documents.First().SelectToken("id").ToString()); } } } } Assert.IsNull(lastKnownContinuationToken); Assert.IsNotNull(forwardOrder); Assert.AreEqual(total, count); Assert.IsFalse(forwardOrder.Where(x => string.IsNullOrEmpty(x)).Any()); CosmosItemRequestOptions requestOptions = new CosmosItemRequestOptions(); requestOptions.Properties = requestOptions.Properties = new Dictionary <string, object>(); requestOptions.Properties.Add(HttpConstants.HttpHeaders.EnumerationDirection, (byte)BinaryScanDirection.Reverse); count = 0; List <string> reverseOrder = new List <string>(); lastKnownContinuationToken = null; iter = this.Container.Database.Containers[this.Container.Id].Items .GetItemStreamIterator(maxItemCount, continuationToken: lastKnownContinuationToken, requestOptions: requestOptions); while (iter.HasMoreResults) { if (useStatelessIteration) { iter = this.Container.Database.Containers[this.Container.Id].Items .GetItemStreamIterator(maxItemCount, continuationToken: lastKnownContinuationToken, requestOptions: requestOptions); } using (CosmosResponseMessage response = await iter.FetchNextSetAsync()) { lastKnownContinuationToken = response.Headers.Continuation; Assert.IsNotNull(response); using (StreamReader reader = new StreamReader(response.Content)) { string json = await reader.ReadToEndAsync(); JArray documents = (JArray)JObject.Parse(json).SelectToken("Documents"); count += documents.Count; if (documents.Any()) { reverseOrder.Add(documents.First().SelectToken("id").ToString()); } } } } Assert.IsNull(lastKnownContinuationToken); Assert.IsNotNull(reverseOrder); Assert.AreEqual(total, count); forwardOrder.Reverse(); CollectionAssert.AreEqual(forwardOrder, reverseOrder); Assert.IsFalse(reverseOrder.Where(x => string.IsNullOrEmpty(x)).Any()); }
private async Task VerifyItemNullExceptions( dynamic testItem, CosmosItemRequestOptions requestOptions = null) { TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.Fail("Null partition key should be blocked without the correct request option"); return(null); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient( (cosmosClientBuilder) => cosmosClientBuilder.AddCustomHandlers(testHandler)); CosmosContainer container = client.Databases["testdb"] .Containers["testcontainer"]; await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.CreateItemAsync <dynamic>( partitionKey: null, item: testItem, requestOptions: requestOptions); }, "CreateItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReadItemAsync <dynamic>( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "ReadItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.UpsertItemAsync <dynamic>( partitionKey: null, item: testItem, requestOptions: requestOptions); }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReplaceItemAsync <dynamic>( partitionKey: null, id: testItem.id, item: testItem, requestOptions: requestOptions); }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.DeleteItemAsync <dynamic>( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set."); CosmosDefaultJsonSerializer jsonSerializer = new CosmosDefaultJsonSerializer(); using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.CreateItemStreamAsync( partitionKey: null, streamPayload: itemStream, requestOptions: requestOptions); }, "CreateItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReadItemStreamAsync( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "ReadItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.UpsertItemStreamAsync( partitionKey: null, streamPayload: itemStream, requestOptions: requestOptions); }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReplaceItemStreamAsync( partitionKey: null, id: testItem.id, streamPayload: itemStream, requestOptions: requestOptions); }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.DeleteItemStreamAsync( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set."); } }
private async Task VerifyItemOperations( object partitionKey, string partitionKeySerialized, dynamic testItem, CosmosItemRequestOptions requestOptions = null) { CosmosResponseMessage response = null; HttpStatusCode httpStatusCode = HttpStatusCode.OK; int testHandlerHitCount = 0; TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.IsTrue(request.RequestUri.OriginalString.StartsWith(@"/dbs/testdb/colls/testcontainer")); Assert.AreEqual(requestOptions, request.RequestOptions); Assert.AreEqual(ResourceType.Document, request.ResourceType); Assert.IsNotNull(request.Headers.PartitionKey); Assert.AreEqual(partitionKeySerialized, request.Headers.PartitionKey); testHandlerHitCount++; response = new CosmosResponseMessage(httpStatusCode, request, errorMessage: null); response.Content = request.Content; return(Task.FromResult(response)); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient( (builder) => builder.AddCustomHandlers(testHandler)); CosmosContainer container = client.Databases["testdb"] .Containers["testcontainer"]; CosmosItemResponse <dynamic> itemResponse = await container.Items.CreateItemAsync <dynamic>( partitionKey : partitionKey, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.ReadItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.UpsertItemAsync <dynamic>( partitionKey : partitionKey, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.ReplaceItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.DeleteItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); Assert.AreEqual(5, testHandlerHitCount, "An operation did not make it to the handler"); CosmosDefaultJsonSerializer jsonSerializer = new CosmosDefaultJsonSerializer(); using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.CreateItemStreamAsync( partitionKey: partitionKey, streamPayload: itemStream)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.ReadItemStreamAsync( partitionKey: partitionKey, id: testItem.id, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.UpsertItemStreamAsync( partitionKey: partitionKey, streamPayload: itemStream, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.ReplaceItemStreamAsync( partitionKey: partitionKey, id: testItem.id, streamPayload: itemStream, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.DeleteItemStreamAsync( partitionKey: partitionKey, id: testItem.id, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } Assert.AreEqual(10, testHandlerHitCount, "A stream operation did not make it to the handler"); }