Beispiel #1
0
        public HttpResponseMessage Post(string name)
        {
            if (name.StartsWith(CopyPrefix))
            {
                var targetFileName = GetQueryStringValue("targetFilename");
                return(Copy(name.Substring(CopyPrefix.Length), targetFileName));
            }

            name = FileHeader.Canonize(name);

            var metadata = GetFilteredMetadataFromHeaders(ReadInnerHeaders);
            var etag     = GetEtag();

            Storage.Batch(accessor =>
            {
                Synchronizations.AssertFileIsNotBeingSynced(name);

                Historian.Update(name, metadata);
                Files.UpdateMetadata(name, metadata, etag);

                SynchronizationTask.Context.NotifyAboutWork();
            });

            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
Beispiel #2
0
        public HttpResponseMessage Delete(string name)
        {
            name = FileHeader.Canonize(name);

            Storage.Batch(accessor =>
            {
                Synchronizations.AssertFileIsNotBeingSynced(name);

                var fileAndPages = accessor.GetFile(name, 0, 0);

                var metadata = fileAndPages.Metadata;

                if (metadata == null)
                {
                    throw new FileNotFoundException();
                }

                if (metadata.Keys.Contains(SynchronizationConstants.RavenDeleteMarker))
                {
                    throw new FileNotFoundException();
                }

                Files.IndicateFileToDelete(name, GetEtag());

                if (!name.EndsWith(RavenFileNameHelper.DownloadingFileSuffix)) // don't create a tombstone for .downloading file
                {
                    Files.PutTombstone(name, metadata);
                    accessor.DeleteConfig(RavenFileNameHelper.ConflictConfigNameForFile(name)); // delete conflict item too
                }
            });

            SynchronizationTask.Context.NotifyAboutWork();

            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
Beispiel #3
0
        public async Task <HttpResponseMessage> ApplyConflict(string filename, long remoteVersion, string remoteServerId, string remoteServerUrl)
        {
            var canonicalFilename = FileHeader.Canonize(filename);

            var localMetadata = Synchronizations.GetLocalMetadata(canonicalFilename);

            if (localMetadata == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            var contentStream = await Request.Content.ReadAsStreamAsync().ConfigureAwait(false);

            var current = new HistoryItem
            {
                ServerId = Storage.Id.ToString(),
                Version  = localMetadata.Value <long>(SynchronizationConstants.RavenSynchronizationVersion)
            };

            var currentConflictHistory = Historian.DeserializeHistory(localMetadata);

            currentConflictHistory.Add(current);

            var remote = new HistoryItem
            {
                ServerId = remoteServerId,
                Version  = remoteVersion
            };

            var remoteMetadata = RavenJObject.Load(new JsonTextReader(new StreamReader(contentStream)));

            var remoteConflictHistory = Historian.DeserializeHistory(remoteMetadata);

            remoteConflictHistory.Add(remote);

            var conflict = new ConflictItem
            {
                CurrentHistory  = currentConflictHistory,
                RemoteHistory   = remoteConflictHistory,
                FileName        = canonicalFilename,
                RemoteServerUrl = Uri.UnescapeDataString(remoteServerUrl)
            };

            ConflictArtifactManager.Create(canonicalFilename, conflict);

            Publisher.Publish(new ConflictNotification
            {
                FileName         = filename,
                SourceServerUrl  = remoteServerUrl,
                Status           = ConflictStatus.Detected,
                RemoteFileHeader = new FileHeader(canonicalFilename, remoteMetadata)
            });

            if (Log.IsDebugEnabled)
            {
                Log.Debug("Conflict applied for a file '{0}' (remote version: {1}, remote server id: {2}).", filename, remoteVersion, remoteServerId);
            }

            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
Beispiel #4
0
        public async Task <HttpResponseMessage> Put(string name, bool preserveTimestamps = false)
        {
            var metadata = GetFilteredMetadataFromHeaders(ReadInnerHeaders);
            var etag     = GetEtag();

            var options = new FileActions.PutOperationOptions();

            long contentSize;

            if (long.TryParse(GetHeader(Constants.FileSystem.RavenFsSize), out contentSize))
            {
                options.ContentSize = contentSize;
            }

            DateTimeOffset lastModified;

            if (DateTimeOffset.TryParse(GetHeader(Constants.RavenLastModified), out lastModified))
            {
                options.LastModified = lastModified;
            }

            options.PreserveTimestamps      = preserveTimestamps;
            options.ContentLength           = Request.Content.Headers.ContentLength;
            options.TransferEncodingChunked = Request.Headers.TransferEncodingChunked ?? false;

            await FileSystem.Files.PutAsync(name, etag, metadata, () => Request.Content.ReadAsStreamAsync(), options);

            Synchronizations.StartSynchronizeDestinationsInBackground();

            return(GetEmptyMessage(HttpStatusCode.Created));
        }
Beispiel #5
0
        public HttpResponseMessage LastSynchronization(Guid from)
        {
            SourceSynchronizationInformation lastEtag = Synchronizations.GetLastSynchronization(from);

            Log.Debug("Got synchronization last ETag request from {0}: [{1}]", from, lastEtag);

            return(GetMessageWithObject(lastEtag)
                   .WithNoCache());
        }
Beispiel #6
0
        public HttpResponseMessage Status(string fileName)
        {
            fileName = FileHeader.Canonize(fileName);

            var report = Synchronizations.GetSynchronizationReport(fileName);

            return(GetMessageWithObject(report)
                   .WithNoCache());
        }
Beispiel #7
0
        private FileStatus CheckSynchronizedFileStatus(string filename, Etag etag)
        {
            var report = Synchronizations.GetSynchronizationReport(filename);

            if (report == null || report.FileETag != etag)
            {
                return(FileStatus.Unknown);
            }

            return(report.Exception == null ? FileStatus.Safe : FileStatus.Broken);
        }
Beispiel #8
0
        public HttpResponseMessage Post(string name)
        {
            name = FileHeader.Canonize(name);

            var metadata = GetFilteredMetadataFromHeaders(ReadInnerHeaders);
            var etag     = GetEtag();

            Storage.Batch(accessor =>
            {
                Synchronizations.AssertFileIsNotBeingSynced(name);

                Historian.Update(name, metadata);
                Files.UpdateMetadata(name, metadata, etag);

                SynchronizationTask.Context.NotifyAboutWork();
            });

            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
Beispiel #9
0
        public HttpResponseMessage Post(string name)
        {
            name = FileHeader.Canonize(name);

            var metadata = GetFilteredMetadataFromHeaders(ReadInnerHeaders);
            var etag     = GetEtag();

            Storage.Batch(accessor =>
            {
                Synchronizations.AssertFileIsNotBeingSynced(name);

                Historian.Update(name, metadata);
                Files.UpdateMetadata(name, metadata, etag);

                Synchronizations.StartSynchronizeDestinationsInBackground();
            });

            //Hack needed by jquery on the client side. We need to find a better solution for this
            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
Beispiel #10
0
        public async Task <HttpResponseMessage> ResolutionStrategyFromServerResolvers()
        {
            var conflict = await ReadJsonObjectAsync <ConflictItem>();

            var localMetadata = Synchronizations.GetLocalMetadata(conflict.FileName);

            if (localMetadata == null)
            {
                throw new InvalidOperationException(string.Format("Could not find the medatada of the file: {0}", conflict.FileName));
            }

            var sourceMetadata = GetFilteredMetadataFromHeaders(ReadInnerHeaders);

            ConflictResolutionStrategy strategy;

            if (ConflictResolver.TryResolveConflict(conflict.FileName, conflict, localMetadata, sourceMetadata, out strategy))
            {
                return(GetMessageWithObject(strategy));
            }

            return(GetMessageWithObject(ConflictResolutionStrategy.NoResolution));
        }
Beispiel #11
0
        private void DeleteFiles(IEnumerable <string> keys, int totalResults, Action <string> progress)
        {
            Storage.Batch(accessor =>
            {
                var files = keys.Select(accessor.ReadFile);
                foreach (var fileWithIndex in files.Select((value, i) => new { i, value }))
                {
                    var file     = fileWithIndex.value;
                    var fileName = file.FullPath;
                    try
                    {
                        Synchronizations.AssertFileIsNotBeingSynced(fileName);
                    }
                    catch (Exception)
                    {
                        //ignore files that are being synced
                        continue;
                    }

                    var metadata = file.Metadata;
                    if (metadata == null || metadata.Keys.Contains(SynchronizationConstants.RavenDeleteMarker))
                    {
                        continue;
                    }

                    Historian.Update(fileName, metadata);
                    Files.IndicateFileToDelete(fileName, null);

                    // don't create a tombstone for .downloading file
                    if (!fileName.EndsWith(RavenFileNameHelper.DownloadingFileSuffix))
                    {
                        Files.PutTombstone(fileName, metadata);
                        accessor.DeleteConfig(RavenFileNameHelper.ConflictConfigNameForFile(fileName)); // delete conflict item too
                    }

                    progress(string.Format("File {0}/{1} was deleted, name: '{2}'.", fileWithIndex.i, totalResults, fileName));
                }
            });
        }
Beispiel #12
0
        public HttpResponseMessage IncrementLastETag(Guid sourceServerId, string sourceFileSystemUrl, string sourceFileETag)
        {
            Synchronizations.IncrementLastEtag(sourceServerId, sourceFileSystemUrl, sourceFileETag);

            return(GetEmptyMessage());
        }