public IFileVersionMetadata WriteRemoteFile(IFolderMetadata folderMetadata, IRemoteFile remoteFile) { if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } if (remoteFile == null) { throw new ArgumentNullException("remoteFile"); } if (string.IsNullOrEmpty(remoteFile.Name)) { throw new ArgumentNullException("remoteFile.Name"); } if (remoteFile.Stream == null) { throw new ArgumentNullException("remoteFile.Stream"); } IBlobFileMetadata blobFileMetadata = this.BlobMetadataAdapter.CreateFile(folderMetadata, remoteFile.Name); blobFileMetadata.Name = remoteFile.Name; //резервация параметров сохранения файла с blobFileMetadata.EnsureRemoteSaveProperties(remoteFile); //запись файла IFileVersionMetadata savedVersion = this.WriteInternal(blobFileMetadata, remoteFile.Stream, remoteFile.TimeCreated); return(savedVersion); }
internal File UploadFileInternal(Folder folder, string fileName, Stream stream) { if (folder == null) { throw new ArgumentNullException("folder"); } if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException("fileName"); } if (stream == null) { throw new ArgumentNullException("stream"); } this.Logger.WriteFormatMessage("UploadFile:Начало загрузки файла, folder.Url: {0}, fileName: {1}", folder.Url, fileName); this.Logger.WriteMessage("UploadFile:Начало записи файла"); IFileVersionMetadata versionMetadata = this.DataAdapter.WriteFile(folder.Metadata, fileName, stream); File file = new File(this, folder, versionMetadata.FileMetadata); FileVersion version = new FileVersion(this, file, versionMetadata); this.Logger.WriteMessage("UploadFile:Окончание записи файла"); this.Logger.WriteFormatMessage("UploadFile:Окончание загрузки файла, folder.Url: {0}, fileName: {1}", folder.Url, fileName); return(file); }
/// <summary> /// Записывает версию файла в хранилище. /// </summary> /// <param name="fileMetadata">Метаданные существующего файла.</param> /// <param name="stream">Содержимое файла.</param> /// <param name="fileName">Имя файла.</param> /// <returns></returns> public IFileVersionMetadata WriteFileVersion(IFileMetadata fileMetadata, Stream stream, string fileName = null) { if (fileMetadata == null) { throw new ArgumentNullException("fileMetadata"); } if (fileMetadata.FolderMetadata == null) { throw new ArgumentNullException("fileMetadata.FolderMetadata"); } if (stream == null) { throw new ArgumentNullException("stream"); } this.Logger.WriteFormatMessage("WriteFileVersion:Начало записи новой версии файла, fileMetadata.Name: {0}, fileMetadata.UniqueID: {1}", fileMetadata.Name, fileMetadata.UniqueID); IBlobFileMetadata blobFileMetadata = (IBlobFileMetadata)fileMetadata; if (!string.IsNullOrEmpty(fileName)) { blobFileMetadata.Name = fileName; } //резервация параметров сохранения //например идентификатора версии, его нужно знать заранее. blobFileMetadata.EnsureSaveProperties(); //запись версии файла IFileVersionMetadata savedVersion = this.WriteInternal(blobFileMetadata, stream); return(savedVersion); }
/// <summary> /// Записывает файл в хранилище. /// </summary> /// <param name="folderMetadata">Метаданные папки.</param> /// <param name="fileName">Имя файла.</param> /// <param name="stream">Содержимое файла.</param> /// <returns></returns> public IFileVersionMetadata WriteFile(IFolderMetadata folderMetadata, string fileName, Stream stream) { if (folderMetadata == null) { throw new ArgumentNullException("folderMetadata"); } if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException("fileName"); } if (stream == null) { throw new ArgumentNullException("stream"); } IBlobFileMetadata blobFileMetadata = this.BlobMetadataAdapter.CreateFile(folderMetadata, fileName); blobFileMetadata.Name = fileName; //запись файла IFileVersionMetadata savedVersion = this.WriteInternal(blobFileMetadata, stream); return(savedVersion); }
/// <summary> /// К-тор. /// </summary> /// <param name="row">Данные.</param> /// <param name="version">Метаданные версии файла.</param> internal FileToken(DataRow row, IFileVersionMetadata version) { if (version == null) { throw new ArgumentNullException("version"); } this.MetadataRow = row; this.FileVersion = version; this.FileMetadata = version.FileMetadata; }
/// <summary> /// Метод генерации токена файла. /// </summary> /// <param name="fileVersionMetadata">Метаданные версии файла.</param> /// <param name="securityIdentifier">Идентификатор безопасности токена.</param> /// <returns></returns> public IFileToken GenerateFileToken(IFileVersionMetadata fileVersionMetadata, string securityIdentifier) { //проверяем наличие токена и создаем при необходимости if (String.IsNullOrEmpty(securityIdentifier)) { return(this.EnsureFileToken(fileVersionMetadata)); } //при выдаче защищенного доступа всегда генерируем новый токен else { return(this.CreateToken(fileVersionMetadata, securityIdentifier)); } }
/// <summary> /// Получение токена доступа к версии файла по уникальносму идентификатору. /// </summary> /// <param name="fileVersionMetadata">Метаданные версии файла.</param> /// <param name="tokenUniqueID">Уникальный идентификатор токена.</param> /// <returns></returns> public IFileToken GetToken(IFileVersionMetadata fileVersionMetadata, Guid tokenUniqueID) { FileToken token = null; this.Logger.WriteFormatMessage("GetToken: Начало операции получения токена. tokenUniqueID='{0}' fileUniqueID='{1}' folderUrl='{2}'", tokenUniqueID, fileVersionMetadata.FileMetadata.UniqueID, fileVersionMetadata.FileMetadata.FolderMetadata.Url); string tableName = this.GetTableName(fileVersionMetadata.FileMetadata); DBObjectDistributedTable table = null; this.Logger.WriteMessage("GetToken: Получение таблицы."); try { table = this.TypedMetadataAdapter.TableActivator.GetDistributedTable(this.DBSchemaAdapter, tableName); } //В случае когда для данного файла и папки генерация токена не запрашивалась, таблица токенов могла быть не создана. //В данном случае ошибки нет, т.к. токен еще не генерировался. catch (DistributedTableNotFoundException notFoundEx) { return(null); } catch (Exception ex) { throw ex; } this.Logger.WriteMessage("GetToken: Конец получения таблицы."); MetadataQueryBuilder queryBuilder = new MetadataQueryBuilder(table.TablePartition.Table, this.TypeDefinition); string query = @" {SelectQuery} WHERE [UniqueID] = '{UniqueID}' AND [Expired] > GETDATE()" .ReplaceKey("SelectQuery", queryBuilder.SelectQuery) .ReplaceKey("UniqueID", tokenUniqueID); this.Logger.WriteFormatMessage("GetToken: Начало запроса в БД. Запрос:'{0}'", query); DataRow resultRow = this.DataAdapter.GetDataRow(query); this.Logger.WriteMessage("GetToken: Конец запроса в БД."); if (resultRow != null) { token = new FileToken(resultRow, fileVersionMetadata); } this.Logger.WriteMessage("GetToken: Конец."); return(token); }
/// <summary> /// Проверяет наличие уже выданного токена на файл и при отсутствии создает новый. /// </summary> /// <param name="fileVersionMetadata">Метаданные версии файла.</param> /// <returns>Токен доступа к версии файла.</returns> private FileToken EnsureFileToken(IFileVersionMetadata fileVersionMetadata) { if (fileVersionMetadata == null) { throw new ArgumentNullException("fileVersionMetadata"); } this.Logger.WriteFormatMessage("EnsureFileToken: Начало операции. fileUniqueID: {0}, folderUrl: {1}", fileVersionMetadata.FileMetadata.UniqueID, fileVersionMetadata.FileMetadata.FolderMetadata.Url); FileToken fileToken = null; this.Logger.WriteMessage("EnsureFileToken: Получение таблицы."); string tableName = this.GetTableName(fileVersionMetadata.FileMetadata); DBObjectDistributedTable table = this.TypedMetadataAdapter.TableActivator.EnsureDistributedTable(this.DBSchemaAdapter, tableName); MetadataQueryBuilder queryBuilder = new MetadataQueryBuilder(table.TablePartition.Table, this.TypeDefinition); this.Logger.WriteMessage("EnsureFileToken: Конец получения таблицы."); string resultQuery = @"DELETE FROM {TableName} WHERE [Expired] < GETDATE() {SelectQuery} WHERE [FileID] = {FileID} AND [VersionID] = {VersionID} AND ([SecurityIdentifier] IS NULL OR [SecurityIdentifier] = '')" .ReplaceKey("TableName", tableName) .ReplaceKey("SelectQuery", queryBuilder.SelectQuery) .ReplaceKey("FileID", fileVersionMetadata.FileMetadata.ID) .ReplaceKey("VersionID", fileVersionMetadata.ID); this.Logger.WriteFormatMessage("EnsureFileToken: Начало запроса в БД. Запрос:{0}", resultQuery); DataRow tokenRow = this.DataAdapter.GetDataRow(resultQuery); this.Logger.WriteMessage("EnsureFileToken: Конец запроса в БД."); if (tokenRow != null) { fileToken = new FileToken(tokenRow, fileVersionMetadata); } else { fileToken = this.CreateToken(fileVersionMetadata, null); } this.Logger.WriteMessage("EnsureFileToken: Конец операции."); return(fileToken); }
/// <summary> /// Обновляет содержимое файла. /// </summary> /// <param name="file">Файл.</param> /// <param name="stream">Содержимое файла.</param> /// <param name="fileName">Новое имя файла.</param> internal void UpdateFileInternal(File file, Stream stream, string fileName = null) { if (file == null) { throw new ArgumentNullException("file"); } if (stream == null) { throw new ArgumentNullException("stream"); } this.Logger.WriteFormatMessage("UpdateFileInternal:Начало обновления содержимого файла {0} ({1}). ", file.Name, file.UniqueID); IFileVersionMetadata versionMetadata = this.DataAdapter.WriteFileVersion(file.Metadata, stream, fileName); FileVersion version = new FileVersion(this, file, versionMetadata); this.Logger.WriteFormatMessage("UpdateFileInternal:Окончание обновления содержимого файла {0} ({1}).", file.Name, file.UniqueID); }
/// <summary> /// Считывает поток данных версии файла. /// </summary> /// <param name="versionMetadata">Метаданные версии файла.</param> /// <returns></returns> public Stream ReadFileVersionStream(IFileVersionMetadata versionMetadata) { if (versionMetadata == null) { throw new ArgumentNullException("versionMetadata"); } this.Logger.WriteFormatMessage("ReadFileVersionStream:Начало чтения содержимого версии файла, folder.Url: {0}, version.UniqueID: {1}", versionMetadata.FileMetadata.FolderMetadata.Url, versionMetadata.UniqueID); IBlobFileVersionMetadata typedVersionMetadata = (IBlobFileVersionMetadata)versionMetadata; //получаем контейнер блобов Blob blob = this.GetBlob(typedVersionMetadata.BlobID); Stream stream = blob.ReadStream(typedVersionMetadata); this.Logger.WriteFormatMessage("ReadFileVersionStream:Окончание чтения содержимого версии файла, folder.Url: {0}, version.UniqueID: {1}", versionMetadata.FileMetadata.FolderMetadata.Url, versionMetadata.UniqueID); return(stream); }
public FileVersion(StorageEngine storage, File file, IFileVersionMetadata metadata) { if (storage == null) { throw new ArgumentNullException("storage"); } if (file == null) { throw new ArgumentNullException("file"); } if (metadata == null) { throw new ArgumentNullException("metadata"); } this.TypedStorage = storage; this.TypedFile = file; this.Metadata = metadata; }
public IFileVersionMetadata WriteRemoteFileVersion(IFileMetadata fileMetadata, IRemoteFile remoteFile) { if (fileMetadata == null) { throw new ArgumentNullException("fileMetadata"); } if (fileMetadata.FolderMetadata == null) { throw new ArgumentNullException("fileMetadata.FolderMetadata"); } if (remoteFile == null) { throw new ArgumentNullException("remoteFile"); } if (remoteFile.Stream == null) { throw new ArgumentNullException("remoteFile.Stream"); } this.Logger.WriteFormatMessage("WriteFileVersion:Начало записи новой версии файла, fileMetadata.Name: {0}, fileMetadata.UniqueID: {1}", fileMetadata.Name, fileMetadata.UniqueID); IBlobFileMetadata blobFileMetadata = (IBlobFileMetadata)fileMetadata; if (!string.IsNullOrEmpty(remoteFile.Name)) { blobFileMetadata.Name = remoteFile.Name; } //резервация параметров сохранения blobFileMetadata.EnsureRemoteSaveProperties(remoteFile); //запись версии файла IFileVersionMetadata savedVersion = this.WriteInternal(blobFileMetadata, remoteFile.Stream, remoteFile.TimeCreated); return(savedVersion); }
/// <summary> /// Создает новый токен доступа к файлу и записывает в БД. /// </summary> /// <param name="fileVersionMetadata">Метаданные версии файла.</param> /// <param name="securityIdentifier">Идентификатор безопасности токена.</param> /// <returns>Новый токен доступа.</returns> private FileToken CreateToken(IFileVersionMetadata fileVersionMetadata, string securityIdentifier) { if (fileVersionMetadata == null) { throw new ArgumentNullException("fileVersionMetadata"); } this.Logger.WriteFormatMessage("CreateToken: Начало операции создания токена. fileUniqueID: {0}, folderUrl: {1}, securityIdentifier: {2}", fileVersionMetadata.FileMetadata.UniqueID, fileVersionMetadata.FileMetadata.FolderMetadata.Url, securityIdentifier ?? String.Empty); FileToken fileToken = new FileToken(null, fileVersionMetadata); fileToken.FileID = fileVersionMetadata.FileMetadata.ID; fileToken.VersionID = fileVersionMetadata.ID; fileToken.Expired = DateTime.Now.AddDays(1); fileToken.UniqueID = Guid.NewGuid(); fileToken.SecurityIdentifier = securityIdentifier; this.Logger.WriteMessage("CreateToken: Сохранение токена в БД."); fileToken.ID = this.InsertObject(fileToken); this.Logger.WriteMessage("CreateToken: Конец операции."); return(fileToken); }
private void ProcessRemoteFilesInternal(ReplicationFolder replicationFolder, Tuple <Guid, Guid>[] remoteFiles) { if (replicationFolder == null) { throw new ArgumentNullException("replicationFolder"); } if (remoteFiles == null || remoteFiles.Length == 0) { throw new ArgumentNullException("remoteFiles"); } //словарь существующих файлов. Dictionary <Guid, File> existsFiles = new Dictionary <Guid, File>(); Dictionary <string, byte> uniqueFileVersions = new Dictionary <string, byte>(); //формируем словарь существующих файлов и списков файлов, //которых не существует и которые необходимо реплицировать. List <RemoteFileInfo> filesToDownload = new List <RemoteFileInfo>(); foreach (Tuple <Guid, Guid> fileVersionInfo in remoteFiles) { Guid fileID = fileVersionInfo.Item1; Guid fileVersionID = fileVersionInfo.Item2; bool fileVersionExists = false; string key = string.Format("{0}_{1}", fileID, fileVersionID); if (uniqueFileVersions.ContainsKey(key)) { continue; } uniqueFileVersions.Add(key, 0); File file = null; try { file = this.Engine.GetFileInternal(replicationFolder.Folder.Url, fileID, null, false); } catch (Exception fileEx) { //таблицы с файлов может не быть. this.Logger.WriteMessage(fileEx.ToString(), LogLevel.Error); } if (file != null) { fileVersionExists = file.VersionUniqueID == fileVersionID || file.GetVersion(fileVersionID, false) != null; if (!existsFiles.ContainsKey(file.UniqueID)) { existsFiles.Add(file.UniqueID, file); } } if (!fileVersionExists) { filesToDownload.Add(new RemoteFileInfo(fileVersionInfo, replicationFolder.Folder)); } } if (filesToDownload.Count == 0) { return; } DateTime?lastSync = null; try { foreach (RemoteFileInfo remoteFileInfo in filesToDownload) { IRemoteFile remoteFile = null; try { remoteFile = this.Transport.GetReplicationFile( replicationFolder.SourceStorage, remoteFileInfo.Folder.Url, remoteFileInfo.UniqueID, remoteFileInfo.VersionID); if (remoteFile == null) { throw new Exception(string.Format("Не удалось получить файла с идентификатором {0} с узла {1}", remoteFileInfo.UniqueID, replicationFolder.SourceStorage.Host)); } StorageNode typedNode = (StorageNode)replicationFolder.SourceStorage; remoteFile.CreatedStorageNode = typedNode.Metadata; var stream = remoteFile.Stream; if (stream == null) { throw new Exception(string.Format("Не удалось получить поток файла с идентификатором {0} с узла {1}", remoteFileInfo.UniqueID, replicationFolder.SourceStorage.Host)); } File localFile = null; if (existsFiles.ContainsKey(remoteFile.UniqueID)) { localFile = existsFiles[remoteFile.UniqueID]; } if (localFile == null) { //загружаем новый файл IFileVersionMetadata fileVersion = this.Engine.DataAdapter.WriteRemoteFile(replicationFolder.TypedFolder.Metadata, remoteFile); localFile = new File(this.Engine, replicationFolder.Folder, fileVersion.FileMetadata); //добавляем в коллекцию существующих на текущем узле existsFiles.Add(localFile.UniqueID, localFile); } else { //файл уже существует, добавляем только новую версию файла this.Engine.DataAdapter.WriteRemoteFileVersion(localFile.Metadata, remoteFile); } //обновляем дату синхронизации по дате создания версии lastSync = remoteFile.TimeCreated; } catch (Exception remoteFileEx) { throw new Exception(string.Format("Ошибка при репликации файла {0} с узла {1}", remoteFileInfo.UniqueID, replicationFolder.SourceStorage.Host), remoteFileEx); } finally { try { if (remoteFile != null && remoteFile.Stream != null) { remoteFile.Stream.Dispose(); } } catch (Exception innerEx) { this.Logger.WriteMessage(innerEx.ToString(), LogLevel.Error); } } } } catch (Exception ex) { this.Logger.WriteMessage(ex.ToString(), LogLevel.Error); } if (lastSync.HasValue) { replicationFolder.Metadata.LastSyncTime = lastSync.Value; replicationFolder.Update(); } }