예제 #1
0
        private async Task<IEnumerable<Task<SynchronizationReport>>> SynchronizeDestinationAsync(SynchronizationDestination destination, bool forceSyncingAll)
        {
            ICredentials credentials = null;
            if (string.IsNullOrEmpty(destination.Username) == false)
            {
                credentials = string.IsNullOrEmpty(destination.Domain)
                    ? new NetworkCredential(destination.Username, destination.Password)
                    : new NetworkCredential(destination.Username, destination.Password, destination.Domain);
            }

            var destinationSyncClient = new SynchronizationServerClient(destination.ServerUrl, destination.FileSystem, destination.ApiKey, credentials);

            bool repeat;

            do
            {
                var lastETag = await destinationSyncClient.GetLastSynchronizationFromAsync(storage.Id).ConfigureAwait(false);

                var activeTasks = synchronizationQueue.Active;
                var filesNeedConfirmation = GetSyncingConfigurations(destination).Where(sync => activeTasks.All(x => x.FileName != sync.FileName)).ToList();

                var confirmations = await ConfirmPushedFiles(filesNeedConfirmation, destinationSyncClient).ConfigureAwait(false);

                var needSyncingAgain = new List<FileHeader>();

                foreach (var confirmation in confirmations)
                {
                    if (confirmation.Status == FileStatus.Safe)
                    {
                        Log.Debug("Destination server {0} said that file '{1}' is safe", destination, confirmation.FileName);
                        RemoveSyncingConfiguration(confirmation.FileName, destination.Url);
                    }
                    else
                    {
                        storage.Batch(accessor =>
                        {
                            var fileHeader = accessor.ReadFile(confirmation.FileName);

                            if (fileHeader != null)
                            {
                                needSyncingAgain.Add(fileHeader);

                                Log.Debug("Destination server {0} said that file '{1}' is {2}.", destination, confirmation.FileName, confirmation.Status);
                            }
                        });
                    }
                }

                if (synchronizationQueue.NumberOfPendingSynchronizationsFor(destination.Url) < AvailableSynchronizationRequestsTo(destination.Url))
                {
                    repeat = await EnqueueMissingUpdatesAsync(destinationSyncClient, lastETag, needSyncingAgain).ConfigureAwait(false) == false;
                }
                else
                    repeat = false;
            }
            while (repeat);
            
            return SynchronizePendingFilesAsync(destinationSyncClient, forceSyncingAll);
        }
예제 #2
0
        public async Task<SynchronizationReport> SynchronizeFileToAsync(string fileName, SynchronizationDestination destination)
        {
            ICredentials credentials = null;
            if (string.IsNullOrEmpty(destination.Username) == false)
            {
                credentials = string.IsNullOrEmpty(destination.Domain)
                                  ? new NetworkCredential(destination.Username, destination.Password)
                                  : new NetworkCredential(destination.Username, destination.Password, destination.Domain);
            }

            var conventions = new FilesConvention();
            if (string.IsNullOrEmpty(destination.AuthenticationScheme) == false)
                conventions.AuthenticationScheme = destination.AuthenticationScheme;

            var destinationClient = new SynchronizationServerClient(destination.ServerUrl, destination.FileSystem, convention: conventions, apiKey: destination.ApiKey, credentials: credentials);

            RavenJObject destinationMetadata;

            try
            {
                destinationMetadata = await destinationClient.GetMetadataForAsync(fileName).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                var exceptionMessage = "Could not get metadata details for " + fileName + " from " + destination.Url;
                Log.WarnException(exceptionMessage, ex);

                return new SynchronizationReport(fileName, Guid.Empty, SynchronizationType.Unknown)
                {
                    Exception = new SynchronizationException(exceptionMessage, ex)
                };
            }

            RavenJObject localMetadata = GetLocalMetadata(fileName);

            NoSyncReason reason;
            SynchronizationWorkItem work = synchronizationStrategy.DetermineWork(fileName, localMetadata, destinationMetadata, FileSystemUrl, out reason);

            if (work == null)
            {
                Log.Debug("File '{0}' was not synchronized to {1}. {2}", fileName, destination.Url, reason.GetDescription());

                return new SynchronizationReport(fileName, Guid.Empty, SynchronizationType.Unknown)
                {
                    Exception = new SynchronizationException(reason.GetDescription())
                };
            }

            return await PerformSynchronizationAsync(destinationClient, work).ConfigureAwait(false);
        }