Файловая корзина#
Файловая корзина (корзина удаленных файлов, recycle bin) хранит удаленные файлы в течение заданного срока вместо немедленного уничтожения. Механизм сохраняет сведения об удалении и, пока содержимое файла остается в хранилище, позволяет пользователю с необходимыми правами найти файл, посмотреть дату удаления и удалившего пользователя, а также выгрузить его содержимое.
Корзина включается отдельно для каждого файлового хранилища с помощью параметра Срок хранения удаленных файлов (дней) на карточке хранилища. После истечения срока хранения файл удаляется окончательно при ближайшем запуске регламентного задания.
Ключевые возможности#
хранение удаленных файлов в течение срока, заданного для файлового хранилища;
сохранение сведений о каждом удалении: даты, удалившего пользователя и объекта-источника, к которому прикреплен файл;
выгрузка содержимого удаленного файла;
окончательное удаление файла;
автоматическая очистка корзины по истечении срока хранения;
передача в S3 команды на удаление объекта при помещении файла в корзину.
Работа механизма#
Условия работы
Корзина выключена по умолчанию. Чтобы включить ее для файлового хранилища, задайте параметр Срок хранения удаленных файлов (дней) со значением больше нуля.
Для автоматической очистки корзины в менеджере заданий должно быть активно регламентное задание Плановая чистка файловой корзины. Задание регистрируется автоматически во включенном состоянии и запускается ежедневно в 01:00. Дополнительная настройка задания не требуется.
Для работы с журналом и выполнения операций пользователю необходимы соответствующие права доступа.
Порядок работы
После удаления файл помещается в корзину или удаляется окончательно.
Пользователь удаляет файл — вложение или версию вложения. Раздел системы, из которого выполнено удаление, на результат не влияет: корзина работает для всех стандартных сценариев удаления файла одинаково. Исключения перечислены в разделе Особенности и ограничения.
Система читает настройки файлового хранилища, в котором находится файл. Если срок хранения не задан или не является положительным, запись о файле и его содержимое удаляются сразу. Если задан положительный срок, система помечает файл как удаленный, а содержимое оставляет в хранилище.
Вместе с признаком удаления система фиксирует дату удаления, имя удалившего пользователя, объект-источник и его наименование. Объект-источник — объект системы, к которому прикреплен файл. Эти сведения записываются при первом удалении и далее не меняются. Если объект-источник у файла не задан, система фиксирует только дату удаления и удалившего пользователя.
Удаленный файл исчезает из обычных списков и карточек файлов и отображается в разделе Журнал удаленных файлов. Путь:
Приложение «Настройка системы» > Аудит > Журнал удаленных файлов.В журнале пользователь с необходимыми правами может найти удаленный файл, выгрузить его содержимое или удалить файл окончательно. При окончательном удалении система удаляет запись о файле и его содержимое из хранилища.
Регламентное задание ежедневно в 01:00 окончательно удаляет файлы с истекшим сроком хранения. Задание обходит хранилища с положительным сроком хранения и обрабатывает файлы каждого хранилища порциями по 1000 записей.
Для безвозвратного удаления файла из корзины используйте в журнале операцию Удалить окончательно.
Внимание
Место в файловом хранилище освобождается после истечения срока хранения или окончательного удаления. Исключение для S3 описано в разделе Синхронизация с хранилищем S3. Это следует учитывать при выборе срока хранения для хранилищ с большим объемом данных.
Работа в интерфейсе системы#
Настройка файлового хранилища
Параметры файловой корзины задаются на закладке Дополнительные настройки карточки файлового хранилища.
Путь: Приложение «Настройка системы» > Сущности > Файловое хранилище.
Настройка |
Тип хранилища |
Назначение |
|---|---|---|
Срок хранения удаленных файлов (дней) |
все типы |
Число дней, в течение которых удаленный файл остается в корзине. Пустое, нулевое или отрицательное значение отключает корзину |
Передавать признак удаления в хранилище S3 |
только S3 |
Передает в S3 команду на удаление объекта при помещении файла в корзину |
Общесистемной настройки срока хранения нет: значение задается у каждого файлового хранилища отдельно. Это позволяет задать длительный срок для хранилища документов и нулевой — для хранилища временных файлов.
Работа с удаленными файлами
Работа с удаленными файлами выполняется в разделе Журнал удаленных файлов.
Путь: Аудит > Журнал удаленных файлов.
Журнал отображает только файлы с признаком удаления и заполненной датой удаления. Последние удаленные файлы отображаются первыми.

