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); } } }
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; } }
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); } }
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 }; } }
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); } } }
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; } }
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); } }
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); }
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); }
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)); }