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