public void UpdateMetadata(string name, RavenJObject metadata, Etag etag) { FileUpdateResult updateMetadata = null; Storage.Batch(accessor => { AssertMetadataUpdateOperationNotVetoed(name, metadata); Historian.UpdateLastModified(metadata); FileSystem.MetadataUpdateTriggers.Apply(trigger => trigger.OnUpdate(name, metadata)); updateMetadata = accessor.UpdateFileMetadata(name, metadata, etag); FileSystem.MetadataUpdateTriggers.Apply(trigger => trigger.AfterUpdate(name, metadata)); }); Search.Index(name, metadata, updateMetadata.Etag); FileSystem.Publisher.Publish(new FileChangeNotification { File = name, Action = FileChangeAction.Update }); Log.Debug("Metadata of a file '{0}' was updated", name); }
private async Task <FileUpdateResult> UpdateFile(Domain.Models.File dbFile, Domain.Models.File file) { var result = new FileUpdateResult(); result.LockResult = await _lockService.GetFileLock(dbFile.Id).LockAsync(0); // Don't need to update or throw error if contents haven't changed if (!dbFile.Content.Equals(file.Content)) { if (!result.LockResult.AcquiredLock) { result.UnableToLock = true; result.FileUpdated = false; } else if (dbFile.CanLock(_userId, _isAdmin)) { dbFile.Content = file.Content; dbFile.Save( _userId, _isAdmin, bypassLock: true); result.FileUpdated = true; result.UnableToLock = false; } else { result.FileUpdated = false; result.UnableToLock = true; } } return(result); }
public void Delete(string fileName, IStorageActionsAccessor actionsAccessor = null) { RavenJObject metadata = null; FileUpdateResult updateResult = null; Action <IStorageActionsAccessor> delete = accessor => { accessor.DeleteConfig(RavenFileNameHelper.ConflictConfigNameForFile(fileName)); metadata = accessor.GetFile(fileName, 0, 0).Metadata; metadata.Remove(SynchronizationConstants.RavenSynchronizationConflict); metadata.Remove(SynchronizationConstants.RavenSynchronizationConflictResolution); updateResult = accessor.UpdateFileMetadata(fileName, metadata, null); }; if (actionsAccessor != null) { delete(actionsAccessor); } else { storage.Batch(delete); } if (metadata != null) { index.Index(fileName, metadata, updateResult.Etag); } }
public void Create(string fileName, ConflictItem conflict) { RavenJObject metadata = null; FileUpdateResult updateMetadata = null; storage.Batch( accessor => { metadata = accessor.GetFile(fileName, 0, 0).Metadata; accessor.SetConfig(RavenFileNameHelper.ConflictConfigNameForFile(fileName), JsonExtensions.ToJObject(conflict)); metadata[SynchronizationConstants.RavenSynchronizationConflict] = true; updateMetadata = accessor.UpdateFileMetadata(fileName, metadata, null); }); if (metadata != null) { index.Index(fileName, metadata, updateMetadata.Etag); } }
public FileUpdateResult PutFile(string filename, long?totalSize, RavenJObject metadata, bool tombstone = false) { FileUpdateResult result; using (var update = new Update(session, Files, JET_prep.Insert)) { Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["name"], filename, Encoding.Unicode); if (totalSize != null) { Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["total_size"], BitConverter.GetBytes(totalSize.Value)); } Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["uploaded_size"], BitConverter.GetBytes(0)); metadata.Remove(Constants.MetadataEtagField); var newEtag = uuidGenerator.CreateSequentialUuid(); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["etag"], newEtag.TransformToValueForEsentSorting()); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["metadata"], ToQueryString(metadata), Encoding.Unicode); update.Save(); result = new FileUpdateResult { PrevEtag = null, Etag = newEtag }; } if (!tombstone) { if (Api.TryMoveFirst(session, Details) == false) { throw new InvalidOperationException("Could not find system metadata row"); } Api.EscrowUpdate(session, Details, tableColumnsCache.DetailsColumns["file_count"], 1); } return(result); }
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 PutAsync(string name, Etag etag, RavenJObject metadata, Func <Task <Stream> > streamAsync, PutOperationOptions options) { FileUpdateResult putResult = null; try { FileSystem.MetricsCounters.FilesPerSecond.Mark(); name = FileHeader.Canonize(name); if (options.PreserveTimestamps) { if (!metadata.ContainsKey(Constants.RavenCreationDate)) { if (metadata.ContainsKey(Constants.CreationDate)) { metadata[Constants.RavenCreationDate] = metadata[Constants.CreationDate]; } else { throw new InvalidOperationException("Preserve Timestamps requires that the client includes the Raven-Creation-Date header."); } } Historian.UpdateLastModified(metadata, options.LastModified.HasValue ? options.LastModified.Value : DateTimeOffset.UtcNow); } else { metadata[Constants.RavenCreationDate] = DateTimeOffset.UtcNow; Historian.UpdateLastModified(metadata); } // TODO: To keep current filesystems working. We should remove when adding a new migration. metadata[Constants.CreationDate] = metadata[Constants.RavenCreationDate].Value <DateTimeOffset>().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ", CultureInfo.InvariantCulture); Historian.Update(name, metadata); long?size = -1; Storage.Batch(accessor => { FileSystem.Synchronizations.AssertFileIsNotBeingSynced(name); AssertPutOperationNotVetoed(name, metadata); SynchronizationTask.Cancel(name); var contentLength = options.ContentLength; var contentSize = options.ContentSize; if (contentLength == 0 || contentSize.HasValue == false) { size = contentLength; if (options.TransferEncodingChunked) { size = null; } } else { size = contentSize; } FileSystem.PutTriggers.Apply(trigger => trigger.OnPut(name, metadata)); using (FileSystem.DisableAllTriggersForCurrentThread()) { IndicateFileToDelete(name, etag); } putResult = accessor.PutFile(name, size, metadata); FileSystem.PutTriggers.Apply(trigger => trigger.AfterPut(name, size, metadata)); Search.Index(name, metadata, putResult.Etag); }); Log.Debug("Inserted a new file '{0}' with ETag {1}", name, putResult.Etag); using (var contentStream = await streamAsync().ConfigureAwait(false)) using (var readFileToDatabase = new ReadFileToDatabase(BufferPool, Storage, FileSystem.PutTriggers, contentStream, name, metadata)) { await readFileToDatabase.Execute().ConfigureAwait(false); if (size != null && readFileToDatabase.TotalSizeRead != size) { throw new HttpResponseException(HttpStatusCode.BadRequest); } if (options.PreserveTimestamps == false) { Historian.UpdateLastModified(metadata); // update with the final file size. } Log.Debug("File '{0}' was uploaded. Starting to update file metadata and indexes", name); metadata["Content-MD5"] = readFileToDatabase.FileHash; FileUpdateResult updateMetadata = null; Storage.Batch(accessor => updateMetadata = accessor.UpdateFileMetadata(name, metadata, null)); long totalSizeRead = readFileToDatabase.TotalSizeRead; metadata["Content-Length"] = totalSizeRead.ToString(CultureInfo.InvariantCulture); Search.Index(name, metadata, updateMetadata.Etag); Publisher.Publish(new FileChangeNotification { Action = FileChangeAction.Add, File = name }); Log.Debug("Updates of '{0}' metadata and indexes were finished. New file ETag is {1}", name, updateMetadata.Etag); } } catch (Exception ex) { if (putResult != null) { using (FileSystem.DisableAllTriggersForCurrentThread()) { IndicateFileToDelete(name, null); } } Log.WarnException(string.Format("Failed to upload a file '{0}'", name), ex); throw; } }
public FileUpdateResult PutFile(string filename, long? totalSize, RavenJObject metadata, bool tombstone = false) { FileUpdateResult result; using (var update = new Update(session, Files, JET_prep.Insert)) { Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["name"], filename, Encoding.Unicode); if (totalSize != null) Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["total_size"], BitConverter.GetBytes(totalSize.Value)); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["uploaded_size"], BitConverter.GetBytes(0)); metadata.Remove(Constants.MetadataEtagField); var newEtag = uuidGenerator.CreateSequentialUuid(); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["etag"], newEtag.TransformToValueForEsentSorting()); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["metadata"], ToQueryString(metadata), Encoding.Unicode); update.Save(); result = new FileUpdateResult { PrevEtag = null, Etag = newEtag }; } if (!tombstone) { if (Api.TryMoveFirst(session, Details) == false) throw new InvalidOperationException("Could not find system metadata row"); Api.EscrowUpdate(session, Details, tableColumnsCache.DetailsColumns["file_count"], 1); } return result; }