public async Task ReceiveAsync(MediaMoverContext context, MediaFile mediaFile, Stream stream)
        {
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(mediaFile, nameof(mediaFile));

            // store data into file
            if (stream != null && stream.Length > 0)
            {
                var filePath = GetPath(mediaFile);

                if (!_fileSystem.FileExists(filePath))
                {
                    // TBD: (mc) We only save the file if it doesn't exist yet.
                    // This should save time and bandwidth in the case where the target
                    // is a cloud based file system (like Azure BLOB).
                    // In such a scenario it'd be advisable to copy the files manually
                    // with other - maybe more performant - tools before performing the provider switch.

                    // Create folder if it does not exist yet
                    var dir = Path.GetDirectoryName(filePath);
                    if (!_fileSystem.FolderExists(dir))
                    {
                        _fileSystem.CreateFolder(dir);
                    }

                    using (stream)
                    {
                        await _fileSystem.SaveStreamAsync(filePath, stream);
                    }

                    context.AffectedFiles.Add(filePath);
                }
            }
        }
Exemple #2
0
        public void MoveTo(ISupportsMediaMoving target, MediaMoverContext context, MediaFile mediaFile)
        {
            Guard.NotNull(target, nameof(target));
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(mediaFile, nameof(mediaFile));

            if (mediaFile.MediaStorageId != null)
            {
                // Let target store data (into a file for example)
                target.Receive(context, mediaFile, OpenRead(mediaFile));

                // Remove picture binary from DB
                try
                {
                    _mediaStorageRepo.Delete(mediaFile.MediaStorageId.Value);
                    //mediaFile.MediaStorageId = null;
                    //mediaFile.MediaStorage = null;

                    _mediaFileRepo.Update(mediaFile);
                }
                catch { }

                context.ShrinkDatabase = true;
            }
        }
Exemple #3
0
        public async Task ReceiveAsync(MediaMoverContext context, MediaFile mediaFile, Stream stream)
        {
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(mediaFile, nameof(mediaFile));

            // Store data for later bulk commit
            if (stream != null && stream.Length > 0)
            {
                // Requires AutoDetectChanges set to true or remove explicit entity detaching
                await SaveAsync(mediaFile, stream);
            }
        }
Exemple #4
0
        public void Receive(MediaMoverContext context, MediaFile mediaFile, Stream stream)
        {
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(mediaFile, nameof(mediaFile));

            // Store data for later bulk commit
            if (stream != null && stream.Length > 0)
            {
                // Requires AutoDetectChanges set to true or remove explicit entity detaching
                Save(mediaFile, MediaStorageItem.FromStream(stream));
            }
        }
        public void Receive(MediaMoverContext context, MediaItem media, byte[] data)
        {
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(media, nameof(media));

            // store data for later bulk commit
            if (data != null && data.LongLength > 0)
            {
                // requires autoDetectChanges set to true or remove explicit entity detaching
                media.Entity.MediaStorage = new MediaStorage {
                    Data = data
                };
            }
        }
Exemple #6
0
        public async Task ReceiveAsync(MediaMoverContext context, MediaItem media, byte[] data)
        {
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(media, nameof(media));

            // store data into file
            if (data != null && data.LongLength != 0)
            {
                var filePath = GetPicturePath(media);

                await _fileSystem.WriteAllBytesAsync(filePath, data);

                context.AffectedFiles.Add(filePath);
            }
        }
        public void MoveTo(ISupportsMediaMoving target, MediaMoverContext context, MediaFile mediaFile)
        {
            Guard.NotNull(target, nameof(target));
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(mediaFile, nameof(mediaFile));

            var filePath = GetPath(mediaFile);

            try
            {
                // Let target store data (into database for example)
                target.Receive(context, mediaFile, OpenRead(mediaFile));

                // Remember file path: we must be able to rollback IO operations on transaction failure
                context.AffectedFiles.Add(filePath);
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception.Message);
            }
        }
        public void OnCompleted(MediaMoverContext context, bool succeeded)
        {
            if (context.AffectedFiles.Any())
            {
                var toFileSystem = context.TargetSystemName.IsCaseInsensitiveEqual(SystemName);

                if ((!toFileSystem && succeeded) || (toFileSystem && !succeeded))
                {
                    // FS > DB sucessful OR DB > FS failed: delete all physical files
                    // run a background task for the deletion of files (fire & forget)

                    Task.Factory.StartNew(state =>
                    {
                        var files = state as string[];
                        foreach (var file in files)
                        {
                            _fileSystem.DeleteFile(file);
                        }
                    }, context.AffectedFiles.ToArray()).ConfigureAwait(false);
                }
            }
        }
