Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }