public void RenameFile(RenameFileOperation operation) { var configName = RavenFileNameHelper.RenameOperationConfigNameForFile(operation.Name); notificationPublisher.Publish(new FileChange { File = FilePathTools.Cannoicalise(operation.Name), Action = FileChangeAction.Renaming }); storage.Batch(accessor => { var previousRenameTombstone = accessor.ReadFile(operation.Rename); if (previousRenameTombstone != null && previousRenameTombstone.Metadata[SynchronizationConstants.RavenDeleteMarker] != null) { // if there is a tombstone delete it accessor.Delete(previousRenameTombstone.Name); } accessor.RenameFile(operation.Name, operation.Rename, true); accessor.UpdateFileMetadata(operation.Rename, operation.MetadataAfterOperation); // copy renaming file metadata and set special markers var tombstoneMetadata = new NameValueCollection(operation.MetadataAfterOperation).WithRenameMarkers(operation.Rename); accessor.PutFile(operation.Name, 0, tombstoneMetadata, true); // put rename tombstone accessor.DeleteConfig(configName); search.Delete(operation.Name); search.Index(operation.Rename, operation.MetadataAfterOperation); }); notificationPublisher.Publish(new ConfigChange { Name = configName, Action = ConfigChangeAction.Set }); notificationPublisher.Publish(new FileChange { File = FilePathTools.Cannoicalise(operation.Rename), Action = FileChangeAction.Renamed }); }
public HttpResponseMessage Patch(string name, string rename) { name = RavenFileNameHelper.RavenPath(name); rename = RavenFileNameHelper.RavenPath(rename); try { ConcurrencyAwareExecutor.Execute(() => Storage.Batch(accessor => { AssertFileIsNotBeingSynced(name, accessor, true); var metadata = accessor.GetFile(name, 0, 0).Metadata; if (metadata.Keys.Contains(SynchronizationConstants.RavenDeleteMarker)) { throw new FileNotFoundException(); } var existingHeader = accessor.ReadFile(rename); if (existingHeader != null && !existingHeader.Metadata.ContainsKey(SynchronizationConstants.RavenDeleteMarker)) { throw new HttpResponseException( Request.CreateResponse(HttpStatusCode.Forbidden, new InvalidOperationException("Cannot rename because file " + rename + " already exists"))); } Historian.UpdateLastModified(metadata); var operation = new RenameFileOperation { Name = name, Rename = rename, MetadataAfterOperation = metadata }; accessor.SetConfig(RavenFileNameHelper.RenameOperationConfigNameForFile(name), JsonExtensions.ToJObject(operation)); accessor.PulseTransaction(); // commit rename operation config StorageOperationsTask.RenameFile(operation); }), ConcurrencyResponseException); } catch (FileNotFoundException) { log.Debug("Cannot rename a file '{0}' to '{1}' because a file was not found", name, rename); return GetEmptyMessage(HttpStatusCode.NotFound); } log.Debug("File '{0}' was renamed to '{1}'", name, rename); StartSynchronizeDestinationsInBackground(); return GetMessageWithString("", HttpStatusCode.NoContent); }
public async Task Should_resume_file_renaming_from_client() { var client = NewAsyncClient(); var rfs = GetRavenFileSystem(); string fileName = FileHeader.Canonize("file.bin"); string rename = FileHeader.Canonize("renamed.bin"); await client.UploadAsync(fileName, new RandomStream(1)); // create config to say to the server that rename operation performed last time were not finished var renameOpConfig = RavenFileNameHelper.RenameOperationConfigNameForFile(fileName); var renameOperation = new RenameFileOperation { Name = fileName, Rename = rename, MetadataAfterOperation = new RavenJObject().WithETag(Guid.Empty) }; rfs.Storage.Batch(accessor => accessor.SetConfigurationValue(renameOpConfig, renameOperation )); await client.Storage.RetryRenamingAsync(); IEnumerable<string> configNames = await client.Configuration.GetKeyNamesAsync(); Assert.DoesNotContain(renameOpConfig, configNames); var renamedMetadata = await client.GetMetadataForAsync(rename); Assert.NotNull(renamedMetadata); }
public void Should_resume_to_rename_file_if_appropriate_config_exists() { var client = NewAsyncClient(); var rfs = GetRavenFileSystem(); string fileName = FileHeader.Canonize("file.bin"); string rename = FileHeader.Canonize("renamed.bin"); client.UploadAsync(fileName, new RandomStream(1)).Wait(); // create config to say to the server that rename operation performed last time were not finished var renameOpConfig = RavenFileNameHelper.RenameOperationConfigNameForFile(fileName); var renameOperation = new RenameFileOperation { Name = fileName, Rename = rename, MetadataAfterOperation = new RavenJObject().WithETag(Guid.Empty) }; rfs.Storage.Batch(accessor => accessor.SetConfigurationValue(renameOpConfig, renameOperation)); rfs.StorageOperationsTask.ResumeFileRenamingAsync().Wait(); IEnumerable<string> configNames = null; rfs.Storage.Batch(accessor => configNames = accessor.GetConfigNames(0, 10).ToArray()); Assert.DoesNotContain(renameOpConfig, configNames); var renamedMetadata = client.GetMetadataForAsync(rename).Result; Assert.NotNull(renamedMetadata); var results = client.SearchOnDirectoryAsync("/").Result; // make sure that indexes are updated Assert.Equal(1, results.FileCount); Assert.Equal(rename, results.Files[0].FullPath); }