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); }
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); }