public void Should_not_perform_file_delete_if_it_is_being_synced()
        {
            var filename = FileHeader.Canonize("file.bin");

            var client = NewAsyncClient();
            var rfs    = GetFileSystem();

            client.UploadAsync("file.bin", new MemoryStream(new byte[] { 1, 2, 3, 4, 5 })).Wait();

            rfs.Files.IndicateFileToDelete(filename, null);

            rfs.Storage.Batch(accessor =>
                              accessor.SetConfigurationValue(RavenFileNameHelper.SyncLockNameForFile(filename),
                                                             LockFileTests.SynchronizationConfig(DateTime.UtcNow)));

            rfs.Files.CleanupDeletedFilesAsync().Wait();

            DeleteFileOperation deleteFile = null;

            rfs.Storage.Batch(accessor =>
                              deleteFile = accessor.GetConfigurationValue <DeleteFileOperation>(RavenFileNameHelper.DeleteOperationConfigNameForFile(RavenFileNameHelper.DeletingFileName(filename))));

            Assert.Equal(RavenFileNameHelper.DeletingFileName(filename), deleteFile.CurrentFileName);
            Assert.Equal(filename, deleteFile.OriginalFileName);
        }
        public void Should_not_delete_downloading_file_if_synchronization_retry_is_being_performed()
        {
            const string fileName            = "file.bin";
            var          downloadingFileName = RavenFileNameHelper.DownloadingFileName(fileName);

            var client = NewAsyncClient();
            var rfs    = GetFileSystem();

            client.UploadAsync(fileName, new RandomStream(1)).Wait();

            client.UploadAsync(downloadingFileName, new RandomStream(1)).Wait();

            rfs.Files.IndicateFileToDelete(downloadingFileName, null);

            rfs.Storage.Batch(accessor =>
                              accessor.SetConfigurationValue(RavenFileNameHelper.SyncLockNameForFile(fileName), LockFileTests.SynchronizationConfig(DateTime.UtcNow)));

            rfs.Files.CleanupDeletedFilesAsync().Wait();

            DeleteFileOperation deleteFile = null;

            rfs.Storage.Batch(accessor =>
                              deleteFile = accessor.GetConfigurationValue <DeleteFileOperation>(RavenFileNameHelper.DeleteOperationConfigNameForFile(RavenFileNameHelper.DeletingFileName(downloadingFileName))));

            Assert.Equal(RavenFileNameHelper.DeletingFileName(downloadingFileName), deleteFile.CurrentFileName);
            Assert.Equal(downloadingFileName, deleteFile.OriginalFileName);
        }
        public void RegisterFileDeletion(FileHeader file, Etag etag = null)
        {
            var operation = new DeleteFileOperation(this, file.Path, etag);

            IncrementRequestCount();

            registeredOperations.Enqueue(operation);
        }
        public void RegisterFileDeletion(string path, Etag etag = null)
        {
            var operation = new DeleteFileOperation(this, path, etag);

            IncrementRequestCount();

            registeredOperations.Enqueue(operation);
        }
