"Avalanche — application framework for Java" — реализация технологии стирающей различия между
вызовами локального и удаленного кода. Отказоустойчивость, масштабируемость,
модифицируемость, непрерывная доступность идут в комплекте приятными бонусами. Все языки программирования предлагают для начала написать простую программу вывода
сообщения "Hello world". Этот пример не подходит для демонстрации функциональных
возможностей "Avalanche — application framework for Java", так как вызов этого примера всегда
возвращает одну и ту же строку и не позволяет идентифицировать источник, возвративший этот
результат. Для первого приложения потребуется реализовать два класса (функцию и приложение), один
интерфейс (адаптер функции) и одну JSP страницу для отображения результата. Разработанное
приложение будет выполняться под управлением Tomcat. В классе реализации функции нет ничего особенного, это обычный класс Java. В качестве
класса функции может быть использован любой класс. Пусть демонстрационный класс функции
возвращает следующую информацию из операционной системы: PID процесса и имя сервера;
версия операционной системы; название операционной системы. Код класса DemoFunction.java С точки зрения языка программирования Java, адаптер — это интерфейс, в котором
декларируются методы класса функции, которые планируются вызывать с помощью этого
адаптера. Для класса DemoFunction требуется написать следующий код интерфейса Код интерфейса DemoAdapter.java Следуют отметить, что все методы созданного интерфейса DemoAdapter должны
обязательно содержать декларирование исключения AvalancheRemote. Данная
реализация чем то напоминает реализацию RMI в языке программирования Java, но есть и
отличия: Реализация адаптера позволяет вызывать методы функции, где бы она не была опубликована. Класс DemoApplication — выполняет вызов метода getInfo() класса DemoFunction
при помощи адаптера DemoAdapter. Пусть класс DemoApplication преобразует
полученный результат вызова getInfo() в формат TXT или HTML. Код интерфейса DemoApplication.java К классу приложения предъявляются следующие требование: он обязательно должен наследоваться от класса ru.funsys.avalanche.Application. Поле info определять не обязательно, ссылку на адаптер можно получить по имени, вызвав наследуемый метод getAdapter(String name) класса ru.funsys.avalanche.Application. Имя адаптера задается в конфигурационном файле приложения. Определение поля позволяет сократить объем кодирования. JSP страница отображает результат вызова метода функции в браузере. Сперва получается ссылка на класс DemoApplication и далее вызывается его метод getInfo c параметром true. Реализация приложения завершена. Теперь нужно определить конфигурацию приложения. В файле web.xml необходимо определить секцию запуска сервлета AvalancheServlet, указав в его параметрах имена конфигурационных файлов приложения и системы логгирования log4j. Сервлет AvalancheServlet инициирует все объекты приложения на основании файла конфигурации avalanche-config.xml. Файл конфигурации приложения с локальным вызовом функции имеет следующий вид В этом файле определены две секции <function> и <application>. Секция <application> имеет вложенный элемент <adapter>, в котором в атрибуте uri указано имя локальной функции (см. значение атрибута name секции <function>). Обращаю внимание на значение атрибута name секции <application>, значение этого атрибута DemoApp указывается в атрибуте id для получения ссылки на экземпляр класса DemoApplication в JSP странице. Вызов удаленной функции обычно требует дополнительной специализированной реализации серверной и клиентской части, предварительно выбрав какое то решения из множества существующих технологий, например REST, SOAP или какую то другую. "Avalanche — application framework for Java" позволяет избежать дополнительного кодирования для вызова методов удаленной функции DemoFunction. Для этого достаточно изменить конфигурацию приложения и опубликовать копию приложения на удаленном сервере. Необходимо добавить в конфигурационный файл avalanche-config.xml секции: Для обеспечения доступа к удаленным объектам по протоколу RMI в файл конфигурации необходимо добавить следующую секцию где: На удаленном узле требуется в конфигурационном файле добавить секцию <connector> где: Для обеспечения доступа к удаленным объектам по протоколу HTTP в файл конфигурации необходимо добавить следующую секцию где: На удаленном узле требуется в конфигурационном файле добавить секцию <connector> где: Примечание! Значение HTTP порта не указывается, используется коннектор HTTP сервера (Tomcat). Дополнительно нужно добавить секции <multipart-config> в конфигурацию сервлета AvalancheServlet и <servlet-mapping> для определения URI этого сервлета в файле web.xml. Новая редакция файла web.xml Чтобы сохранить работоспособность примера локального вызова функции, добавим две копии секции <application> с именами RMIApp и HTTPApp. Атрибуты uri вложенных элементов <adapter> этих секций примут составные значения имя-интерфейса/имя-удаленной функции, т.е. rmi-interface/info и http-interface/info. Объединенная редакция конфигурационного файла avalanche-config.xml для локального и удаленного вызовов по протоколам RMI и HTTP Для сохранения работоспособности JSP страницы first.jsp можно создать ее копии для вызова удаленной функции по протоколу RMI и HTTP, указав значения в атрибуте id RMIApp и HTTPApp соответственно. Код rmi.jsp Код http.jsp Теперь достаточно скопировать разработанное приложение на другой узел, при необходимости заменить значение localhost на адрес удаленного узла в секциях <interface> файла avalanche-config.xml, и проверить работоспособность приложения. Как видно из приведенного примера, для обеспечения удаленного вызова функции не потребовалось вносить каких либо корректировок в программный код локального вызова. Исходные коды, рассмотренного здесь примера приложения, опубликованы на GitHub Приведу пример удаленного вызова с использованием общего файлового сервиса. Оба узла (вызывающий и вызываемый) должны иметь доступ к общему сетевому файловому сервису. Эта разновидность удаленного вызова не такая быстрая, сказывается наличие временных задержек при сканировании файловой структуры для обнаружения файлов запросов и ответов. Но если нельзя по каким либо соображениям общаться напрямую по протоколам на основе TCP/IP, то можно организовать обмен через файловую систему (при наличии общего файлового сетевого ресурса). Для обеспечения доступа к удаленным объектам с использованием файлового сервиса в файл конфигурации необходимо добавить следующую секцию где: На удаленном узле требуется в конфигурационном файле добавить секцию <connector> где: Для каждой опубликованной функции в файловом коннекторе в каталоге коннектора создается свой подкаталог с именем функции (в приведенном примере: info-function) Как и для других протоколов взаимодействия файловый обмен не требует какой-то специфической реализации кода приложения. В любой момент можно переключиться на другой протокол только скорректировав конфигурационные файлы узлов приложения. Программист, Архитектор, Руководитель проекта