Пример #1
0
        public void UpdateMetadata(string name, RavenJObject metadata, Etag etag)
        {
            MetadataUpdateResult 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);
        }
Пример #2
0
        public void Delete(string fileName, IStorageActionsAccessor actionsAccessor = null)
        {
            RavenJObject         metadata     = null;
            MetadataUpdateResult 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);
            }
        }
Пример #3
0
        public void Create(string fileName, ConflictItem conflict)
        {
            RavenJObject         metadata       = null;
            MetadataUpdateResult 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);
            }
        }
Пример #4
0
        public MetadataUpdateResult PutFile(string filename, long?totalSize, RavenJObject metadata, bool tombstone = false)
        {
            MetadataUpdateResult 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 MetadataUpdateResult
                {
                    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);
        }
Пример #5
0
        public async Task PutAsync(string name, Etag etag, RavenJObject metadata, Func <Task <Stream> > streamAsync, PutOperationOptions options)
        {
            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);
                    }

                    var 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, metadata.Value <string>(Constants.MetadataEtagField));

                using (var contentStream = await streamAsync())
                    using (var readFileToDatabase = new ReadFileToDatabase(BufferPool, Storage, FileSystem.PutTriggers, contentStream, name, metadata))
                    {
                        await readFileToDatabase.Execute();

                        if (readFileToDatabase.TotalSizeRead != size)
                        {
                            using (FileSystem.DisableAllTriggersForCurrentThread())
                            {
                                IndicateFileToDelete(name, null);
                            }
                            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;

                        MetadataUpdateResult updateMetadata = null;
                        Storage.Batch(accessor => updateMetadata = accessor.UpdateFileMetadata(name, metadata, null));

                        int 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, metadata.Value <string>(Constants.MetadataEtagField));
                    }
            }
            catch (Exception ex)
            {
                Log.WarnException(string.Format("Failed to upload a file '{0}'", name), ex);

                throw;
            }
        }
Пример #6
0
        public MetadataUpdateResult PutFile(string filename, long? totalSize, RavenJObject metadata, bool tombstone = false)
        {
	        MetadataUpdateResult 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 MetadataUpdateResult
				{
					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;
        }
Пример #7
0
        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, metadata));

                fs.Historian.UpdateLastModified(metadata);

                var synchronizingFile = SynchronizingFileStream.CreatingOrOpeningAndWriting(fs, tempFileName, metadata);

                fs.PutTriggers.Apply(trigger => trigger.AfterPut(tempFileName, null, metadata));

                var provider = new MultipartSyncStreamProvider(synchronizingFile, localFile);

                Log.Debug("Starting to process/read multipart content of a file '{0}'", fileName);

                await MultipartContent.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();
                metadata["Content-MD5"] = synchronizingFile.FileHash;

                MetadataUpdateResult updateResult = null;
                fs.Storage.Batch(accessor => updateResult = accessor.UpdateFileMetadata(tempFileName, metadata, 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, metadata, updateResult.Etag);
                });

                if (localFile == null)
                {
                    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);
                }

                fs.Publisher.Publish(new FileChangeNotification {
                    File = fileName, Action = localFile == null ? FileChangeAction.Add : FileChangeAction.Update
                });
            }
        }