Exemple #9
0
        public void Receive(MediaMoverContext context, MediaItem media, byte[] data)
        {
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(media, nameof(media));

            // store data into file
            if (data != null && data.LongLength != 0)
            {
                var filePath = GetPicturePath(media);

                if (!_fileSystem.FileExists(filePath))
                {
                    // TBD: (mc) We only save the file if it doesn't exist yet.
                    // This should save time and bandwidth in the case where the target
                    // is a cloud based file system (like Azure BLOB).
                    // In such a scenario it'd be advisable to copy the files manually
                    // with other - maybe more performant - tools before performing the provider switch.
                    _fileSystem.WriteAllBytes(filePath, data);
                    context.AffectedFiles.Add(filePath);
                }
            }
        }
        public void MoveTo(ISupportsMediaMoving target, MediaMoverContext context, MediaItem media)
        {
            Guard.NotNull(target, nameof(target));
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(media, nameof(media));

            if (media.Entity.MediaStorage != null)
            {
                // let target store data (into a file for example)
                target.Receive(context, media, media.Entity.MediaStorage.Data);

                // remove picture binary from DB
                try
                {
                    _mediaStorageRepository.Delete(media.Entity.MediaStorage);
                }
                catch { }

                media.Entity.MediaStorageId = null;

                context.ShrinkDatabase = true;
            }
        }
Exemple #11
0
        public void MoveTo(ISupportsMediaMoving target, MediaMoverContext context, MediaItem media)
        {
            Guard.NotNull(target, nameof(target));
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(media, nameof(media));

            var filePath = GetPicturePath(media);

            try
            {
                // read data from file
                var data = _fileSystem.ReadAllBytes(filePath);

                // let target store data (into database for example)
                target.Receive(context, media, data);

                // remember file path: we must be able to rollback IO operations on transaction failure
                context.AffectedFiles.Add(filePath);
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception.Message);
            }
        }
Exemple #12
0
        public virtual bool Move(Provider <IMediaStorageProvider> sourceProvider, Provider <IMediaStorageProvider> targetProvider)
        {
            Guard.NotNull(sourceProvider, nameof(sourceProvider));
            Guard.NotNull(targetProvider, nameof(targetProvider));

            var success = false;
            var utcNow  = DateTime.UtcNow;
            var context = new MediaMoverContext(sourceProvider.Metadata.SystemName, targetProvider.Metadata.SystemName);

            var source = sourceProvider.Value as ISupportsMediaMoving;
            var target = targetProvider.Value as ISupportsMediaMoving;

            // Source and target must support media storage moving
            if (source == null)
            {
                throw new ArgumentException(T("Admin.Media.StorageMovingNotSupported", sourceProvider.Metadata.SystemName));
            }

            if (target == null)
            {
                throw new ArgumentException(T("Admin.Media.StorageMovingNotSupported", targetProvider.Metadata.SystemName));
            }

            // Source and target provider must not be equal
            if (sourceProvider.Metadata.SystemName.IsCaseInsensitiveEqual(targetProvider.Metadata.SystemName))
            {
                throw new ArgumentException(T("Admin.Media.CannotMoveToSameProvider"));
            }

            // We are about to process data in chunks but want to commit ALL at once after ALL chunks have been processed successfully.
            // AutoDetectChanges true required for newly inserted binary data.
            using (var scope = new DbContextScope(ctx: _services.DbContext,
                                                  autoDetectChanges: true,
                                                  proxyCreation: false,
                                                  validateOnSave: false,
                                                  autoCommit: false))
            {
                using (var transaction = scope.DbContext.BeginTransaction())
                {
                    try
                    {
                        var pager = new FastPager <MediaFile>(_mediaFileRepo.Table, PAGE_SIZE);
                        while (pager.ReadNextPage(out var files))
                        {
                            foreach (var file in files)
                            {
                                // Move item from source to target
                                source.MoveTo(target, context, file);

                                file.UpdatedOnUtc = utcNow;
                                ++context.MovedItems;
                            }

                            scope.DbContext.SaveChanges();

                            // Detach all entities from previous page to save memory
                            scope.DbContext.DetachEntities(files, deep: true);
                        }

                        transaction.Commit();
                        success = true;
                    }
                    catch (Exception exception)
                    {
                        success = false;
                        transaction.Rollback();

                        _services.Notifier.Error(exception);
                        _logger.Error(exception);
                    }
                }
            }


            if (success)
            {
                _services.Settings.SetSetting("Media.Storage.Provider", targetProvider.Metadata.SystemName);
            }

            // inform both provider about ending
            source.OnCompleted(context, success);
            target.OnCompleted(context, success);

            if (success && context.ShrinkDatabase)
            {
                _services.DbContext.ShrinkDatabase();
            }

            return(success);
        }
