- PVSM.RU - https://www.pvsm.ru -
[1]
Здравствуйте. В этой статье будет описан еще один способ создания установщика для приложений в InterSystems Caché. Под приложениями здесь имеются в виду разные библиотеки или утилиты, которые могут быть добавлены или удалены из Caché всего одним действием. Если вы всё ещё пишете инструкции для пользователей по установке ваших приложений в Caché, состоящие более чем из одной строки — самое время это автоматизировать.
Допустим, мы разработали некоторую веб-утилиту для Caché, которую хотим в дальнейшем поставлять. Конечно, хотелось бы не тревожить пользователей, которые собираются её устанавливать всякими подробностями по настройке и детальными инструкциями процесса установки. К тому же, все эти инструкции должны быть максимально подробными и ориентированными на пользователей, которые могут не знать Caché. В случае с веб-утилитой при установке потребуется попросить пользователя не только импортировать классы утилиты в Caché, но и, как минимум, настроить веб-приложение для доступа к нему, что является достаточно объемным набором действий:
Конечно, не составляет особого труда все эти действия выполнить программно — нужно будет только один раз разобраться [2] с тем, как создаются веб-приложения с помощью Caché ObjectScript. Но даже в этом случае понадобится, например, попросить пользователя запустить установочный скрипт через терминал.
В Caché есть возможность ограничиться всего одним действием при поставке — импортом пакета классов. И этого достаточно — пользователю просто нужно будет импортировать XML-файл с пакетом классов любым знакомым ему способом:
При этом время компиляции классов будет выполнен код, который произведет установку. Причём если пользователю не понравится установленное им приложение (пакет), и он удалит его, существует также возможность выполнить произвольный код при так называемой «декомпиляции» для отката действий, выполненных при установке.
Расширить поведение компилятора Caché, а именно выполнить произвольный код при компиляции и «декомпиляции» классов позволяет создание класса-проекции в пакете, который мы собираемся установить пользователю. Это такой класс, который наследует %Projection.AbstractProjection [3] и переопределяет два класс-метода: CreateProjection, который выполняется при компиляции класса, и RemoveProjection, который выполняется перед повторной компиляцией класса и при его удалении.
Обычно такой класс называется Installer. Давайте рассмотрим пример такого класса для нашего приложения MyPackage:
Class MyPackage.Installer Extends %Projection.AbstractProjection [ CompileAfter = (Class1, Class2) ]
{
Projection Reference As Installer;
/// This method is invoked when a class is compiled.
ClassMethod CreateProjection(cls As %String, ByRef params) As %Status
{
write !, "Installing..."
}
/// This method is invoked when a class is 'uncompiled'.
ClassMethod RemoveProjection(cls As %String, ByRef params, recompile As %Boolean) As %Status
{
write !, "Uninstalling..."
}
}
Поведение здесь можно описать так:
Так же важно отметить следующее:
Класс %Projection.AbstractProjection [3] также содержит и другие методы, которые мы можем переопределять, но для поставленной задачи они совсем не нужны.
Теперь посмотрим немного глубже на задачу создания веб-приложения для нашей утилиты. Смоделируем простой случай — предположим, у нас есть REST-приложение, которое всего-то отвечает “I am installed!” при попытке его открыть через веб-браузер. Чтобы создать такое приложение, нам необходимо создать класс, описывающий его:
Class MyPackage.REST Extends %CSP.REST
{
XData UrlMap
{
<Routes>
<Route Url="/" Method="GET" Call="Index"/>
</Routes>
}
ClassMethod Index() As %Status
{
write "I am installed!"
return $$$OK
}
}
Класс создан, теперь осталось зарегистрировать это веб-приложение через портал управления. Как это делается как раз и было показано на картинках в начале этой статьи. После выполнения указанных действий, на этом этапе было бы неплохо убедится, что веб-приложение работает, зайдя по адресу http://localhost:57772/myWebApp/ [4] (1. Косая черта в конце необходима; 2. Порт 57772 может быть другим в вашей системе. Он будет идентичен порту, на котором вы просматривали портал управления).
Всю эту рутину создания веб-приложения конечно же можно автоматизировать, переопределив метод CreateProjection для создания веб-приложения, и метод RemoveProjection для его удаления. Наш класс-проекция в простейшем случае будет выглядеть так:
Class MyPackage.Installer Extends %Projection.AbstractProjection [ CompileAfter = MyPackage.REST ]
{
Projection Reference As Installer;
Parameter WebAppName As %String = "/myWebApp";
Parameter DispatchClass As %String = "MyPackage.REST";
ClassMethod CreateProjection(cls As %String, ByRef params) As %Status
{
set currentNamespace = $Namespace
write !, "Changing namespace to %SYS..."
znspace "%SYS" // необходимо изменить пространство имён на %SYS, так как класс Security.Applications существует только там
write !, "Configuring WEB application..."
set cspProperties("AutheEnabled") = $$$AutheUnauthenticated // общедоступное приложение
set cspProperties("NameSpace") = currentNamespace // приложение для области, куда производится импорт
set cspProperties("Description") = "A test WEB application." // описание приложения
set cspProperties("IsNameSpaceDefault") = $$$NO // это приложение не является основным для области
set cspProperties("DispatchClass") = ..#DispatchClass // ранее написанный класс-обработчик
return ##class(Security.Applications).Create(..#WebAppName, .cspProperties)
}
ClassMethod RemoveProjection(cls As %String, ByRef params, recompile As %Boolean) As %Status
{
write !, "Changing namespace to %SYS..."
znspace "%SYS"
write !, "Deleting WEB application..."
return ##class(Security.Applications).Delete(..#WebAppName)
}
}
В этом примере при каждой компиляции класса MyPackage.Installer будет создаваться веб-приложение, а при «декомпиляции» — удаляться. Конечно, было бы хорошим тоном добавить немного проверок на то, существуют ли веб-приложение перед тем, как его удалять или создавать (##class(Security.Applications).Exists(“Имя”) [2]), но ради простоты примера оставим это читателю как домашнее задание.
На данном этапе, после создания классов MyPackage.REST и MyPackage.Installer, мы можем экспортировать классы как один XML файл и делиться этим файлом со всеми желающими. У них, в свою очередь, при импорте и компиляции XML файла автоматически будет создано веб-приложение, и всё, что останется сделать, так это зайти по указанному вами в инструкции адресу.
Рассмотренный в этой статье пример приложения, которое само себя устанавливает, можно скачать отсюда [5] и сразу попробовать «установить».
В отличие от метода установки приложений с использованием системного класса %Installer, о котором так же писали на хабре [6], установка через класс-проекцию обладает следующими значительными отличиями:
Данный подход к поставке приложений уже используется в моих проектах — Caché WEB Terminal [7] и Caché Class Explorer [8]. Там же можно подсмотреть и пример реализованного класса Installer [9].
Хотелось бы напоследок добавить о том, что сообщество инженеров InterSystems экспериментирует с внедрением Package Manager [10]’a, который уже давно существует для таких платформ как NodeJS (npm), Ruby (RubyGems) и т.д. Этот инструмент позволит устанавливать и настраивать любые пакеты и приложения (такие как веб-терминал для Caché [11]) используя всего одну команду. Ну а пока новые приложения на InterSystems Caché и Ensemble с исходными кодами можно найти в этом репозитории [12].
Автор: InterSystems
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/115453
Ссылки в тексте:
[1] Image: https://habrahabr.ru/company/intersystems/blog/279207/
[2] разобраться: http://docs.intersystems.com/cache20152/csp/documatic/%25CSP.Documatic.cls?CLASSNAME=Security.Applications
[3] %Projection.AbstractProjection: http://docs.intersystems.com/cache20152/csp/documatic/%25CSP.Documatic.cls?CLASSNAME=%25Projection.AbstractProjection
[4] http://localhost:57772/myWebApp/: http://localhost:57772/myWebApp/
[5] отсюда: https://gist.github.com/ZitRos/e761473b7933a1beb204
[6] писали на хабре: https://habrahabr.ru/company/intersystems/blog/268767/
[7] Caché WEB Terminal: https://github.com/intersystems-ru/webterminal
[8] Caché Class Explorer: https://github.com/intersystems-ru/UMLExplorer
[9] пример реализованного класса Installer: https://github.com/intersystems-ru/webterminal/blob/master/export/WebTerminal/Installer.xml
[10] Package Manager: https://github.com/intersystems-ru/CPM
[11] веб-терминал для Caché: http://intersystems-ru.github.io/webterminal/
[12] этом репозитории: https://github.com/intersystems-ru
[13] Источник: https://habrahabr.ru/post/279207/
Нажмите здесь для печати.