public override async Task <ResponseMessage> SendAsync( RequestMessage request, CancellationToken cancellationToken) { // We clone the request message as the Content is disposed before we can use it in the test assertions later. this.Received.Add(EncryptionTestHandler.CloneRequestMessage(request)); if (this.func != null) { return(await this.func(request)); } HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError; if (request.ResourceType == ResourceType.ClientEncryptionKey) { DataEncryptionKeyProperties dekProperties = null; if (request.OperationType == OperationType.Create) { dekProperties = this.serializer.FromStream <DataEncryptionKeyProperties>(request.Content); string databaseRid = ResourceId.NewDatabaseId(1).ToString(); dekProperties.ResourceId = ResourceId.NewClientEncryptionKeyId(databaseRid, (uint)this.Received.Count).ToString(); dekProperties.CreatedTime = EncryptionTestHandler.ReducePrecisionToSeconds(DateTime.UtcNow); dekProperties.LastModified = dekProperties.CreatedTime; dekProperties.ETag = Guid.NewGuid().ToString(); dekProperties.SelfLink = string.Format( "dbs/{0}/{1}/{2}/", databaseRid, Paths.ClientEncryptionKeysPathSegment, dekProperties.ResourceId); httpStatusCode = HttpStatusCode.Created; if (!this.Deks.TryAdd(dekProperties.Id, dekProperties)) { httpStatusCode = HttpStatusCode.Conflict; } } else if (request.OperationType == OperationType.Read) { string dekId = EncryptionTestHandler.ParseDekUri(request.RequestUri); httpStatusCode = HttpStatusCode.OK; if (!this.Deks.TryGetValue(dekId, out dekProperties)) { httpStatusCode = HttpStatusCode.NotFound; } } else if (request.OperationType == OperationType.Replace) { string dekId = EncryptionTestHandler.ParseDekUri(request.RequestUri); dekProperties = this.serializer.FromStream <DataEncryptionKeyProperties>(request.Content); dekProperties.LastModified = EncryptionTestHandler.ReducePrecisionToSeconds(DateTime.UtcNow); dekProperties.ETag = Guid.NewGuid().ToString(); httpStatusCode = HttpStatusCode.OK; if (!this.Deks.TryGetValue(dekId, out DataEncryptionKeyProperties existingDekProperties)) { httpStatusCode = HttpStatusCode.NotFound; } if (!this.Deks.TryUpdate(dekId, dekProperties, existingDekProperties)) { throw new InvalidOperationException("Concurrency not handled in tests."); } } else if (request.OperationType == OperationType.Delete) { string dekId = EncryptionTestHandler.ParseDekUri(request.RequestUri); httpStatusCode = HttpStatusCode.NoContent; if (!this.Deks.TryRemove(dekId, out _)) { httpStatusCode = HttpStatusCode.NotFound; } } ResponseMessage responseMessage = new ResponseMessage(httpStatusCode, request) { Content = dekProperties != null?this.serializer.ToStream(dekProperties) : null, }; responseMessage.Headers.RequestCharge = EncryptionUnitTests.requestCharge; responseMessage.Headers.ETag = dekProperties?.ETag; return(responseMessage); } else if (request.ResourceType == ResourceType.Document) { JObject item = null; if (request.OperationType == OperationType.Create) { item = EncryptionUnitTests.ParseStream(request.Content); string itemId = item.Property("id").Value.Value <string>(); httpStatusCode = HttpStatusCode.Created; if (!this.Items.TryAdd(itemId, item)) { httpStatusCode = HttpStatusCode.Conflict; } } else if (request.OperationType == OperationType.Read) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); httpStatusCode = HttpStatusCode.OK; if (!this.Items.TryGetValue(itemId, out item)) { httpStatusCode = HttpStatusCode.NotFound; } } else if (request.OperationType == OperationType.Replace) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); item = EncryptionUnitTests.ParseStream(request.Content); httpStatusCode = HttpStatusCode.OK; if (!this.Items.TryGetValue(itemId, out JObject existingItem)) { httpStatusCode = HttpStatusCode.NotFound; } if (!this.Items.TryUpdate(itemId, item, existingItem)) { throw new InvalidOperationException("Concurrency not handled in tests."); } } else if (request.OperationType == OperationType.Delete) { string itemId = EncryptionTestHandler.ParseItemUri(request.RequestUri); httpStatusCode = HttpStatusCode.NoContent; if (!this.Items.TryRemove(itemId, out _)) { httpStatusCode = HttpStatusCode.NotFound; } } ResponseMessage responseMessage = new ResponseMessage(httpStatusCode, request) { Content = item != null?this.serializer.ToStream(item) : null, }; responseMessage.Headers.RequestCharge = EncryptionUnitTests.requestCharge; return(responseMessage); } return(new ResponseMessage(httpStatusCode, request)); }