Example #1
0
        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;
            }
        }
Example #2
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;
            }
        }