public async Task ShouldFailOver() { var sourceClient = NewClient(0); var destinationClient = NewClient(1); var source1Content = new RandomStream(10000); await sourceClient.UploadAsync("test1.bin", source1Content); var destination = new SynchronizationDestination() { FileSystem = destinationClient.FileSystemName, ServerUrl = destinationClient.ServerUrl }; await sourceClient.Config.SetDestinationsConfig(destination); sourceClient.ReplicationInformer.RefreshReplicationInformation(sourceClient); await sourceClient.Synchronization.SynchronizeDestinationsAsync(); var destinationFiles = await destinationClient.GetFilesAsync("/"); Assert.Equal(1, destinationFiles.FileCount); Assert.Equal(1, destinationFiles.Files.Length); var server = GetServer(0); server.Dispose(); var fileFromSync = await sourceClient.GetFilesAsync("/"); Assert.Equal(1, fileFromSync.FileCount); Assert.Equal(1, fileFromSync.Files.Length); }
private IEnumerable<SynchronizationDetails> GetSyncingConfigurations(SynchronizationDestination destination) { IList<SynchronizationDetails> configObjects = new List<SynchronizationDetails>(); try { storage.Batch( accessor => { configObjects = accessor.GetConfigsStartWithPrefix(RavenFileNameHelper.SyncNamePrefix + Uri.EscapeUriString(destination.FileSystemUrl), 0, 100) .Select(config => config.JsonDeserialization<SynchronizationDetails>()) .ToList(); }); } catch (Exception e) { Log.WarnException(string.Format("Could not get syncing configurations for a destination {0}", destination), e); } return configObjects; }
private async Task<DestinationSyncResult> SynchronizeDestinationAsync(SynchronizationDestination destination, bool forceSyncingContinuation) { try { 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 destinationClient = new RavenFileSystemClient(destination.ServerUrl, destination.FileSystem, apiKey: destination.ApiKey, credentials: credentials).Synchronization; var lastETag = await destinationClient.GetLastSynchronizationFromAsync(storage.Id); var activeTasks = synchronizationQueue.Active.ToList(); var filesNeedConfirmation = GetSyncingConfigurations(destination).Where(sync => activeTasks.All(x => x.FileName != sync.FileName)).ToList(); var confirmations = await ConfirmPushedFiles(filesNeedConfirmation, destinationClient); 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.FileSystemUrl); } 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); } }); } } await EnqueueMissingUpdatesAsync(destinationClient, lastETag, needSyncingAgain); var reports = await Task.WhenAll(SynchronizePendingFilesAsync(destinationClient, forceSyncingContinuation)); var destinationSyncResult = new DestinationSyncResult { DestinationServer = destination.ServerUrl, DestinationFileSystem = destination.FileSystem }; if (reports.Length > 0) { var successfulSynchronizationsCount = reports.Count(x => x.Exception == null); var failedSynchronizationsCount = reports.Count(x => x.Exception != null); if (successfulSynchronizationsCount > 0 || failedSynchronizationsCount > 0) { Log.Debug( "Synchronization to a destination {0} has completed. {1} file(s) were synchronized successfully, {2} synchronization(s) were failed", destination.FileSystemUrl, successfulSynchronizationsCount, failedSynchronizationsCount); } destinationSyncResult.Reports = reports; } return destinationSyncResult; } catch (Exception ex) { Log.WarnException(string.Format("Failed to perform a synchronization to a destination {0}", destination), ex); return new DestinationSyncResult { DestinationServer = destination.ServerUrl, DestinationFileSystem = destination.FileSystem, Exception = ex }; } }
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 destinationClient = new RavenFileSystemClient(destination.ServerUrl, destination.FileSystem, apiKey: destination.ApiKey, credentials: credentials).Synchronization; RavenJObject destinationMetadata; try { destinationMetadata = await destinationClient.GetMetadataForAsync(fileName); } catch (Exception ex) { var exceptionMessage = "Could not get metadata details for " + fileName + " from " + destination.FileSystemUrl; 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.FileSystemUrl, reason.GetDescription()); return new SynchronizationReport(fileName, Guid.Empty, SynchronizationType.Unknown) { Exception = new SynchronizationException(reason.GetDescription()) }; } return await PerformSynchronizationAsync(destinationClient, work); }