В журнале отображаются имя файла, файловое хранилище, полный путь, размер файла, владелец, дата создания, тип и наименование объекта-источника, тип прикрепленного файла, дата удаления и удаливший пользователь.
На панели фильтров можно задать файловое хранилище, имя файла, владельца, удалившего пользователя и период удаления. Условия панели можно дополнить с помощью универсального фильтра.
Операция |
Доступность |
Результат |
|---|---|---|
Выгрузить файл |
для активной строки удаленного файла |
Скачивает содержимое файла из хранилища. Если содержимого в хранилище нет, система сообщает имя файла и файлового хранилища |
Удалить окончательно |
для активной строки удаленного файла |
После подтверждения безвозвратно удаляет содержимое файла из хранилища и запись |
Устройство файловой корзины#
При включенной файловой корзине операция delete объекта Btk_File выполняет логическое удаление: устанавливает признак bDeleted = 1, фиксирует дату удаления и сведения об удалившем пользователе. Запись Btk_File сохраняется до окончательного удаления.
Механизм реализован в модуле btk и включается настройкой файлового хранилища. Прикладные модули используют механизм через стандартную операцию delete.
Техническая часть предназначена для разработчиков прикладных модулей, архитекторов и специалистов сопровождения.
Архитектура механизма#
Механизм построен на следующих принципах:
Разделение логического и физического удаления. Операция
deleteделегирует выполнение вdeleteUsingRecycleBin, а физическое удаление выполняет отдельная операцияpurge.Централизация политики удаления. Прикладной код вызывает стандартную операцию
deleteи не определяет способ удаления. По этой причинеBtk_AttachVerApiудаляет основной файл версии вложения вызовомBtk_FileApi().delete(...), а не прямым вызовомdeleteUsingRecycleBin.Управление поведением через настройки хранилища. Срок хранения читается из
jSettingsобъектаBtk_FileStorageв момент удаления, поэтому администратор включает корзину отдельно для каждого хранилища.Хранение метаданных рядом с файлом. Дата удаления, удаливший пользователь и объект-источник записываются в атрибуты
dDeleteиjDeleteDataзаписиBtk_File.
Дерево компонентов
Btk_FileApi (политика удаления файла)
├── delete(rop) — точка входа прикладного кода, делегирует в deleteUsingRecycleBin
├── deleteUsingRecycleBin(rop, gidpSrc, bScheduleBeforeFlush) — маршрутизация: корзина или purge
├── purge(rop) — окончательное удаление: физический файл и запись Btk_File
├── purgeBeforeFlush(rop) — отложенное окончательное удаление на beforeFlush
└── processRecycleBin() — регламентная очистка корзины по истечении срока хранения
Btk_FileStorageApi (настройки хранилища)
├── getRecycleBinSettings(idpFileStorage) / getRecycleBinSettings(rop)
└── RecycleBinSettings(nRetentionPeriod, bS3Sync)
ru.bitec.app.btk.file.DeletedFileData(sUser, gidSrcObj, sSrcObjHeadline) (метаданные удаления)
├── forSource(gidpSrc) — сбор данных удаления
├── forFile(idpFile) — чтение данных из jDeleteData
└── applyToFile(rop) — запись dDelete и ключей jDeleteData
Компоненты разделяют политику удаления, настройки хранилища и хранение метаданных удаления. Далее описаны данные и настройки, на которых основано это взаимодействие.
Данные и настройки файловой корзины#
Состояние файла
Состояние файла в корзине описывают три атрибута класса Btk_File.
Атрибут |
Тип ODM |
Заголовок |
Назначение |
|---|---|---|---|
|
Number |
Пометка удаления |
признак нахождения файла в корзине |
|
Date |
Дата удаления |
момент помещения файла в корзину |
|
Jsonb |
Информация об удаленном файле |
сведения об удалении: пользователь и объект-источник |
Значение bDeleted = 1 означает, что файл находится в корзине. Сеттер setbDeleted не выполняет действий с файловым хранилищем.
Метаданные удаления
Ключ |
Тип значения |
Содержание |
|---|---|---|
|
строка |
имя удалившего пользователя, |
|
gid |
объект-источник, к которому прикреплен файл |
|
строка |
заголовок объекта-источника, |
Значения gidSrcObj и sSrcObjHeadline остаются пустыми, если файл удаляют без объекта-источника.
Настройки файлового хранилища
Настройки корзины хранятся в ключах jsonb-атрибута jSettings объекта Btk_FileStorage и отображаются на закладке Дополнительные настройки карточки файлового хранилища.
Ключ |
Заголовок в интерфейсе |
Тип |
Область применения |
|---|---|---|---|
|
Срок хранения удаленных файлов (дней) |
число |
все типы файловых хранилищ |
|
Передавать признак удаления в хранилище S3 |
логический |
только хранилища типа S3 |
Пустое, нулевое или отрицательное значение nRecycleBinRetentionDays отключает корзину: стандартная операция delete выполняет окончательное удаление вместо помещения файла в корзину.
Чтение настроек в коде
Btk_FileStorageApi предоставляет две перегрузки getRecycleBinSettings — по идентификатору хранилища и по объекту ApiRop. Обе возвращают case-класс RecycleBinSettings(nRetentionPeriod: NPeriod, bS3Sync: Boolean).
Пример получения настроек для объекта файлового хранилища:
val recycleBinSettings =
Btk_FileStorageApi().getRecycleBinSettings(rvFileStorage)
Если ключ bNeedS3RecycleBinSync отсутствует, bS3Sync принимает значение false.
Жизненный цикл файла#
Состояния записи Btk_File
Состояние |
Признаки |
Как достигается |
Видимость в формах |
|---|---|---|---|
Активный |
|
создание файла |
форма «Файлы» и форма администрирования файловых хранилищ |
В корзине |
|
|
журнал удаленных файлов |
Удален окончательно |
запись |
|
нигде |
Обратный переход из состояния «В корзине» в состояние «Активный» не предусмотрен.
Последовательность обработки удаления#
Помещение файла в корзину
Сценарий выполняется, когда прикладной код удаляет файл, а у хранилища задан положительный срок хранения.
Пример стандартного удаления:
val ropFile = Btk_FileApi().load(idpFile)
Btk_FileApi().delete(ropFile)
Далее механизм выполняет следующие действия:
Прикладной код вызывает
Btk_FileApi().delete(rop).deleteделегирует выполнение вdeleteUsingRecycleBin(rop)с параметрами по умолчанию.Метод проверяет признак
bDeleted. Значение, отличное от1, означает, что файл еще не находится в корзине.Btk_FileStorageApi().load(...)загружает хранилище файла. При пустомidFileStorageиспользуется хранилище по умолчаниюidDefault.getRecycleBinSettings(rvFileStorage)разбираетjSettingsи возвращаетRecycleBinSettings.Поскольку срок хранения положительный, метод вычисляет GID источника
gidpSrc.nvl(rop.get(_.gidSrc)).DeletedFileData.forSource(gidvSrc).applyToFile(rop)записываетdDeleteи ключиjDeleteData.setbDeleted(rop, 1.nr)помечает файл как находящийся в корзине.Запись
Btk_Fileостается в системе до окончательного удаления.
Окончательное удаление при выключенной корзине
Шаги 1–5 совпадают с помещением в корзину, но срок хранения не задан, равен нулю или отрицательный. Далее метод выбирает режим по параметру bScheduleBeforeFlush:
при
trueвызываетсяpurgeBeforeFlush(rop)— вызов окончательного удаления откладывается доbeforeFlush;при
falseвызываетсяpurge(rop)— окончательное удаление записи начинается в текущем вызове.
Окончательное удаление из журнала удаленных файлов
Операция Удалить окончательно доступна для активной строки журнала. Система загружает запись Btk_File по идентификатору и запрашивает подтверждение. После подтверждения вызывается операция purge.
Операция безвозвратно удаляет физический файл из хранилища и запись Btk_File, после чего список журнала обновляется.
Регламентная очистка корзины
По расписанию задание выполняет
Btk_FileApi.processRecycleBin().Система получает файловые хранилища с положительным сроком хранения удаленных файлов.
Для каждого хранилища система вычисляет предельную дату удаления: из текущей даты вычитает настроенный срок хранения.
Отдельный запрос выбирает удаленные файлы текущего хранилища, дата удаления которых меньше предельной.
Файлы обрабатываются порциями по 1000 записей. Для каждого файла вызывается
Btk_FileApi().purge(...), после каждой порции выполняетсяsession.flush().После завершения обработки файлового хранилища выполняется
session.commit().
Срок хранения вычисляется приложением при обработке хранилища, поэтому изменение настройки действует и на файлы, помещенные в корзину ранее. Разделение обхода хранилищ и выбора файлов исключает соединение Btk_File с Btk_FileStorage и разбор jSettings в запросе по таблице файлов.
Для отбора файлов конкретного хранилища по дате удаления используется частичный составной индекс по хранилищу и дате удаления. Индекс содержит только записи корзины, поэтому его размер зависит от объема корзины, а не от общего количества файлов. Ранее созданный частичный индекс по дате удаления также сохраняется.
Синхронизация с хранилищем S3
Синхронизация с S3 выполняется при одновременном выполнении двух условий:
настройка
bNeedS3RecycleBinSyncактивна;тип хранилища равен
Btk_FileStorageTypeApi().idS3.
Файл помещается в корзину в стандартном порядке: запись сохраняет bDeleted = 1, dDelete и jDeleteData.
Дополнительно на beforeFlush планируется вызов deleteFile(svFullFileName) по системному имени хранилища. Команда на удаление передается в S3, а метаданные удаления остаются в системе.
При включенной синхронизации содержимое файла может стать недоступно сразу после помещения записи в корзину. Срок хранения удаленных объектов в S3 настраивается отдельно и может быть меньше срока хранения в Global ERP. В этом случае содержимое удаляется из S3 раньше записи Btk_File.
Транзакции и обработка ошибок#
Физическое удаление файла в purge, purgeBeforeFlush и при синхронизации с S3 выполняется через session.scheduleBeforeFlush.
Регламентное задание обрабатывает каждое файловое хранилище в отдельной транзакции. Файлы выбираются порциями по 1000 записей. После обработки порции система вызывает session.flush(), а после завершения всего хранилища — session.commit().
При вызове session.flush() сначала выполняются запланированные действия beforeFlush. Поэтому физические файлы начинают удаляться до фиксации удаления записей Btk_File в конце обработки хранилища.
Исключение AppException при отдельном вызове purge записывается в журнал, увеличивает счетчик ошибок и не останавливает обработку остальных файлов порции. Если AppException возникает за пределами обработки отдельного файла, транзакция хранилища отменяется, после чего задание переходит к следующему хранилищу.
Ход очистки записывается в серверный журнал и журнал менеджера заданий. В начале задания система указывает количество хранилищ с включенной корзиной. Перед обработкой хранилища записываются его название и предельная дата удаления, а после успешного завершения — название хранилища, количество удаленных файлов и ошибок. В конце задания записываются общие счетчики удаленных файлов и пофайловых ошибок. Отдельное сообщение для каждой порции файлов не формируется.
Сообщение об ошибке отдельного файла содержит название хранилища, полный путь к файлу, текст ошибки и стек вызовов. При ошибке уровня файлового хранилища записываются его идентификатор, текст ошибки и стек вызовов; путь к конкретному файлу в этом случае не гарантирован.
Особенности и ограничения#
При работе с файловой корзиной учитывайте следующие особенности и ограничения:
корзина выключена по умолчанию и начинает использоваться только после задания срока хранения для файлового хранилища;
восстановление файла из корзины не предусмотрено — пользователю с необходимыми правами доступны просмотр сведений об удалении, выгрузка содержимого и окончательное удаление;
окончательное удаление необратимо и выполняется с помощью операции Удалить окончательно, регламентного задания или повторного удаления файла, уже находящегося в корзине;
удаленные файлы доступны в разделе Журнал удаленных файлов и не отображаются в обычных списках и карточках файлов;
файлы удаляются не в момент истечения срока хранения, а при ближайшем запуске регламентного задания;
срок хранения отсчитывается от даты удаления файла, а не от даты его создания или изменения;
при очистке хранилища по настройкам
Btk_FileStorageCleanSettingвыполняетсяpurgeBeforeFlush: записьBtk_Fileи физическое содержимое файла удаляются окончательно, минуя корзину;служебные и производные файлы могут удаляться окончательно с помощью
purgeилиpurgeBeforeFlush, минуя корзину;срок хранения задается только на уровне файлового хранилища — отдельные политики по типам файлов или объектам-источникам не предусмотрены;
операции с базой данных и физическим хранилищем не образуют единую транзакцию: при ошибке во время обработки файлового хранилища записи
Btk_Fileмогут сохраниться в базе данных, хотя часть физических файлов уже удалена.