Exemple #13
0
        public virtual bool Move(Provider <IMediaStorageProvider> sourceProvider, Provider <IMediaStorageProvider> targetProvider)
        {
            Guard.NotNull(sourceProvider, nameof(sourceProvider));
            Guard.NotNull(targetProvider, nameof(targetProvider));

            var success = false;
            var utcNow  = DateTime.UtcNow;
            var context = new MediaMoverContext(sourceProvider.Metadata.SystemName, targetProvider.Metadata.SystemName);

            var source = sourceProvider.Value as ISupportsMediaMoving;
            var target = targetProvider.Value as ISupportsMediaMoving;

            // source and target must support media storage moving
            if (source == null)
            {
                throw new ArgumentException(T("Admin.Media.StorageMovingNotSupported", sourceProvider.Metadata.SystemName));
            }

            if (target == null)
            {
                throw new ArgumentException(T("Admin.Media.StorageMovingNotSupported", targetProvider.Metadata.SystemName));
            }

            // source and target provider must not be equal
            if (sourceProvider.Metadata.SystemName.IsCaseInsensitiveEqual(targetProvider.Metadata.SystemName))
            {
                throw new ArgumentException(T("Admin.Media.CannotMoveToSameProvider"));
            }

            // we are about to process data in chunks but want to commit ALL at once when ALL chunks have been processed successfully.
            // autoDetectChanges true required for newly inserted binary data.
            using (var scope = new DbContextScope(ctx: _services.DbContext,
                                                  autoDetectChanges: true,
                                                  proxyCreation: false,
                                                  validateOnSave: false,
                                                  autoCommit: false))
            {
                using (var transaction = _services.DbContext.BeginTransaction())
                {
                    try
                    {
                        // Files
                        var queryFiles = _pictureRepository.Table
                                         .Expand(x => x.MediaStorage)
                                         .OrderBy(x => x.Id);

                        PageEntities(queryFiles, picture =>
                        {
                            // move item from source to target
                            source.MoveTo(target, context, picture);

                            picture.UpdatedOnUtc = utcNow;
                            ++context.MovedItems;
                        });

                        transaction.Commit();
                        success = true;
                    }
                    catch (Exception exception)
                    {
                        success = false;
                        transaction.Rollback();

                        _services.Notifier.Error(exception.Message);
                        _logger.Error(exception);
                    }
                }
            }


            if (success)
            {
                _services.Settings.SetSetting("Media.Storage.Provider", targetProvider.Metadata.SystemName);
            }

            // inform both provider about ending
            source.OnCompleted(context, success);
            target.OnCompleted(context, success);

            if (success && context.ShrinkDatabase)
            {
                _services.DbContext.ShrinkDatabase();
            }

            return(success);
        }
Exemple #14
0
 public void OnCompleted(MediaMoverContext context, bool succeeded)
 {
     // nothing to do
 }
 public Task ReceiveAsync(MediaMoverContext context, MediaItem media, byte[] data)
 {
     Receive(context, media, data);
     return(Task.FromResult(0));
 }