Example #5
0
        public override object ReadJson(
            JsonReader reader,
            Type objectType,
            object existingValue,
            JsonSerializer serializer)
        {
            JArray ja     = JArray.Load(reader);
            var    result = new List <IRollbackableOperation>();

            foreach (var jsonObject in ja)
            {
                var unit = default(IRollbackableOperation);
                switch (jsonObject["Type"].Value <string>())
                {
                case "AppendAllText":
                    unit = new AppendAllTextOperation(
                        jsonObject["path"].Value <string>(),
                        jsonObject["contents"].Value <string>());
                    break;

                case "Copy":
                    unit = new CopyOperation(
                        jsonObject["sourceFileName"].Value <string>(),
                        jsonObject["path"].Value <string>(),
                        jsonObject["overwrite"].Value <bool>());
                    break;

                case "CreateFile":
                    unit = new CreateFileOperation(
                        jsonObject["path"].Value <string>());
                    break;

                case "Delete":
                    unit = new DeleteFileOperation(
                        jsonObject["path"].Value <string>());
                    break;

                case "Move":
                    unit = new MoveOperation(
                        jsonObject["sourceFileName"].Value <string>(),
                        jsonObject["destFileName"].Value <string>());
                    break;

                case "WriteAllText":
                    unit = new WriteAllTextOperation(
                        jsonObject["path"].Value <string>(),
                        jsonObject["contents"].Value <string>());
                    break;
                }

                serializer.Populate(jsonObject.CreateReader(), unit);
                result.Add(unit);
            }

            return(result);
        }
        public void RegisterFileDeletion(FileHeader file, Etag etag = null)
        {
            deletedEntities.Add(file.Directory);

            var operation = new DeleteFileOperation(this, file.Directory, etag);

            IncrementRequestCount();

            registeredOperations.Enqueue(operation);
        }
