Формулировка проблемы: в рамках реализации Synergy IDE необходимо обеспечить возможность экспорта и импорта отдельных приложений и глобальных настроек платформы.
Связанные задачи:
Решение:
В данной задаче описаны:
Поскольку в Synergy IDE считается, что каждый объект приложения представляет собой отдельный файл или папку с файлами, то необходимо изменить подход к экспорту и импорту приложений Synergy.
Во-первых, при экспорте приложения экспортируются все объекты приложения, без возможности выбора отдельных объектов. Таким образом, исключается проверка целостности экспортируемой конфигурации.
Во-вторых, результатом экспорта
является 7z
-архив, содержащий полную структуру
приложения, аналогичную отображаемой в навигаторе приложения, с
точностью до имен файлов и некоторых метаданных отдельных
объектов. Соответственно, в качестве файла для импорта также
принимается 7z
-архив, содержащий все объекты
приложения вне зависимости от того, какие из объектов фактически
требуют замены. Причем исключается возможность управления версиями
форм, удалением дочерних объектов при замене родительского,
правами при замене объектов: в случае замены объекта он заменяется
целиком, права на него также заменяются. Если для объекта были
указаны права с использованием служебных групп, то эти права
склеиваются.
В-третьих, для импорта архива в приложение необходимо, чтобы номер ревизии импортируемого приложения был больше или равен номеру ревизии текущего приложения. Если это не так, разработчик должен предварительно экспортировать текущее приложение и объединить его с импортируемыми изменениями.
Далее все эти изменения рассмотрены более подробно.
Экспорт открытого приложения выполняется при выборе пункта меню "Приложения" - "Экспорт приложения".
При этом отображается диалог запроса подтверждения действия с сообщением:
В ходе экспорта будут выгружены все объекты приложения. Данный процесс займет некоторое время. Вы уверены, что хотите продолжить?
В случае подтверждения действия отображается отображается окно прогресса экспорта, аналогичное прогрессу экспорта конфигурации, и начинается экспорт объектов приложения в архив:
В корне архива располагается папка
application
, содержащая файл
<код_приложения>.application.json
со сведениями о приложении:
мультиязычное поле "Наименование"
поле "Код"
поле "Ревизия"
список прав на приложение:
группа пользователей
состояние флажка "Чтение"
состояние флажка "Изменение"
При этом если в качестве группы указана служебная группа, то для данной строки экспортируется код группы.
Для каждого объекта приложения в папке
application
создается отдельный файл /
папка с файлами:
для папки приложения создается папка с таким же наименованием, содержащая файлы/папки входящих в нее объектов приложения;
для каждого объекта сущности "Форма" создается
отдельная папка с названием
<код_формы>.form
, содержащая
файлы:
formDefinition.json
с описанием
структуры формы, связей с другими объектами
приложения и значений компонентов по умолчанию;
form.main.script.js
, содержащий
код скрипта формы;
файл шаблона печатного представления формы, если он был загружен;
[<код_динтаблицы>.]<код компонента>.js
для каждого компонента формы, к которому был
добавлен отдельный скрипт;
<код_динтаблицы>
указывается только в том случае, если компонент
располагается в динамической таблице;
для каждого объекта сущности "Пользовательский
компонент" создается отдельная папка с названием
<код_компонента>.userModule
,
содержащая файлы:
description.json
со сведениями об
объекте: название, код пользовательского компонента
и признак использования в формах;
script.js
, содержащий код
JavaScript;
template.html
, содержащий код
HTML;
для каждого объекта сущности "Скрипт
интерпретатора" создается отдельная папка с
названием
<название_скрипта>.interpreterScript
,
содержащая файлы:
description.json
со
сведениями об объекте;
script.js
, содержащий код
скрипта;
для каждого объекта сущности "Пользовательский
отчет" создается отдельная папка с названием
<код_отчета>.userReport
,
содержащая файлы:
description.json
со сведениями об
отчете;
report.template.jrxml
, содержащий
шаблон отчета;
для каждой корневой группы пользователей создается
отдельный файл
<код_группы>.userGroup.json
,
содержащий описание самой корневой группы и ее дочерних
групп;
для каждой корневой группы реестров, как и для групп
пользователей, создается отдельный файл
<код_группы>.registryGroup.json
,
содержащий описание самой корневой группы и ее дочерних
групп;
для каждого объекта остальных сущностей создаются
отдельные файлы json
, имена которым
присваиваются по правилу
<код_объекта>.<имя_сущности>.json
.
Формат файлов соответствует форматам, используемым для
экспорта/импорта конфигурации.
Экспорт считается успешным, если были успешно экспортированы все объектв приложения.
Результатом экспорта является архив в формате
7z
. Имя архива по умолчанию -
app-<код_приложения>-YYYY-MM-DD_hh-mm-ss.7z
,
где YYYY-MM-DD_hh-mm-ss
- текущие дата и
время на сервере.
Экспорт приложения не должен изменять номер его ревизии.
Альтернативный поток 1. Код
экспортируемого объекта содержит символ
/
Ошибка возникает в случае, если код объекта приложения, не
являющегося скриптом или компонентом формы, содержит символы,
использование которых в имени файла недопустимо в файловой
системе - то есть, символ /
.
При этом объект с таким кодом не экспортируется, в области логов событий отображается ошибка с текстом:
Невозможно выполнить экспорт объекта
path/to/file
: код объекта не должен содержать
символы /
, \
,
?
и *
Путь к файлу указывается относительно корневой ноды приложения.
Для каждого некорректного файла отображается отдельная строка с ошибкой, продолжается проверка кодов остальных объектов.
Импорт в открытое приложение выполняется при выборе пункта меню "Приложения" - "Импорт приложения". Пункт меню доступен только в том случае, если у пользователя есть право "Изменение" для текущего приложения.
Первым шагом импорта является выбор файла в диалоговом окне:
Разработчик должен выбрать один архив 7z
и
нажать на кнопку "Импортировать". При этом возможно
выполнение альтернативных потоков 2, 3.
После нажатия на кнопку "Импортировать" отображается диалог запроса подтверждения действия с сообщением:
В ходе импорта все объекты приложения будут полностью заменены загружаемыми. Данный процесс займет некоторое время. Вы действительно хотите продолжить?
Если разработчик подтверждает импорт, то отображается окно прогресса импорта приложения. Внешний вид окна аналогичен существующему прогрессу импорта конфигурации.
Процесс импорта просходит в четыре этапа:
Предварительная валидация выбранного архива. На этом же шаге выполняется обратное преобразование имени файла/папки в имя объекта приложения: исключается указание имени сущности объекта.
Ошибки, возникающие в ходе валидации, отображаются в логе событий. В случае, если валидация была успешно завершена, в логе отображается сообщение "Валидация архива успешно завершена", и отображается таблица импорта объектов.
Если валидация была завершена с ошибками, то кнопка "Завершить" становится доступной, окно не закрывается, импорт объектов не начинается. Возможно выполнение альтернативных потоков 4-10.
Во время предварительной валидации архива для каждой папки и каждого файла вычисляется хэш-сумма. Если она отличается от значения для соответствующего объекта приложения в среде импорта, то объект считается измененным.
Выбор объектов для импорта. Отображется таблица импорта объектов приложения, содержащая целевую структуру приложения - состояние структуры приложения после применения импорта - и флаг "Включать зависимости", по умолчанию включенный. Каждому измененному объекту или папке приложения соответствует флаг включения и подпись:
объект присутствует и в приложении, и в архиве: флаг включен, подпись "Объект будет заменен";
объект присутствует в приложении, но отсутствует в архиве: флаг отключен, подпись "Объект будет скрыт/удален";
объект присутствует в архиве, но отсутствует в приложении: флаг включен, подпись "Объект будет добавлен";
объект присутствует и в приложении, и в архиве, но у него отличается родительская папка: флаг включен, подпись "Объект будет перемещен".
На этом шаге SAD включает флаги объектов, которые должны быть импортированы. При этом:
если флаг "Включать зависимости" включен, то при включении флага объекта включаются также все объекты, от которых он зависит (аналогично реализации импорта/экспорта конфигурации); при отключении флага объекта также отключаются флаги объектов, зависящих от него;
если флаг "Включать зависимости" отключен, то при включении/отключении флага объекта состояние флагов связанных с ним объектов не изменяется.
После завершения выбора объектов необходимо проверить целостность итогового приложения. Проверка выполняется после нажатия на кнопку "Проверить". В процессе проверки отображается окно, содержащее прогресс-бар, область логов, кнопки "Назад", "Импортировать" и "Завершить". Возможно выполнение альтернативных потоков 11, 12.
В случае, если проверка целостности завершена без ошибок, в логе отображается сообщение "Проверка целостности приложения успешно завершена", кнопка "Импортировать" становится доступной. Кнопки "Назад" и "Завершить" в это время заблокированы. По нажатию на кнопку "Импортировать" начинается непосредственно импорт объектов.
Если проверка целостности была завершена с ошибками, кнопки "Назад" и "Завершить" становятся доступны. По нажатию на кнопку "Назад" отображается таблица импорта объектов, состояние флагов для которых такое же, как перед началом проверки. По нажатию на кнопку "Завершить" окно прогресса закрывается, изменения не применяются.
Создание и инициализация импортируемых объектов.
Настройка объектов, их прав, связей и других параметров.
Процент завершения каждого этапа вычисляется независимо. Таким образом, в случае успеха после предварительной валидации архива прогресс-бар трижды принимает значение 100%.
Результатом импорта является обновление структуры и объектов приложения в среде импорта.
Импорт увеличивает номер ревизии приложения.
Необходимо добавить новое события источника "Конфигуратор" для успешного импорта приложения.
Событие: "Импорт приложения"
Описание: Идентификатор: %uuid_приложения%
.
Импортировано приложение из файла
%имя_файла%
. Получен номер ревизии:
%новый_номер_ревизии%
.
Среда импорта | Импортируемый архив | Результат |
---|---|---|
Есть активный объект | Есть активный объект | Активный объект из архива |
Есть скрытый объект | Есть активный объект | Активный объект из архива |
Есть активный объект | Есть скрытый объект | Скрытый объект из архива |
Есть скрытый объект | Нет объекта | Скрытый объект из среды импорта |
Есть активный объект, допустимо его удаление | Нет объекта | Объект удаляется из среды импорта (с учетом проверки целостности) |
Есть активный объект, допустимо его скрытие | Нет объекта | Объект в среде импорта скрывается |
Нет объекта | Есть объект | Добавляется объект из приложения (с учетом проверки целостности) |
Альтернативный поток 2. Не выбран файл.
Действие не выполняется, система отображает сообщение об ошибке с текстом:
Выберите файл
Альтернативный поток 3. Выбран файл,
не являющийся корректным
7z
-архивом.
Действие не выполняется, система отображает сообщение об ошибке с текстом:
Ошибка при чтении архива
Альтернативный поток 4. В выбранном
архиве содержатся некорретные файлы
json
.
Ошибка возникает в случае, если файл в архиве не может быть
прочитан как файл json
, имеет неизвестную
структуру, а также в случае, когда имя сущности объекта
отличаются от указанной в имени файла/папки.
При валидации архива в области логов событий отображается ошибка с текстом:
Некорректный формат файла
path/to/file.json
:
%текст_ошибки%
Путь к файлу указывается относительно корня импортируемого архива.
Для каждого некорректного файла отображается отдельная строка с ошибкой, продолжается валидация остальных элементов архива.
Альтернативный поток 5. Не совпадает номер ревизии в сведениях о приложении в архиве и в среде импорта.
При валидации архива в области логов событий отображается ошибка с текстом:
Не совпадает номер ревизии в сведениях о приложении в архиве и в среде импорта. Пожалуйста, актуализируйте сведения о приложении в импортируемом архиве.
Валидация завершается.
Альтернативный поток 6. Невозможно выполнить обратное преобразование имени файла в код объекта: неизвестный шаблон имени
Ошибка возникает в случае, когда имя файла или папки в архиве
не соответствует известным
шаблонам (например, templateN.html
вместо template.html
для html-кода
пользовательского компонента, или файл
script.js
без родительской папки)
При валидации архива в области логов событий отображается ошибка с текстом:
Неизвестный шаблон имени элемента
path/to/object
Путь к файлу указывается относительно корня импортируемого архива.
Для каждого некорректного файла отображается отдельная строка с ошибкой, продолжается валидация остальных элементов архива.
Альтернативный поток 7. Невозможно выполнить обратное преобразование имени файла в код объекта: код объекта, указанный в файле, не соответствует указанному имени файла или папки.
Ошибка возникает в случае, когда код объекта, который содержится в файле json, не соответствует имени этого файла/ имени папки с учетом шаблонов именования.
При валидации архива в области логов событий отображается ошибка с текстом:
Невозможно выполнить преобразование имени в код для
элемента path/to/object
: код, указанный в
свойствах объекта, не соответствует имени элемента
Для каждого некорректного файла или папки отображается отдельная строка с ошибкой, продолжается валидация остальных элементов архива.
Альтернативный поток 8. Невозможно выполнить обратное преобразование имени файла в код объекта: код объекта имеет некорректный формат.
Ошибка возникает в случае, когда в результате преобразования имен содержимого архива в коды объектов приложения полученный код не соответствует правилам валидации кода, принятым для сущности этого объекта. Например:
код 123 form
некорректен для любой
сущности, поскольку содержит пробел и начинается с цифры;
код код.объекта
некорректен для таких
сущностей, как шаблоны номеров или журналы, поскольку
содержит символы кириллицы и точку. Однако такой код может
быть корректным для форм и реестров, поскольку эти
сущности поддерживают использование кириллицы в кодах.
При валидации архива в области логов событий отображается ошибка с текстом:
Невозможно выполнить преобразование имени в код для
элемента path/to/object
: код объекта не
соответствует правилам валидации для своей сущности
Для каждого некорректного элемента архива отображается отдельная строка с ошибкой, продолжается валидация остальных элементов.
Альтернативный поток 9. Невозможно выполнить обратное преобразование имени файла в код объекта: проблема уникальности кодов объектов.
Ошибка возникает в случае, когда в результате преобразования имен содержимого архива в коды объектов приложения присутствует два или более объекта одной сущности и с одинаковыми кодами, или полученный код объекта уже используется в экземпляре Synergy.
При валидации архива в области логов событий отображается ошибка с текстом:
Невозможно выполнить преобразование имени в код для
элемента path/to/object
: данный код уже
используется
Для каждого некорректного файла отображается отдельная строка с ошибкой, продолжается валидация остальных элементов архива.
Альтернативный поток 10. В архиве присутствуют файлы объектов, для которых не указаны обязательные параметры
Ошибка возникает в случае, когда в архиве присутствует файл объекта, для которого не объявлены или пусты секции, соответствующие обязательным параметрам объекта (например, есть файл реестра, для которого не указано наименование).
При валидации архива в области логов событий отображается ошибка с текстом:
Некорректно указаны обязательные параметры для
объекта в файле
path/to/file.json
Путь к файлу указывается относительно корня импортируемого архива.
Для каждого некорректного файла отображается отдельная строка с ошибкой, продолжается валидация остальных элементов архива.
Альтернативный поток 11. В результирующем приложении присутствуют объекты, для которых не определены зависимые объекты
Ошибка возникает в случае, если для какого-либо объекта был указан объект, от которого он зависит, но архив или приложение не этого объекта (например, есть реестр, для которого не импортируется соответствующая ему форма, или для формы, в которой используется справочник, не выбран этот справочник).
При валидации структуры приложения в области логов событий отображается ошибка с текстом:
%Имя_сущности% %код_объекта%
содержит объявления несуществующих или не выбранных объектов:
%имя_сущности_отсутствующего_объекта1% с кодом %код_отсутствующего_объекта1%
,
...,
%имя_сущности_отсутствующего_объектаN% с кодом %код_отсутствующего_объектаN%
Для каждого некорректного объекта отображается отдельная строка с ошибкой, продолжается валидация остальных объектов.
Альтернативный поток 12. В результирующем приложении присутствуют ссылки объекты, которые будут удалены в результате импорта
Ошибка возникает в случае, когда объект, на который ссылается импортируемый объект, содержится в приложении, но не содержится в архиве, и сущность этого объекта поддерживает удаление. Например, в ситуации, когда импортируется форма без учета зависимостей, но для справочника, на который ссылается компонент этой формы, включен флаг удаления при импорте.
При валидации структуры приложения в области логов событий отображается ошибка с текстом:
%Имя_сущности% %код_объекта%
содержит ссылки на объекты, которые будут удалены в результате
импорта: %имя_сущности_удаляемого_объекта1%
с кодом %код_удаляемого_объекта1%
, ...,
%имя_сущности_удаляемого_объектаN%
с кодом
%код_удаляемого_объектаN%
Для каждого некорректного объекта отображается отдельная строка с ошибкой, продолжается валидация остальных объектов.
Для импорта и экспорта настроек платформы используется существующий импорт/экспорт конфигурации. Для этого необходимо исключить из процессов импорта и экспорта конфигурации все сущности, которые могут включаться в приложение, и оставить только настройки платформы.
Во-первых, переименовать:
пункт "Импорт/экспорт конфигурации" - "Импорт/экспорт настроек";
заголовок окна импорта/экспорта - "Импорт/экспорт настроек";
заголовок окна экспорта - "Экспорт настроек";
заголовок окна импорта - "Импорт настроек".
Во-вторых, из таблиц экспорта и импорта исключить сущности:
счетчики;
шаблоны номеров;
журналы;
типы документов;
внешние модули;
пользовательские компоненты;
внешние модули-компоненты;
формы;
шаблоны маршрутов;
реестры;
группы реестров;
карточки пользователей;
карточки должностей;
карточки подразделений;
действия по сотрудникам;
действия по резерву;
группы;
пользовательские отчеты.
При импорте конфигурации перечисленные сущности, если они содержатся в импортируемом файле, должны игнорироваться.
Сущность "Справочники" необходимо переименовать на "Системные справочники". Она должна включать только справочники с кодами:
action_progress
resolution
send_items
calendar_types
pm_custom_fields
resolution_work_types
work_completion
В-третьих, в разделе "Импорт настроек" исключить флаг "Добавлять новую версию для объектов типа "Форма"".
В-четвертых, изменить событие название и описание успешного импорта конфигурации в разделе "Мониторинг" - "События":
Событие: Импорт настроек.
Описание: Импортированы настройки из файла %имя_файла%. Добавлены: %перечисление добавленных настроек по типам%. Изменены: %перечисление измененных настроек по типам%.
Необходимо изменить метод
rest/api/configuration
: при передаче
параметра new_version
его значение должно
игнорироваться.
В файле, переданном в параметре data
,
необходимо игнорировать все передаваемые объекты, за исключением
системных и специальных справочников:
action_progress
resolution
send_items
calendar_types
pm_custom_fields
resolution_work_types
work_completion
Необходимо реализовать новый метод API для экспорта приложения:
URL метода: rest/api/app/export
Тип метода: GET
Метод принимает один параметр: app_code
- код
экспортируемого архива.
В случае успеха возвращает архив 7z
со всеми
объектами приложения.
В случае ошибки возвращается json
со
следующими полями:
errorCode
- код выполнения (не равный 0);
errorMessage
- сообщение о результате
выполнения (только неуспешном).
Альтернативный поток 1. Не найдено
приложение с кодом
<app_code>
. Сервер
возвращает ошибку 400 с сообщением:
{ "errorCode": 904, "errorMessage": "Не найдено приложение <app_code>" }
Альтернативный поток 2. Пользователь не авторизован, или у авторизованного пользователя недостаточно прав для экспорта. Сервер возвращает ошибку 403 с сообщением:
{ "errorCode": 2, "errorMessage": "Пользователь не авторизован, или у пользователя недостаточно прав для экспорта" }
Альтернативный поток 3. Экспорт приложения завершен с ошибками. Сервер возвращает ошибку 400 с сообщением:
{ "errorCode": 3, "errorMessage": "%текст_первой_полученной_ошибки%" }
Необходимо реализовать новый метод API для импорта приложения:
URL метода: rest/api/app/import
Тип метода: POST
Параметры:
data
- файл, который необходимо
импортировать (обязательный);
locale
- код локали (не обязательный, при
отсутствии параметра используется
язык
системы по умолчанию).
Метод возвращает json
со следующими полями:
errorCode
- код выполнения, 0 - успешно,
иначе - ошибка;
errorMessage
- сообщение о результате
выполнения (успешном либо неуспешном).
messages
- архив логов импорта с
элементами:
type
- тип сообщения, возможные
значения: error
или
info
;
messages
- текст сообщения;
added
- время на сервере в момент
возникновения сообщения.
Код приложения для импорта выделяется из архива
data
. Если экземпляр Synergy не содержит
приложения с таким кодом, то в случае успешного импорта оно
будет создано.
Альтернативный поток 1. Не передан
параметр data
. Сервер возвращает
ошибку 400 с сообщением:
{ "errorCode": 3, "errorMessage": "Не передан параметр data" }
Альтернативный поток 2. Передан
невалидный параметр data
. Сервер
возвращает ошибку 400 с сообщением:
{ "errorCode": 3, "errorMessage": "Ошибка при чтении архива data" }
Альтернативный поток 3. Пользователь не авторизован, или у авторизованного пользователя недостаточно прав для импорта. Сервер возвращает ошибку 403 с сообщением:
{ "errorCode": 2, "errorMessage": "Пользователь не авторизован, или у пользователя недостаточно прав для импорта" }
Альтернативный поток 4. Валидация архива завершена с ошибками. Сервер возвращает ошибку 400 с сообщением:
{ "errorCode": 3, "errorMessage": "Чтение архива произошло с ошибками" "messages": [ /*логи импорта*/ ] }
Альтернативный поток 5. В случае других ошибок сервер возвращает ошибку HTTP 500.