public async System.Threading.Tasks.Task TestBatch() { IUserRequest meRequest = graphClient.Me.Request(); IGraphServiceUsersCollectionRequest newUserRequest = graphClient.Users.Request(); // We have the ./users URL, query parameters, and request headers. User newUser = new User(); newUser.DisplayName = "New User"; newUser.UserPrincipalName = "*****@*****.**"; IDirectoryObjectWithReferenceRequest managerRequest = graphClient.Me.Manager.Request(); // We have the /me/manager URL, query parameters, and request headers. IDriveItemChildrenCollectionRequest driveRequest = graphClient.Me.Drive.Root.Children.Request(); // We have the /me/drive/root/children URL, query parameters, and request headers. IEducationRootRequest eduRequest = graphClient.Education.Request(); // We have the /education URL, query parameters, and request headers. BatchContainer batchContainer = new BatchContainer(); BatchPart part1 = batchContainer.AddToBatch(meRequest, Method.GET); // I don't think we need a copy of the BatchPart. batchContainer.AddToBatch(driveRequest, Method.GET); batchContainer.AddToBatch(eduRequest, Method.GET); batchContainer.AddToBatch(newUserRequest, Method.POST, 4, newUser, new BatchPart[] { part1 }); // We have to use reflection to determine which HttpVerb method we are using, and then, what // the return type will be. This might be costly batch scenario can contain a large number BatchResponse response = await graphClient.Batch.PostAsync(batchContainer); // of requests across many batches. I think we want to avoid reflection. User me = (User)response.batchResponses.Where(i => i.id == 1).First().body; // No auto-deserialization. User me2 = (User)response.batchResponses.Where(i => i.body.GetType() == typeof(User)).FirstOrDefault().body; foreach (BatchResponsePart part in response.batchResponses) { var responseItem = part.body; // If we deserialize into a dynamic object, the customer would have int statusCode = part.status; } Assert.IsNotNull(me.UserPrincipalName); }
public async Task <(SyncContext, BatchInfo, ChangesStatistics)> GetChangeBatchAsync(SyncContext context, ScopeInfo scopeInfo) { // While we have an other batch to process var isLastBatch = false; // Create the BatchInfo and SyncContext to return at the end BatchInfo changes = new BatchInfo(); changes.Directory = BatchInfo.GenerateNewDirectoryName(); SyncContext syncContext = null; ChangesStatistics changesStatistics = null; while (!isLastBatch) { HttpMessage httpMessage = new HttpMessage(); httpMessage.SyncContext = context; httpMessage.Step = HttpStep.GetChangeBatch; httpMessage.GetChangeBatch = new HttpGetChangeBatchMessage { ScopeInfo = scopeInfo, BatchIndexRequested = changes.BatchIndex }; var httpMessageResponse = await this.httpRequestHandler.ProcessRequest(context, httpMessage, cancellationToken); if (httpMessageResponse == null) { throw new Exception("Can't have an empty body"); } if (httpMessageResponse.GetChangeBatch == null) { throw new Exception("Can't have an empty GetChangeBatch"); } changesStatistics = httpMessageResponse.GetChangeBatch.ChangesStatistics; changes.InMemory = httpMessageResponse.GetChangeBatch.InMemory; syncContext = httpMessageResponse.SyncContext; // get the bpi and add it to the BatchInfo var bpi = httpMessageResponse.GetChangeBatch.BatchPartInfo; if (bpi != null) { changes.BatchIndex = bpi.Index; changes.BatchPartsInfo.Add(bpi); isLastBatch = bpi.IsLastBatch; } else { changes.BatchIndex = 0; isLastBatch = true; // break the while { } story break; } if (changes.InMemory) { // load the DmSet in memory bpi.Set = httpMessageResponse.GetChangeBatch.Set.ConvertToDmSet(); } else { // Serialize the file ! var bpId = BatchInfo.GenerateNewFileName(changes.BatchIndex.ToString()); var fileName = Path.Combine(this.serviceConfiguration.BatchDirectory, changes.Directory, bpId); BatchPart.Serialize(httpMessageResponse.GetChangeBatch.Set, fileName); bpi.FileName = fileName; } // Clear the DmSetSurrogate from response, we don't need it anymore httpMessageResponse.GetChangeBatch.Set.Dispose(); httpMessageResponse.GetChangeBatch.Set = null; // if not last, increment batchIndex for next request if (!isLastBatch) { changes.BatchIndex++; } } return(syncContext, changes, changesStatistics); }
public async Task <(SyncContext, BatchInfo, ChangesSelected)> GetChangeBatchAsync( SyncContext context, MessageGetChangesBatch message) { // While we have an other batch to process var isLastBatch = false; // Create the BatchInfo and SyncContext to return at the end BatchInfo changes = new BatchInfo { Directory = BatchInfo.GenerateNewDirectoryName() }; SyncContext syncContext = null; ChangesSelected changesSelected = null; while (!isLastBatch) { HttpMessage httpMessage = new HttpMessage { SyncContext = context, Step = HttpStep.GetChangeBatch, Content = new HttpMessageGetChangesBatch { ScopeInfo = message.ScopeInfo, BatchIndexRequested = changes.BatchIndex, DownloadBatchSizeInKB = message.DownloadBatchSizeInKB, BatchDirectory = message.BatchDirectory, Schema = new DmSetSurrogate(message.Schema), Filters = message.Filters, Policy = message.Policy, SerializationFormat = message.SerializationFormat } }; var httpMessageResponse = await this.httpRequestHandler.ProcessRequest(httpMessage, message.SerializationFormat, cancellationToken); if (httpMessageResponse == null) { throw new Exception("Can't have an empty body"); } HttpMessageGetChangesBatch httpMessageContent; if (httpMessageResponse.Content is HttpMessageGetChangesBatch) { httpMessageContent = httpMessageResponse.Content as HttpMessageGetChangesBatch; } else { httpMessageContent = (httpMessageResponse.Content as JObject).ToObject <HttpMessageGetChangesBatch>(); } if (httpMessageContent == null) { throw new Exception("Can't have an empty GetChangeBatch"); } changesSelected = httpMessageContent.ChangesSelected; changes.InMemory = httpMessageContent.InMemory; syncContext = httpMessageResponse.SyncContext; // get the bpi and add it to the BatchInfo var bpi = httpMessageContent.BatchPartInfo; if (bpi != null) { changes.BatchIndex = bpi.Index; changes.BatchPartsInfo.Add(bpi); isLastBatch = bpi.IsLastBatch; } else { changes.BatchIndex = 0; isLastBatch = true; // break the while { } story break; } if (changes.InMemory) { // load the DmSet in memory bpi.Set = httpMessageContent.Set.ConvertToDmSet(); } else { // Serialize the file ! var bpId = BatchInfo.GenerateNewFileName(changes.BatchIndex.ToString()); var fileName = Path.Combine(message.BatchDirectory, changes.Directory, bpId); BatchPart.Serialize(httpMessageContent.Set, fileName); bpi.FileName = fileName; bpi.Clear(); } // Clear the DmSetSurrogate from response, we don't need it anymore if (httpMessageContent.Set != null) { httpMessageContent.Set.Dispose(); httpMessageContent.Set = null; } // if not last, increment batchIndex for next request if (!isLastBatch) { changes.BatchIndex++; } } return(syncContext, changes, changesSelected); }
private async Task <HttpMessage> ApplyChangesAsync(HttpMessage httpMessage) { HttpMessageApplyChanges httpMessageContent; if (httpMessage.Content is HttpMessageApplyChanges) { httpMessageContent = httpMessage.Content as HttpMessageApplyChanges; } else { httpMessageContent = (httpMessage.Content as JObject).ToObject <HttpMessageApplyChanges>(); } if (httpMessageContent == null) { throw new ArgumentException("ApplyChanges message could not be null"); } var scopeInfo = httpMessageContent.FromScope; if (scopeInfo == null) { throw new ArgumentException("ApplyChanges ScopeInfo could not be null"); } var schema = httpMessageContent.Schema.ConvertToDmSet(); BatchInfo batchInfo; var bpi = httpMessageContent.BatchPartInfo; if (httpMessageContent.InMemory) { batchInfo = new BatchInfo { BatchIndex = 0, BatchPartsInfo = new List <BatchPartInfo>(new[] { bpi }), InMemory = true }; bpi.Set = httpMessageContent.Set.ConvertToDmSet(); httpMessageContent.Set.Dispose(); httpMessageContent.Set = null; var(c, s) = await this.ApplyChangesAsync(httpMessage.SyncContext, new MessageApplyChanges { FromScope = scopeInfo, Schema = schema, Policy = httpMessageContent.Policy, UseBulkOperations = httpMessageContent.UseBulkOperations, ScopeInfoTableName = httpMessageContent.ScopeInfoTableName, Changes = batchInfo }); httpMessageContent.ChangesApplied = s; httpMessageContent.BatchPartInfo.Clear(); httpMessageContent.BatchPartInfo.FileName = null; httpMessage.SyncContext = c; httpMessage.Content = httpMessageContent; return(httpMessage); } // not in memory batchInfo = this.LocalProvider.CacheManager.GetValue <BatchInfo>("ApplyChanges_BatchInfo"); if (batchInfo == null) { batchInfo = new BatchInfo { BatchIndex = 0, BatchPartsInfo = new List <BatchPartInfo>(new[] { bpi }), InMemory = false, Directory = BatchInfo.GenerateNewDirectoryName() }; } else { batchInfo.BatchPartsInfo.Add(bpi); } var bpId = BatchInfo.GenerateNewFileName(httpMessageContent.BatchIndex.ToString()); // to save the file, we should use the local configuration batch directory var fileName = Path.Combine(this.Configuration.BatchDirectory, batchInfo.Directory, bpId); BatchPart.Serialize(httpMessageContent.Set, fileName); bpi.FileName = fileName; this.LocalProvider.CacheManager.Set("ApplyChanges_BatchInfo", batchInfo); // Clear the httpMessage set if (httpMessageContent != null) { httpMessageContent.Set.Dispose(); httpMessageContent.Set = null; } // if it's last batch sent if (bpi.IsLastBatch) { var(c, s) = await this.ApplyChangesAsync(httpMessage.SyncContext, new MessageApplyChanges { FromScope = scopeInfo, Schema = schema, Policy = httpMessageContent.Policy, UseBulkOperations = httpMessageContent.UseBulkOperations, ScopeInfoTableName = httpMessageContent.ScopeInfoTableName, Changes = batchInfo }); this.LocalProvider.CacheManager.Remove("ApplyChanges_BatchInfo"); httpMessage.SyncContext = c; httpMessageContent.ChangesApplied = s; } httpMessageContent.BatchPartInfo.Clear(); httpMessageContent.BatchPartInfo.FileName = null; httpMessage.Content = httpMessageContent; return(httpMessage); }
private async Task <HttpMessage> ApplyChangesAsync(HttpMessage httpMessage) { if (httpMessage.ApplyChanges == null) { throw new ArgumentException("ApplyChanges message could not be null"); } var scopeInfo = httpMessage.ApplyChanges.ScopeInfo; if (scopeInfo == null) { throw new ArgumentException("ApplyChanges ScopeInfo could not be null"); } BatchInfo batchInfo; var bpi = httpMessage.ApplyChanges.BatchPartInfo; if (httpMessage.ApplyChanges.InMemory) { batchInfo = new BatchInfo { BatchIndex = 0, BatchPartsInfo = new List <BatchPartInfo>(new[] { bpi }), InMemory = true }; bpi.Set = httpMessage.ApplyChanges.Set.ConvertToDmSet(); httpMessage.ApplyChanges.Set.Dispose(); httpMessage.ApplyChanges.Set = null; var(c, s) = await this.ApplyChangesAsync(httpMessage.SyncContext, scopeInfo, batchInfo); httpMessage.SyncContext = c; httpMessage.ApplyChanges.ChangesStatistics = s; httpMessage.ApplyChanges.BatchPartInfo.Clear(); httpMessage.ApplyChanges.BatchPartInfo.FileName = null; return(httpMessage); } // not in memory batchInfo = this.LocalProvider.CacheManager.GetValue <BatchInfo>("ApplyChanges_BatchInfo"); if (batchInfo == null) { batchInfo = new BatchInfo { BatchIndex = 0, BatchPartsInfo = new List <BatchPartInfo>(new[] { bpi }), InMemory = false, Directory = BatchInfo.GenerateNewDirectoryName() }; } else { batchInfo.BatchPartsInfo.Add(bpi); } var bpId = BatchInfo.GenerateNewFileName(httpMessage.ApplyChanges.BatchIndex.ToString()); var fileName = Path.Combine(this.LocalProvider.GetCacheConfiguration().BatchDirectory, batchInfo.Directory, bpId); BatchPart.Serialize(httpMessage.ApplyChanges.Set, fileName); bpi.FileName = fileName; this.LocalProvider.CacheManager.Set("ApplyChanges_BatchInfo", batchInfo); // Clear the httpMessage set if (httpMessage.ApplyChanges != null) { httpMessage.ApplyChanges.Set.Dispose(); httpMessage.ApplyChanges.Set = null; } // if it's last batch sent if (bpi.IsLastBatch) { var(c, s) = await this.ApplyChangesAsync(httpMessage.SyncContext, scopeInfo, batchInfo); this.LocalProvider.CacheManager.Remove("ApplyChanges_BatchInfo"); httpMessage.SyncContext = c; httpMessage.ApplyChanges.ChangesStatistics = s; } httpMessage.ApplyChanges.BatchPartInfo.Clear(); httpMessage.ApplyChanges.BatchPartInfo.FileName = null; return(httpMessage); }