Example #7
0
        public void RegisterFileDeletion(string path, Etag etag = null)
        {
			FileHeader existingEntity;
			if (etag == null && UseOptimisticConcurrency && entitiesByKey.TryGetValue(path, out existingEntity))
			{
				if (IsDeleted(path) == false) // do not set etag if we already know that file was deleted
					etag = existingEntity.Etag;
			}

	        deletedEntities.Add(path);

            var operation = new DeleteFileOperation(this, path, etag);

            IncrementRequestCount();

            registeredOperations.Enqueue(operation);
        }
        public void Should_create_apropriate_config_after_indicating_file_to_delete()
        {
            var client = NewAsyncClient();
            var rfs    = GetRavenFileSystem();

            client.UploadAsync("toDelete.bin", new MemoryStream(new byte[] { 1, 2, 3, 4, 5 })).Wait();

            rfs.StorageOperationsTask.IndicateFileToDelete("toDelete.bin");

            DeleteFileOperation deleteFile = null;

            rfs.Storage.Batch(accessor =>
                              deleteFile = accessor.GetConfigurationValue <DeleteFileOperation>(RavenFileNameHelper.DeleteOperationConfigNameForFile(RavenFileNameHelper.DeletingFileName("toDelete.bin"))));

            Assert.Equal(RavenFileNameHelper.DeletingFileName("toDelete.bin"), deleteFile.CurrentFileName);
            Assert.Equal("toDelete.bin", deleteFile.OriginalFileName);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var            jo       = JObject.Load(reader);
            var            taskType = (FileOperationType)(int)jo["operationType"];
            IFileOperation fileOperation;

            switch (taskType)
            {
            case FileOperationType.MoveFile:
                fileOperation = new MoveFileOperation();
                break;

            case FileOperationType.Update:
                fileOperation = new UpdateFileOperation();
                break;

            case FileOperationType.Delete:
                fileOperation = new DeleteFileOperation();
                break;

            case FileOperationType.Download:
                fileOperation = new DownloadFileOperation();
                break;

            case FileOperationType.DeltaPatch:
                fileOperation = new DeltaPatchOperation();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            using (JsonReader jObjectReader = CopyReaderForObject(reader, jo))
                serializer.Populate(jObjectReader, fileOperation);

            return(fileOperation);
        }
Example #10
0
        public void IndicateFileToDelete(string fileName)
        {
            var deletingFileName = RavenFileNameHelper.DeletingFileName(fileName);
            var fileExists       = true;

            storage.Batch(accessor =>
            {
                var existingFileHeader = accessor.ReadFile(fileName);

                if (existingFileHeader == null)
                {
                    // do nothing if file does not exist
                    fileExists = false;
                    return;
                }

                if (existingFileHeader.Metadata[SynchronizationConstants.RavenDeleteMarker] != null)
                {
                    // if it is a tombstone drop it
                    accessor.Delete(fileName);
                    fileExists = false;
                    return;
                }

                var metadata = new RavenJObject(existingFileHeader.Metadata).WithDeleteMarker();

                var renameSucceeded = false;

                int deleteVersion = 0;

                do
                {
                    try
                    {
                        accessor.RenameFile(fileName, deletingFileName);
                        renameSucceeded = true;
                    }
                    catch (FileExistsException)                     // it means that .deleting file was already existed
                    {
                        var deletingFileHeader = accessor.ReadFile(deletingFileName);

                        if (deletingFileHeader != null && deletingFileHeader.Equals(existingFileHeader))
                        {
                            fileExists = false;                             // the same file already marked as deleted no need to do it again
                            return;
                        }

                        // we need to use different name to do a file rename
                        deleteVersion++;
                        deletingFileName = RavenFileNameHelper.DeletingFileName(fileName, deleteVersion);
                    }
                } while (!renameSucceeded && deleteVersion < 128);

                if (renameSucceeded)
                {
                    accessor.UpdateFileMetadata(deletingFileName, metadata);
                    accessor.DecrementFileCount(deletingFileName);

                    Log.Debug(string.Format("File '{0}' was renamed to '{1}' and marked as deleted", fileName, deletingFileName));

                    var configName = RavenFileNameHelper.DeleteOperationConfigNameForFile(deletingFileName);
                    var operation  = new DeleteFileOperation {
                        OriginalFileName = fileName, CurrentFileName = deletingFileName
                    };
                    accessor.SetConfig(configName, JsonExtensions.ToJObject(operation));

                    notificationPublisher.Publish(new ConfigurationChangeNotification {
                        Name = configName, Action = ConfigurationChangeAction.Set
                    });
                }
                else
                {
                    Log.Warn("Could not rename a file '{0}' when a delete operation was performed", fileName);
                }
            });

            if (fileExists)
            {
                search.Delete(fileName);
                search.Delete(deletingFileName);
            }
        }
Example #11
0
        public void Retry()
        {
            if (savedEndpointOperation != null)
            {
                switch (Operation)
                {
                case PNOperationType.PNAccessManagerAudit:
                    if (savedEndpointOperation is AuditOperation)
                    {
                        AuditOperation endpoint = savedEndpointOperation as AuditOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNAccessManagerGrant:
                    if (savedEndpointOperation is GrantOperation)
                    {
                        GrantOperation endpoint = savedEndpointOperation as GrantOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNAddChannelsToGroupOperation:
                    if (savedEndpointOperation is AddChannelsToChannelGroupOperation)
                    {
                        AddChannelsToChannelGroupOperation endpoint = savedEndpointOperation as AddChannelsToChannelGroupOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNRemoveGroupOperation:
                    if (savedEndpointOperation is DeleteChannelGroupOperation)
                    {
                        DeleteChannelGroupOperation endpoint = savedEndpointOperation as DeleteChannelGroupOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.ChannelGroupAllGet:
                    if (savedEndpointOperation is ListAllChannelGroupOperation)
                    {
                        ListAllChannelGroupOperation endpoint = savedEndpointOperation as ListAllChannelGroupOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.ChannelGroupGet:
                    if (savedEndpointOperation is ListChannelsForChannelGroupOperation)
                    {
                        ListChannelsForChannelGroupOperation endpoint = savedEndpointOperation as ListChannelsForChannelGroupOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNRemoveChannelsFromGroupOperation:
                    if (savedEndpointOperation is RemoveChannelsFromChannelGroupOperation)
                    {
                        RemoveChannelsFromChannelGroupOperation endpoint = savedEndpointOperation as RemoveChannelsFromChannelGroupOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNGetStateOperation:
                    if (savedEndpointOperation is GetStateOperation)
                    {
                        GetStateOperation endpoint = savedEndpointOperation as GetStateOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNHereNowOperation:
                    if (savedEndpointOperation is HereNowOperation)
                    {
                        HereNowOperation endpoint = savedEndpointOperation as HereNowOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNSetStateOperation:
                    if (savedEndpointOperation is SetStateOperation)
                    {
                        SetStateOperation endpoint = savedEndpointOperation as SetStateOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNWhereNowOperation:
                    if (savedEndpointOperation is WhereNowOperation)
                    {
                        WhereNowOperation endpoint = savedEndpointOperation as WhereNowOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNFireOperation:
                    if (savedEndpointOperation is FireOperation)
                    {
                        FireOperation endpoint = savedEndpointOperation as FireOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNPublishOperation:
                    if (savedEndpointOperation is PublishOperation)
                    {
                        PublishOperation endpoint = savedEndpointOperation as PublishOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PushRegister:
                    if (savedEndpointOperation is AddPushChannelOperation)
                    {
                        AddPushChannelOperation endpoint = savedEndpointOperation as AddPushChannelOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PushGet:
                    if (savedEndpointOperation is AuditPushChannelOperation)
                    {
                        AuditPushChannelOperation endpoint = savedEndpointOperation as AuditPushChannelOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PushUnregister:
                    if (savedEndpointOperation is RemovePushChannelOperation)
                    {
                        RemovePushChannelOperation endpoint = savedEndpointOperation as RemovePushChannelOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNHistoryOperation:
                    if (savedEndpointOperation is HistoryOperation)
                    {
                        HistoryOperation endpoint = savedEndpointOperation as HistoryOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNFetchHistoryOperation:
                    if (savedEndpointOperation is FetchHistoryOperation)
                    {
                        FetchHistoryOperation endpoint = savedEndpointOperation as FetchHistoryOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNMessageCountsOperation:
                    if (savedEndpointOperation is MessageCountsOperation)
                    {
                        MessageCountsOperation endpoint = savedEndpointOperation as MessageCountsOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNTimeOperation:
                    if (savedEndpointOperation is TimeOperation)
                    {
                        TimeOperation endpoint = savedEndpointOperation as TimeOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNSetUuidMetadataOperation:
                    if (savedEndpointOperation is SetUuidMetadataOperation)
                    {
                        SetUuidMetadataOperation endpoint = savedEndpointOperation as SetUuidMetadataOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNSetChannelMetadataOperation:
                    if (savedEndpointOperation is SetChannelMetadataOperation)
                    {
                        SetChannelMetadataOperation endpoint = savedEndpointOperation as SetChannelMetadataOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNDeleteUuidMetadataOperation:
                    if (savedEndpointOperation is RemoveUuidMetadataOperation)
                    {
                        RemoveUuidMetadataOperation endpoint = savedEndpointOperation as RemoveUuidMetadataOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNDeleteChannelMetadataOperation:
                    if (savedEndpointOperation is RemoveChannelMetadataOperation)
                    {
                        RemoveChannelMetadataOperation endpoint = savedEndpointOperation as RemoveChannelMetadataOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNGetUuidMetadataOperation:
                    if (savedEndpointOperation is GetUuidMetadataOperation)
                    {
                        GetUuidMetadataOperation endpoint = savedEndpointOperation as GetUuidMetadataOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNGetChannelMetadataOperation:
                    if (savedEndpointOperation is GetChannelMetadataOperation)
                    {
                        GetChannelMetadataOperation endpoint = savedEndpointOperation as GetChannelMetadataOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNGetAllUuidMetadataOperation:
                    if (savedEndpointOperation is GetAllUuidMetadataOperation)
                    {
                        GetAllUuidMetadataOperation endpoint = savedEndpointOperation as GetAllUuidMetadataOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNGetAllChannelMetadataOperation:
                    if (savedEndpointOperation is GetAllChannelMetadataOperation)
                    {
                        GetAllChannelMetadataOperation endpoint = savedEndpointOperation as GetAllChannelMetadataOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNManageMembershipsOperation:
                    if (savedEndpointOperation is ManageMembershipsOperation)
                    {
                        ManageMembershipsOperation endpoint = savedEndpointOperation as ManageMembershipsOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNSetMembershipsOperation:
                    if (savedEndpointOperation is SetMembershipsOperation)
                    {
                        SetMembershipsOperation endpoint = savedEndpointOperation as SetMembershipsOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNRemoveMembershipsOperation:
                    if (savedEndpointOperation is RemoveMembershipsOperation)
                    {
                        RemoveMembershipsOperation endpoint = savedEndpointOperation as RemoveMembershipsOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNManageChannelMembersOperation:
                    if (savedEndpointOperation is ManageChannelMembersOperation)
                    {
                        ManageChannelMembersOperation endpoint = savedEndpointOperation as ManageChannelMembersOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNSetChannelMembersOperation:
                    if (savedEndpointOperation is SetChannelMembersOperation)
                    {
                        SetChannelMembersOperation endpoint = savedEndpointOperation as SetChannelMembersOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNRemoveChannelMembersOperation:
                    if (savedEndpointOperation is RemoveChannelMembersOperation)
                    {
                        RemoveChannelMembersOperation endpoint = savedEndpointOperation as RemoveChannelMembersOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNGetMembershipsOperation:
                    if (savedEndpointOperation is GetMembershipsOperation)
                    {
                        GetMembershipsOperation endpoint = savedEndpointOperation as GetMembershipsOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNGetChannelMembersOperation:
                    if (savedEndpointOperation is GetChannelMembersOperation)
                    {
                        GetChannelMembersOperation endpoint = savedEndpointOperation as GetChannelMembersOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNAddMessageActionOperation:
                    if (savedEndpointOperation is AddMessageActionOperation)
                    {
                        AddMessageActionOperation endpoint = savedEndpointOperation as AddMessageActionOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNRemoveMessageActionOperation:
                    if (savedEndpointOperation is RemoveMessageActionOperation)
                    {
                        RemoveMessageActionOperation endpoint = savedEndpointOperation as RemoveMessageActionOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNPublishFileMessageOperation:
                    if (savedEndpointOperation is PublishFileMessageOperation)
                    {
                        PublishFileMessageOperation endpoint = savedEndpointOperation as PublishFileMessageOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNFileUrlOperation:
                    if (savedEndpointOperation is GetFileUrlOperation)
                    {
                        GetFileUrlOperation endpoint = savedEndpointOperation as GetFileUrlOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNListFilesOperation:
                    if (savedEndpointOperation is ListFilesOperation)
                    {
                        ListFilesOperation endpoint = savedEndpointOperation as ListFilesOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNDeleteFileOperation:
                    if (savedEndpointOperation is DeleteFileOperation)
                    {
                        DeleteFileOperation endpoint = savedEndpointOperation as DeleteFileOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                case PNOperationType.PNDownloadFileOperation:
                    if (savedEndpointOperation is DownloadFileOperation)
                    {
                        DownloadFileOperation endpoint = savedEndpointOperation as DownloadFileOperation;
                        if (endpoint != null)
                        {
                            endpoint.Retry();
                        }
                    }
                    break;

                default:
                    break;
                }
            }
        }
Example #12
0
        public void IndicateFileToDelete(string fileName, Etag etag)
        {
            var deletingFileName = RavenFileNameHelper.DeletingFileName(fileName);
            var fileExists       = true;

            Storage.Batch(accessor =>
            {
                AssertDeleteOperationNotVetoed(fileName);

                var existingFile = accessor.ReadFile(fileName);

                if (existingFile == null)
                {
                    // do nothing if file does not exist
                    fileExists = false;
                    return;
                }

                if (existingFile.Metadata[SynchronizationConstants.RavenDeleteMarker] != null)
                {
                    // if it is a tombstone drop it
                    accessor.Delete(fileName);
                    fileExists = false;
                    return;
                }

                if (etag != null && existingFile.Etag != etag)
                {
                    throw new ConcurrencyException("Operation attempted on file '" + fileName + "' using a non current etag")
                    {
                        ActualETag   = existingFile.Etag,
                        ExpectedETag = etag
                    }
                }
                ;

                var metadata = new RavenJObject(existingFile.Metadata).WithDeleteMarker();

                var renameSucceeded = false;

                int deleteVersion = 0;

                do
                {
                    try
                    {
                        accessor.RenameFile(fileName, deletingFileName);
                        renameSucceeded = true;
                    }
                    catch (FileExistsException)                     // it means that .deleting file was already existed
                    {
                        var deletingFileHeader = accessor.ReadFile(deletingFileName);

                        if (deletingFileHeader != null && deletingFileHeader.Equals(existingFile))
                        {
                            fileExists = false;                             // the same file already marked as deleted no need to do it again
                            return;
                        }

                        // we need to use different name to do a file rename
                        deleteVersion++;
                        deletingFileName = RavenFileNameHelper.DeletingFileName(fileName, deleteVersion);
                    }
                } while (!renameSucceeded && deleteVersion < 128);

                if (renameSucceeded)
                {
                    accessor.UpdateFileMetadata(deletingFileName, metadata, null);
                    accessor.DecrementFileCount(deletingFileName);

                    Log.Debug("File '{0}' was renamed to '{1}' and marked as deleted", fileName, deletingFileName);

                    var configName = RavenFileNameHelper.DeleteOperationConfigNameForFile(deletingFileName);
                    var operation  = new DeleteFileOperation {
                        OriginalFileName = fileName, CurrentFileName = deletingFileName
                    };
                    accessor.SetConfig(configName, JsonExtensions.ToJObject(operation));

                    FileSystem.DeleteTriggers.Apply(trigger => trigger.AfterDelete(fileName));

                    Publisher.Publish(new ConfigurationChangeNotification {
                        Name = configName, Action = ConfigurationChangeAction.Set
                    });
                    Publisher.Publish(new FileChangeNotification {
                        File = fileName, Action = FileChangeAction.Delete
                    });

                    Log.Debug("File '{0}' was deleted", fileName);
                }
                else
                {
                    Log.Warn("Could not rename a file '{0}' when a delete operation was performed", fileName);
                }
            });

            if (fileExists)
            {
                Search.Delete(fileName);
                Search.Delete(deletingFileName);
            }
        }
        public void Clone(FileSystemSite source, FileSystemSite destination, FileSystemCloningOptions options)
        {
            // Ensure the source and destination directories are directory indicated.
            var ensuredSource      = source.EnsureSiteDirectoryPathIsDirectoryIndicated(this.StringlyTypedPathOperator);
            var ensuredDestination = destination.EnsureSiteDirectoryPathIsDirectoryIndicated(this.StringlyTypedPathOperator);

            // Get all source file-system entries.
            var sourceFileSystemEntries = ensuredSource.FileSystemOperator.EnumerateFileSystemEntries(ensuredSource.DirectoryPath, true)
                                          .ToList();

            // Get all destination file-system entries.
            var destinationFileSystemEntries = ensuredDestination.FileSystemOperator.EnumerateFileSystemEntries(ensuredDestination.DirectoryPath, true)
                                               .ToList();

            // Create relative-path source and destination file-system entries.
            FileSystemEntry MakeRelativeEntry(string baseDirectoryPath, FileSystemEntry entry)
            {
                var sourceBaseDirectoryRelativeEntryPath = this.StringlyTypedPathOperator.GetRelativePath(baseDirectoryPath, entry.Path);

                var relativeEntry = FileSystemEntry.New(sourceBaseDirectoryRelativeEntryPath, entry.Type, entry.LastModifiedUTC);

                return(relativeEntry);
            }

            var sourceBaseDirectoryRelativePathEntries = sourceFileSystemEntries.Select(entry => MakeRelativeEntry(ensuredSource.DirectoryPath, entry))
                                                         .Select(fileSystemEntry =>
            {
                // Make sure we are using a common path format.
                var standardPathFileSystemEntry = fileSystemEntry.GetStandardPathFormatEntry(this.StringlyTypedPathOperator);
                return(standardPathFileSystemEntry);
            })
                                                         .ToList();

            var destinationBaseDirectoryRelativePathEntries = destinationFileSystemEntries.Select(entry => MakeRelativeEntry(ensuredDestination.DirectoryPath, entry))
                                                              .Select(fileSystemEntry =>
            {
                // Make sure we are using a common path format.
                var standardPathFileSystemEntry = fileSystemEntry.GetStandardPathFormatEntry(this.StringlyTypedPathOperator);
                return(standardPathFileSystemEntry);
            })
                                                              .ToList();

            // Write out source and destination data.

            // Get the file-system cloning difference.
            var difference = this.FileSystemCloningDifferencer.PerformDifference(sourceBaseDirectoryRelativePathEntries, destinationBaseDirectoryRelativePathEntries, options);

            // Create a list of operations, using absolute paths.
            var operations = new List <IFileSystemCloningOperation>();

            // Special case: the destination directory does not exist. If so, make sure it is created first to allow files to be copied into it!
            var destinationDirectoryExists = ensuredDestination.FileSystemOperator.ExistsDirectory(ensuredDestination.DirectoryPath);

            if (!destinationDirectoryExists)
            {
                var createDestinationDirectoryOperation = new CreateDirectoryOperation(ensuredDestination.DirectoryPath);

                operations.Add(createDestinationDirectoryOperation);
            }

            foreach (var directoryToCreate in difference.RelativeDirectoryPathsToCreate)
            {
                string destinationDirectoryToCreate = this.StringlyTypedPathOperator.Combine(ensuredDestination.DirectoryPath, directoryToCreate);

                var createDirectoryOperation = new CreateDirectoryOperation(destinationDirectoryToCreate);

                operations.Add(createDirectoryOperation);
            }

            foreach (var directoryToDelete in difference.RelativeDirectoryPathsToDelete)
            {
                string destinationDirectoryToDelete = this.StringlyTypedPathOperator.Combine(ensuredDestination.DirectoryPath, directoryToDelete);

                var deleteDirectoryOperation = new DeleteDirectoryOperation(destinationDirectoryToDelete);

                operations.Add(deleteDirectoryOperation);
            }

            foreach (var fileToCopy in difference.RelativeFilePathsToCopy)
            {
                string sourceFilePath      = this.StringlyTypedPathOperator.Combine(ensuredSource.DirectoryPath, fileToCopy);
                string destinationFilePath = this.StringlyTypedPathOperator.Combine(ensuredDestination.DirectoryPath, fileToCopy);

                var copyFileOperation = new CopyFileOperation(sourceFilePath, destinationFilePath);

                operations.Add(copyFileOperation);
            }

            foreach (var fileToUpdate in difference.RelativeFilePathsToUpdate)
            {
                string sourceFilePath      = this.StringlyTypedPathOperator.Combine(ensuredSource.DirectoryPath, fileToUpdate);
                string destinationFilePath = this.StringlyTypedPathOperator.Combine(ensuredDestination.DirectoryPath, fileToUpdate);

                var copyFileOperation = new CopyFileOperation(sourceFilePath, destinationFilePath);

                operations.Add(copyFileOperation);
            }

            foreach (var fileToDelete in difference.RelativeFilePathsToDelete)
            {
                string destinationFilePath = this.StringlyTypedPathOperator.Combine(ensuredDestination.DirectoryPath, fileToDelete);

                var deleteFileOperation = new DeleteFileOperation(destinationFilePath);

                operations.Add(deleteFileOperation);
            }

            // Write out and allow approval of the list of operations?

            // Execute the list of operations.
            foreach (var operation in operations)
            {
                operation.Execute(ensuredSource.FileSystemOperator, ensuredDestination.FileSystemOperator);
            }
        }