private void FinishSynchronization(string fileName, SynchronizationReport report, ServerInfo sourceServer, Guid sourceFileETag) { try { // we want to execute those operation in a single batch but we also have to ensure that // Raven/Synchronization/Sources/sourceServerId config is modified only by one finishing synchronization at the same time SynchronizationFinishLocks.GetOrAdd(sourceServer.Id, new ReaderWriterLockSlim()).EnterWriteLock(); SynchronizationTask.IncomingSynchronizationFinished(fileName, sourceServer, sourceFileETag); Storage.Batch(accessor => { SaveSynchronizationReport(fileName, accessor, report); FileLockManager.UnlockByDeletingSyncConfiguration(fileName, accessor); if (report.Exception == null) { SaveSynchronizationSourceInformation(sourceServer, sourceFileETag, accessor); } }); } catch (Exception ex) { Log.ErrorException( string.Format("Failed to finish synchronization of a file '{0}' from {1}", fileName, sourceServer), ex); } finally { SynchronizationFinishLocks.GetOrAdd(sourceServer.Id, new ReaderWriterLockSlim()).ExitWriteLock(); } }
public async Task Should_report_that_file_is_broken_if_last_synchronization_set_exception() { var destinationClient = NewClient(0); var sampleGuid = Guid.NewGuid(); var failureSynchronization = new SynchronizationReport("test.bin", sampleGuid, SynchronizationType.Unknown) { Exception = new Exception("There was an exception in last synchronization.") }; await destinationClient.Config.SetConfig(RavenFileNameHelper.SyncResultNameForFile("test.bin"), failureSynchronization); var confirmations = await destinationClient.Synchronization .ConfirmFilesAsync(new List <Tuple <string, Guid> > { new Tuple <string, Guid>( "test.bin", sampleGuid) }); confirmations = confirmations.ToList(); Assert.Equal(1, confirmations.Count()); Assert.Equal(FileStatus.Broken, confirmations.ToArray()[0].Status); Assert.Equal("test.bin", confirmations.ToArray()[0].FileName); }
public void PostReport(SynchronizationReport report) { if (report == null) { throw new Exception("Test Failed!"); } SynchronizationReport = report; }
public void AddReport(SynchronizationReport report) { if (report.HasErrors || AcceptAddingReportsWithJustWarnings && report.HasWarnings || AcceptAddingReportsWithoutWarningsOrErrors) { _inner.AddReport(report); } }
public void Update(SynchronizationReport report) { ProfileStatusViewModel profileStatusViewModel; if (_profileStatusViewModelsById.TryGetValue(report.ProfileId, out profileStatusViewModel)) { profileStatusViewModel.Update(report); } }
protected virtual void OnReportAdded(SynchronizationReportName name, SynchronizationReport report) { var handler = ReportAdded; if (handler != null) { handler(this, new ReportAddedEventArgs(report, name)); } }
public SynchronizationRunSummary(SynchronizationReport report) { StartTimeUtc = report.StartTime; Result = report.HasErrors ? SyncronizationRunResult.Error : report.HasWarnings ? SyncronizationRunResult.Warning : SyncronizationRunResult.Ok; }
private SynchronizationReportName GetNextFreeName(string directory, SynchronizationReport report) { var reportName = SynchronizationReportName.Create(report.ProfileId, report.StartTime, report.HasWarnings, report.HasErrors); while (File.Exists(Path.Combine(directory, reportName.ToString()))) { reportName = reportName.IncreaseSequence(); } return(reportName); }
public void Update(SynchronizationReport report) { _lastSyncronizationRun = report.StartTime; LastResult = report.HasErrors ? SyncronizationRunResult.Error : report.HasWarnings ? SyncronizationRunResult.Warning : SyncronizationRunResult.Ok; RecalculateLastRunAgoInMinutes(); }
public void AddReport(SynchronizationReport report) { var reportName = GetNextFreeName(_reportDirectory, report); using (var fileStream = File.Create(Path.Combine(_reportDirectory, reportName.ToString()))) { Serializer <SynchronizationReport> .SerializeTo(report, fileStream); } OnReportAdded(reportName, report); }
public static ReportViewModel CreateDesignInstance(bool hasWarnings = false, bool hasErrors = false) { var report = new SynchronizationReport(); report.ADelta = "This is the ADelta"; report.BDelta = "This is the BDelta"; var reportName = SynchronizationReportName.Create(Guid.NewGuid(), new DateTime(2000, 10, 10), hasWarnings, hasErrors); var proxy = new ReportProxy(reportName, () => report, "The profile name"); return(new ReportViewModel(proxy, NullSynchronizationReportRepository.Instance)); }
private void AddReportViewModel(SynchronizationReportName reportName, SynchronizationReport report) { string profileName; if (!_currentProfileNamesById.TryGetValue(reportName.SyncronizationProfileId, out profileName)) { profileName = "<Not existing anymore>"; } var reportProxy = new ReportProxy(reportName, () => report, profileName); var reportViewModel = new ReportViewModel(reportProxy, _reportRepository); _reports.Add(reportViewModel); }
public void NotifyUser(SynchronizationReport report, bool notifyWarnings, bool notifyErrors) { if (report.HasErrors && notifyErrors) { _nofifyIcon.ShowBalloonTip( 10 * 1000, ComponentContainer.MessageBoxTitle, $"Syncronization profile '{report.ProfileName}' executed with error(s).", ToolTipIcon.Error); } else if (report.HasWarnings && notifyWarnings) { _nofifyIcon.ShowBalloonTip( 10 * 1000, ComponentContainer.MessageBoxTitle, $"Syncronization profile '{report.ProfileName}' executed with warnings(s).", ToolTipIcon.Warning); } }
private SynchronizationReport GetSynchronizationReport(string fileName) { SynchronizationReport preResult = null; Storage.Batch( accessor => { try { var name = RavenFileNameHelper.SyncResultNameForFile(fileName); preResult = accessor.GetConfig(name).JsonDeserialization <SynchronizationReport>(); } catch (FileNotFoundException) { // just ignore } }); return(preResult); }
public async Task Big_character_file_test(long size) { var sourceContent = new RandomCharacterStream(size); var destinationContent = new RandomlyModifiedStream(new RandomCharacterStream(size), 0.01); var destinationClient = NewAsyncClient(0); var sourceClient = NewAsyncClient(1); var sourceMetadata = new RavenJObject { {"SomeTest-metadata", "some-value"} }; var destinationMetadata = new RavenJObject { {"SomeTest-metadata", "should-be-overwritten"} }; await destinationClient.UploadAsync("test.bin", destinationContent, destinationMetadata); await sourceClient.UploadAsync("test.bin", sourceContent, sourceMetadata); SynchronizationReport result = SyncTestUtils.ResolveConflictAndSynchronize(sourceClient, destinationClient, "test.bin"); Assert.Equal(sourceContent.Length, result.BytesCopied + result.BytesTransfered); }
private void SaveAndShowReport(SynchronizationReport report) { if (report.HasErrors || _logReportsWithJustWarnings && report.HasWarnings || _logReportsWithoutWarningsOrErrors) { var reportName = _synchronizationReportRepository.AddReport(report); if (IsReportsViewVisible) { ShowReportsImplementation(); // show to bring it into foreground return; } var hasErrors = report.HasErrors; var hasWarnings = report.HasWarnings; if (hasErrors || hasWarnings) { if (hasWarnings && _showReportsWithWarningsImmediately || hasErrors && _showReportsWithErrorsImmediately) { ShowReportsImplementation(); var reportNameAsString = reportName.ToString(); _currentReportsViewModel.SelectReportByName(reportNameAsString); return; } var handler = SynchronizationFailedWhileReportsFormWasNotVisible; if (handler != null) { handler(this, EventArgs.Empty); } } } }
public void PostReport(SynchronizationReport report) { SaveAndShowReport(report); _permanentStatusesViewModel.Update(report.ProfileId, new SynchronizationRunSummary(report)); _trayNotifier.NotifyUser(report, _showReportsWithWarningsImmediately, _showReportsWithErrorsImmediately); }
public ReportAddedEventArgs(SynchronizationReport report, SynchronizationReportName reportName) : base(report) { _reportName = reportName; }
public void PostReport(SynchronizationReport report) { SaveAndShowReport(report); _profileStatusesViewModel.Update(report); _trayNotifier.NotifyUser(report, _showReportsWithWarningsImmediately, _showReportsWithErrorsImmediately); }
private void SaveSynchronizationReport(string fileName, IStorageActionsAccessor accessor, SynchronizationReport report) { var name = RavenFileNameHelper.SyncResultNameForFile(fileName); accessor.SetConfig(name, JsonExtensions.ToJObject(report)); }
public async Task <HttpResponseMessage> MultipartProceed(string fileSystemName) { if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } var fileName = Request.Headers.GetValues(SyncingMultipartConstants.FileName).FirstOrDefault(); var canonicalFilename = FileHeader.Canonize(fileName); var tempFileName = RavenFileNameHelper.DownloadingFileName(canonicalFilename); var sourceServerInfo = ReadInnerHeaders.Value <ServerInfo>(SyncingMultipartConstants.SourceServerInfo); var sourceFileETag = Guid.Parse(GetHeader(Constants.MetadataEtagField).Trim('\"')); var report = new SynchronizationReport(canonicalFilename, sourceFileETag, SynchronizationType.ContentUpdate); Log.Debug("Starting to process multipart synchronization request of a file '{0}' with ETag {1} from {2}", fileName, sourceFileETag, sourceServerInfo); StorageStream localFile = null; var isNewFile = false; var isConflictResolved = false; try { Storage.Batch(accessor => { AssertFileIsNotBeingSynced(canonicalFilename, accessor); FileLockManager.LockByCreatingSyncConfiguration(canonicalFilename, sourceServerInfo, accessor); }); SynchronizationTask.IncomingSynchronizationStarted(canonicalFilename, sourceServerInfo, sourceFileETag, SynchronizationType.ContentUpdate); PublishSynchronizationNotification(fileSystemName, canonicalFilename, sourceServerInfo, report.Type, SynchronizationAction.Start); Storage.Batch(accessor => StartupProceed(canonicalFilename, accessor)); RavenJObject sourceMetadata = GetFilteredMetadataFromHeaders(ReadInnerHeaders); var localMetadata = GetLocalMetadata(canonicalFilename); if (localMetadata != null) { AssertConflictDetection(canonicalFilename, localMetadata, sourceMetadata, sourceServerInfo, out isConflictResolved); localFile = StorageStream.Reading(Storage, canonicalFilename); } else { isNewFile = true; } Historian.UpdateLastModified(sourceMetadata); var synchronizingFile = SynchronizingFileStream.CreatingOrOpeningAndWriting(Storage, Search, StorageOperationsTask, tempFileName, sourceMetadata); var provider = new MultipartSyncStreamProvider(synchronizingFile, localFile); Log.Debug("Starting to process/read multipart content of a file '{0}'", fileName); await Request.Content.ReadAsMultipartAsync(provider); Log.Debug("Multipart content of a file '{0}' was processed/read", fileName); report.BytesCopied = provider.BytesCopied; report.BytesTransfered = provider.BytesTransfered; report.NeedListLength = provider.NumberOfFileParts; synchronizingFile.PreventUploadComplete = false; synchronizingFile.Flush(); synchronizingFile.Dispose(); sourceMetadata["Content-MD5"] = synchronizingFile.FileHash; Storage.Batch(accessor => accessor.UpdateFileMetadata(tempFileName, sourceMetadata)); Storage.Batch(accessor => { StorageOperationsTask.IndicateFileToDelete(canonicalFilename); accessor.RenameFile(tempFileName, canonicalFilename); Search.Delete(tempFileName); Search.Index(canonicalFilename, sourceMetadata); }); if (isNewFile) { Log.Debug("Temporary downloading file '{0}' was renamed to '{1}'. Indexes were updated.", tempFileName, fileName); } else { Log.Debug("Old file '{0}' was deleted. Indexes were updated.", fileName); } if (isConflictResolved) { ConflictArtifactManager.Delete(canonicalFilename); } } catch (Exception ex) { if (ShouldAddExceptionToReport(ex)) { report.Exception = ex; } } finally { if (localFile != null) { localFile.Dispose(); } } if (report.Exception == null) { Log.Debug( "File '{0}' was synchronized successfully from {1}. {2} bytes were transfered and {3} bytes copied. Need list length was {4}", fileName, sourceServerInfo, report.BytesTransfered, report.BytesCopied, report.NeedListLength); } else { Log.WarnException( string.Format("Error has occurred during synchronization of a file '{0}' from {1}", fileName, sourceServerInfo), report.Exception); } FinishSynchronization(canonicalFilename, report, sourceServerInfo, sourceFileETag); PublishFileNotification(fileName, isNewFile ? FileChangeAction.Add : FileChangeAction.Update); PublishSynchronizationNotification(fileSystemName, fileName, sourceServerInfo, report.Type, SynchronizationAction.Finish); if (isConflictResolved) { Publisher.Publish(new ConflictNotification { FileName = fileName, Status = ConflictStatus.Resolved }); } return(GetMessageWithObject(report)); }
private async Task <SynchronizationReport> PerformSynchronizationAsync(ISynchronizationServerClient synchronizationServerClient, SynchronizationWorkItem work) { var destinationUrl = synchronizationServerClient.BaseUrl; if (Log.IsDebugEnabled) { Log.Debug("Starting to perform {0} for a file '{1}' and a destination server {2}", work.GetType().Name, work.FileName, destinationUrl); } if (AvailableSynchronizationRequestsTo(destinationUrl) <= 0) { if (Log.IsDebugEnabled) { Log.Debug("The limit of active synchronizations to {0} server has been achieved. Cannot process a file '{1}'.", destinationUrl, work.FileName); } if (synchronizationQueue.EnqueueSynchronization(destinationUrl, work)) { publisher.Publish(new SynchronizationUpdateNotification { FileName = work.FileName, DestinationFileSystemUrl = destinationUrl, SourceServerId = storage.Id, SourceFileSystemUrl = FileSystemUrl, Type = work.SynchronizationType, Action = SynchronizationAction.Enqueue, Direction = SynchronizationDirection.Outgoing }); } return(new SynchronizationReport(work.FileName, work.FileETag, work.SynchronizationType) { Exception = new SynchronizationException(string.Format( "The limit of active synchronizations to {0} server has been achieved. Cannot process a file '{1}'.", destinationUrl, work.FileName)) }); } string fileName = work.FileName; synchronizationQueue.SynchronizationStarted(work, destinationUrl); publisher.Publish(new SynchronizationUpdateNotification { FileName = work.FileName, DestinationFileSystemUrl = destinationUrl, SourceServerId = storage.Id, SourceFileSystemUrl = FileSystemUrl, Type = work.SynchronizationType, Action = SynchronizationAction.Start, Direction = SynchronizationDirection.Outgoing }); SynchronizationReport report; try { report = await work.PerformAsync(synchronizationServerClient).ConfigureAwait(false); } catch (Exception ex) { report = new SynchronizationReport(work.FileName, work.FileETag, work.SynchronizationType) { Exception = ex, }; } var synchronizationCancelled = false; if (report.Exception == null) { var moreDetails = string.Empty; if (work.SynchronizationType == SynchronizationType.ContentUpdate) { moreDetails = string.Format(". {0} bytes were transferred and {1} bytes copied. Need list length was {2}", report.BytesTransfered, report.BytesCopied, report.NeedListLength); } context.UpdateSuccessfulSynchronizationTime(); if (Log.IsDebugEnabled) { Log.Debug("{0} to {1} has finished successfully{2}", work, destinationUrl, moreDetails); } } else { if (work.IsCancelled || report.Exception is TaskCanceledException) { synchronizationCancelled = true; if (Log.IsDebugEnabled) { Log.DebugException(string.Format("{0} to {1} was canceled", work, destinationUrl), report.Exception); } } else { Log.WarnException(string.Format("{0} to {1} has finished with the exception", work, destinationUrl), report.Exception); } } Queue.SynchronizationFinished(work, destinationUrl); if (synchronizationCancelled == false) { CreateSyncingConfiguration(fileName, work.FileETag, destinationUrl, work.SynchronizationType); } publisher.Publish(new SynchronizationUpdateNotification { FileName = work.FileName, DestinationFileSystemUrl = destinationUrl, SourceServerId = storage.Id, SourceFileSystemUrl = FileSystemUrl, Type = work.SynchronizationType, Action = SynchronizationAction.Finish, Direction = SynchronizationDirection.Outgoing }); return(report); }
public HttpResponseMessage Delete(string fileSystemName, string fileName) { var canonicalFilename = FileHeader.Canonize(fileName); var sourceServerInfo = ReadInnerHeaders.Value <ServerInfo>(SyncingMultipartConstants.SourceServerInfo); var sourceFileETag = Guid.Parse(GetHeader(Constants.MetadataEtagField).Trim('\"')); Log.Debug("Starting to delete a file '{0}' with ETag {1} from {2} because of synchronization", fileName, sourceFileETag, sourceServerInfo); var report = new SynchronizationReport(canonicalFilename, sourceFileETag, SynchronizationType.Delete); try { Storage.Batch(accessor => { AssertFileIsNotBeingSynced(canonicalFilename, accessor); FileLockManager.LockByCreatingSyncConfiguration(canonicalFilename, sourceServerInfo, accessor); }); SynchronizationTask.IncomingSynchronizationStarted(canonicalFilename, sourceServerInfo, sourceFileETag, SynchronizationType.Delete); PublishSynchronizationNotification(fileSystemName, canonicalFilename, sourceServerInfo, report.Type, SynchronizationAction.Start); Storage.Batch(accessor => StartupProceed(canonicalFilename, accessor)); var localMetadata = GetLocalMetadata(canonicalFilename); if (localMetadata != null) { // REVIEW: Use InnerHeaders for consistency? var sourceMetadata = GetFilteredMetadataFromHeaders(Request.Headers); // Request.Headers.FilterHeadersToObject(); bool isConflictResolved; AssertConflictDetection(canonicalFilename, localMetadata, sourceMetadata, sourceServerInfo, out isConflictResolved); Storage.Batch(accessor => { StorageOperationsTask.IndicateFileToDelete(canonicalFilename); var tombstoneMetadata = new RavenJObject { { SynchronizationConstants.RavenSynchronizationHistory, localMetadata[SynchronizationConstants.RavenSynchronizationHistory] }, { SynchronizationConstants.RavenSynchronizationVersion, localMetadata[SynchronizationConstants.RavenSynchronizationVersion] }, { SynchronizationConstants.RavenSynchronizationSource, localMetadata[SynchronizationConstants.RavenSynchronizationSource] } }.WithDeleteMarker(); Historian.UpdateLastModified(tombstoneMetadata); accessor.PutFile(canonicalFilename, 0, tombstoneMetadata, true); }); PublishFileNotification(fileName, FileChangeAction.Delete); } } catch (Exception ex) { if (ShouldAddExceptionToReport(ex)) { report.Exception = ex; Log.WarnException(string.Format("Error was occurred during deletion synchronization of file '{0}' from {1}", fileName, sourceServerInfo), ex); } } finally { FinishSynchronization(canonicalFilename, report, sourceServerInfo, sourceFileETag); } PublishSynchronizationNotification(fileSystemName, fileName, sourceServerInfo, report.Type, SynchronizationAction.Finish); if (report.Exception == null) { Log.Debug("File '{0}' was deleted during synchronization from {1}", fileName, sourceServerInfo); } return(this.GetMessageWithObject(report, HttpStatusCode.OK)); }
public HttpResponseMessage UpdateMetadata(string fileSystemName, string fileName) { bool isConflictResolved = false; var canonicalFilename = FileHeader.Canonize(fileName); var sourceServerInfo = ReadInnerHeaders.Value <ServerInfo>(SyncingMultipartConstants.SourceServerInfo); // REVIEW: (Oren) It works, but it seems to me it is not an scalable solution. var sourceFileETag = Guid.Parse(GetHeader(Constants.MetadataEtagField).Trim('\"')); Log.Debug("Starting to update a metadata of file '{0}' with ETag {1} from {2} because of synchronization", fileName, sourceFileETag, sourceServerInfo); var report = new SynchronizationReport(canonicalFilename, sourceFileETag, SynchronizationType.MetadataUpdate); try { Storage.Batch(accessor => { AssertFileIsNotBeingSynced(canonicalFilename, accessor); FileLockManager.LockByCreatingSyncConfiguration(canonicalFilename, sourceServerInfo, accessor); }); SynchronizationTask.IncomingSynchronizationStarted(canonicalFilename, sourceServerInfo, sourceFileETag, SynchronizationType.MetadataUpdate); PublishSynchronizationNotification(fileSystemName, canonicalFilename, sourceServerInfo, report.Type, SynchronizationAction.Start); Storage.Batch(accessor => StartupProceed(canonicalFilename, accessor)); var localMetadata = GetLocalMetadata(canonicalFilename); var sourceMetadata = GetFilteredMetadataFromHeaders(ReadInnerHeaders); AssertConflictDetection(canonicalFilename, localMetadata, sourceMetadata, sourceServerInfo, out isConflictResolved); Historian.UpdateLastModified(sourceMetadata); Storage.Batch(accessor => accessor.UpdateFileMetadata(canonicalFilename, sourceMetadata)); Search.Index(canonicalFilename, sourceMetadata); if (isConflictResolved) { ConflictArtifactManager.Delete(canonicalFilename); } PublishFileNotification(fileName, FileChangeAction.Update); } catch (Exception ex) { if (ShouldAddExceptionToReport(ex)) { report.Exception = ex; Log.WarnException( string.Format("Error was occurred during metadata synchronization of file '{0}' from {1}", fileName, sourceServerInfo), ex); } } finally { FinishSynchronization(canonicalFilename, report, sourceServerInfo, sourceFileETag); } PublishSynchronizationNotification(fileSystemName, fileName, sourceServerInfo, report.Type, SynchronizationAction.Finish); if (isConflictResolved) { Publisher.Publish(new ConflictNotification { FileName = fileName, Status = ConflictStatus.Resolved }); } if (report.Exception == null) { Log.Debug("Metadata of file '{0}' was synchronized successfully from {1}", fileName, sourceServerInfo); } return(this.GetMessageWithObject(report, HttpStatusCode.OK)); }
public ReportEventArgs(SynchronizationReport report) { _report = report; }
public SynchronizationReportName AddReport(SynchronizationReport report) { throw new NotSupportedException(); }
public void NotifyUser(SynchronizationReport report, bool notifyWarnings, bool notifyErrors) { }
private async Task ExecuteContentUpdate(RavenJObject localMetadata, SynchronizationReport report) { var tempFileName = RavenFileNameHelper.DownloadingFileName(fileName); using (var localFile = localMetadata != null ? StorageStream.Reading(fs.Storage, fileName) : null) { fs.PutTriggers.Apply(trigger => trigger.OnPut(tempFileName, sourceMetadata)); fs.Historian.UpdateLastModified(sourceMetadata); var synchronizingFile = SynchronizingFileStream.CreatingOrOpeningAndWriting(fs, tempFileName, sourceMetadata); fs.PutTriggers.Apply(trigger => trigger.AfterPut(tempFileName, null, sourceMetadata)); var provider = new MultipartSyncStreamProvider(synchronizingFile, localFile); if (Log.IsDebugEnabled) { Log.Debug("Starting to process/read multipart content of a file '{0}'", fileName); } await MultipartContent.ReadAsMultipartAsync(provider).ConfigureAwait(false); if (Log.IsDebugEnabled) { Log.Debug("Multipart content of a file '{0}' was processed/read", fileName); } report.BytesCopied = provider.BytesCopied; report.BytesTransfered = provider.BytesTransfered; report.NeedListLength = provider.NumberOfFileParts; synchronizingFile.PreventUploadComplete = false; synchronizingFile.Flush(); synchronizingFile.Dispose(); sourceMetadata["Content-MD5"] = synchronizingFile.FileHash; FileUpdateResult updateResult = null; fs.Storage.Batch(accessor => updateResult = accessor.UpdateFileMetadata(tempFileName, sourceMetadata, null)); fs.Storage.Batch(accessor => { using (fs.DisableAllTriggersForCurrentThread()) { fs.Files.IndicateFileToDelete(fileName, null); } accessor.RenameFile(tempFileName, fileName); fs.Search.Delete(tempFileName); fs.Search.Index(fileName, sourceMetadata, updateResult.Etag); }); if (Log.IsDebugEnabled) { var message = localFile == null ? string.Format("Temporary downloading file '{0}' was renamed to '{1}'. Indexes were updated.", tempFileName, fileName) : string.Format("Old file '{0}' was deleted. Indexes were updated.", fileName); Log.Debug(message); } fs.Publisher.Publish(new FileChangeNotification { File = fileName, Action = localFile == null ? FileChangeAction.Add : FileChangeAction.Update }); } }
public async Task <SynchronizationReport> Execute() { var report = new SynchronizationReport(fileName, sourceFileEtag, type); try { AssertOperationAndLockFile(); NotifyStart(); Prepare(); var localMetadata = fs.Synchronizations.GetLocalMetadata(fileName); bool conflictResolved; AssertConflictDetection(localMetadata, out conflictResolved); fs.SynchronizationTriggers.Apply(trigger => trigger.BeforeSynchronization(fileName, sourceMetadata, type)); dynamic afterSynchronizationTriggerData = null; switch (type) { case SynchronizationType.Delete: ExecuteDelete(localMetadata); break; case SynchronizationType.Rename: ExecuteRename(Rename); break; case SynchronizationType.MetadataUpdate: ExecuteMetadataUpdate(); break; case SynchronizationType.ContentUpdate: await ExecuteContentUpdate(localMetadata, report).ConfigureAwait(false); afterSynchronizationTriggerData = new { TempFileName = RavenFileNameHelper.DownloadingFileName(fileName) }; break; default: throw new ArgumentOutOfRangeException("type", type.ToString()); } fs.SynchronizationTriggers.Apply(trigger => trigger.AfterSynchronization(fileName, sourceMetadata, type, afterSynchronizationTriggerData)); if (conflictResolved) { fs.ConflictArtifactManager.Delete(fileName); fs.Publisher.Publish(new ConflictNotification { FileName = fileName, Status = ConflictStatus.Resolved }); } } catch (Exception ex) { if (ShouldAddExceptionToReport(ex)) { report.Exception = ex; Log.WarnException(string.Format("Error was occurred during deletion synchronization of file '{0}' from {1}", fileName, sourceFs), ex); } } fs.Synchronizations.FinishSynchronization(fileName, report, sourceFs, sourceFileEtag); NotifyEnd(); return(report); }
public HttpResponseMessage Rename(string fileSystemName, string fileName, string rename) { bool isConflictResolved = false; var canonicalFilename = FileHeader.Canonize(fileName); var canonicalRename = FileHeader.Canonize(rename); var sourceServerInfo = ReadInnerHeaders.Value <ServerInfo>(SyncingMultipartConstants.SourceServerInfo); var sourceFileETag = Guid.Parse(GetHeader(Constants.MetadataEtagField).Trim('\"')); var sourceMetadata = GetFilteredMetadataFromHeaders(ReadInnerHeaders); Log.Debug("Starting to rename a file '{0}' to '{1}' with ETag {2} from {3} because of synchronization", fileName, rename, sourceFileETag, sourceServerInfo); var report = new SynchronizationReport(canonicalFilename, sourceFileETag, SynchronizationType.Rename); try { Storage.Batch(accessor => { AssertFileIsNotBeingSynced(canonicalFilename, accessor); FileLockManager.LockByCreatingSyncConfiguration(canonicalFilename, sourceServerInfo, accessor); }); SynchronizationTask.IncomingSynchronizationStarted(canonicalFilename, sourceServerInfo, sourceFileETag, SynchronizationType.Rename); PublishSynchronizationNotification(fileSystemName, canonicalFilename, sourceServerInfo, report.Type, SynchronizationAction.Start); Storage.Batch(accessor => StartupProceed(canonicalFilename, accessor)); var localMetadata = GetLocalMetadata(canonicalFilename); AssertConflictDetection(canonicalFilename, localMetadata, sourceMetadata, sourceServerInfo, out isConflictResolved); if (isConflictResolved) { ConflictArtifactManager.Delete(canonicalFilename); } StorageOperationsTask.RenameFile(new RenameFileOperation { FileSystem = FileSystem.Name, Name = canonicalFilename, Rename = canonicalRename, MetadataAfterOperation = sourceMetadata.WithETag(sourceFileETag).DropRenameMarkers() }); } catch (Exception ex) { if (ShouldAddExceptionToReport(ex)) { report.Exception = ex; Log.WarnException(string.Format("Error was occurred during renaming synchronization of file '{0}' from {1}", fileName, sourceServerInfo), ex); } } finally { FinishSynchronization(canonicalFilename, report, sourceServerInfo, sourceFileETag); } PublishSynchronizationNotification(fileSystemName, canonicalFilename, sourceServerInfo, report.Type, SynchronizationAction.Finish); if (isConflictResolved) { Publisher.Publish(new ConflictNotification { FileName = fileName, Status = ConflictStatus.Resolved }); } if (report.Exception == null) { Log.Debug("File '{0}' was renamed to '{1}' during synchronization from {2}", fileName, rename, sourceServerInfo); } return(GetMessageWithObject(report)); }