Пример веб-приложения с применением технологий WSO2

Не так давно на сайте WSO2 был опубликован цикл статей, посвященных разработке веб-приложений с применением продуктов и технологий WSO2. Мне с одной стороны понравился этот пример - так как он дает представление об особенностях WSO2, с другой стороны не очень понравился (ну совсем уж откровенным игнорированием элементарных best practices). И я решил написать свой tutorial, исправив и доплнив некоторые места исходного.

Исходный цикл статей доступен по адресам:

В нашем случае мы будем использовать сдедующие продукты и версии:

  • WSO2 Developer Studio 3.7.1 (но я постараюсь минимально использовать фишки IDE - что бы можно было реализовать примеры без привязки к конкретной среде программирования)
  • WSO2 Application Server 5.2.1 - сервер приложений (по сути дела Tomcat 7.x на базе платформы Carbon)
  • WSO2 Data Services Server 3.2.2 - сервер для работы с базой данных (в нашем случае будет реализовывать DAO-уровень вместо стандартных JPA/Hibernate)

Исходные коды доступны в github: https://github.com/akakunin/wso-health-tutorial/tree/1.0.0

Установка и настройка среды

Начнем с установки продуктов. WSO2 Developer Studio - это по сути дела Eclipse + набор плагинов WSO2 - не думаю что стоит описыват установку и настройку Eclipse.

Развертывание продуктов WSO2 делается однообразно (по сути дела распаковать zip) - можно использовать описание на базе WSO2 ESB, которое я опубликовал ранее.

Тут ест только один важный момент - так как нам будет необходимо запускать одновременно несколько продуктов WSO2 - нам надо "развести" их по портам. Для этого необходимо прописать разные значения в теге <Offset> файла carbon.xml

Для WSO2 AS оставим это значение равным 0 (то есть он будет доступен по портам 8280, 8243, 9443), для WSO2 DSS пропишем 2 (то есть он будет использовать порты 8282, 8245, 9445).

Подключим указанные сервисы к WSO2 DevStudio (опять-таки как это делать можно посмотреть на примере ESB) - что бы можно было запускать и смотреть логи сразу из среды программирования.

Создаем базу и таблицы

Для начала работы нам надо создать базу данных и таблицы в ней. Для этого используем MySQL и скрипт patiens.sql из исходников:

DROP DATABASE IF EXISTS patientdb;
CREATE DATABASE patientdb DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON patientdb.* TO patientdb@'%' IDENTIFIED BY "patientdb";
GRANT ALL ON patientdb.* TO patientdb@'localhost' IDENTIFIED BY "patientdb";
USE patientdb;
SOURCE patients.sql;

Cоздаем сервис для работы с данными

За работы с данными у нас будет отвечать сервер WSO2 DSS. 

Для того, что бы сервер мог работать с базой MySQL  необходимо в капку <DSS_HOME>/repository/components/lib положить jar с драйвером MySQL.

Далее запускаем его (можно прямо из Eclipse) и после запуска заходим в его админку по адресу https://localhost:9445/carbon (как мы помним - мы настроили Offset Для этого сервера в 2, так что все порты сдвинуты на 2 от стандартных значений). Имя пользователя-пароль по умолчанию - admin / admin.

В консоли идем в Services -> Add -> Data Services -> Create

Создаем сервис "WSO2HealthIT" с namespace-ом "http://ws.wso2.org/dataservice/samples/health"

Жмем Next  и добавляем новый DataSource для работы с нашей базой

Жмем "Test Connection" - что бы убедиться что все прошло как надо, после чего "Save".

Идем дальше и добавляем 2 запроса.

Первый запрос - "registerPatientQuery", выбираем созданный DataSource, вставляем SQL:

insert into patient (patientNumber, patientLastName, patientFirstName, phone, city, streetname, country)
values(:patientNumber,:patientLastName,:patientFirstName,:phone,:city,:streetname,:country)

После чего нажимаем "Generate Input Mappings" (что бы DSS сам сгенерировал нам необходимые входные параметры).

Второй запрос будет получать информацию по пациенту, называется "patientDetailsByNumberSQL" и использует SQL:

select patientNumber, patientLastName, patientFirstName, phone, city, streetName, country from patient where patientNumber = ?

Для данного сервиса нужно будет ручками добавить входной параметр "patientNumber".

Для генерации выходных параметров жмем "Generate Response" - нам будут созданы Output Mapping-и. Для соотвествия изначальному tutorial поменяем имена в соотвествии с приведенной ниже таблицей (например в xml  будет использоваться теги patient-first-name и patient-last-name, streetname идет маленькими буквами)

Дальше создаем operations - которые будут работать с созданными запросами.

Сначала создаем "registerPatient" Для работы с запросом "registerPatientQuery"

Затем и operation "patientDetailsByNumber" которая обращается к запросу "patientDetailsByNumberSQL"

Все - можно нажать Finish. Готово - через пару секунд в списке сервисов должен появится новый сервис (WSO2HealthIT) который можно даже протестировать через встроенный в DSS SOAP UI (кликаем на "Try this service")

Для ленивых - на самом деле можно было бы и не проходить весь этот утомительный Wizard - а просто нажать Upload - и загрузить WSO2HealthIT.dbs из исходников - только предварительно проверьте настройки DataSource (имя пользователя, пароль, имя базы).

Создание web-приложения

Важно понимать, что WSO2 AS - это по сути дела Tomcat 7 + Carbon (в принципе как и большинство других продуктов WSO2 представляют собой тот или иной Open Source проект "посаженные" поверх их OSGI платформы Carbon). В этом плане разработка веб-приложения для WSO2 AS  не отличается от разработка для того же Tomcat.

В оригинальном tutorial проект создавался средствами IDE (Eclipse) - но тут у меня все-таки дрогнула рука - по этому проект был переделан на использование Maven. Сам код пока не менял - он "индийский" - его мы будем улучшать в следующих "выпусках". В конце концов - цель данного руководства - не научить правильно писать Java-приложения на JEE, а показать нюансы именно разработки под WSO2.

Так как приложение теперь используем maven - то его можно легко импортировать в Eclipse (либо любую другую IDE).

После сборки приложения (mvn clean install) идем в админку WSO2 AS (https://localhost:9443/carbon/admin) и деплоим полученный war-файл (Applications -> Add -> Web Applications). При деплое можно указать версию приложения (в моем случае я указал 1.0.0 - это позволяет запускать на сервере одновленменно несколько версий одного приложения).

После деплоя мы должны увидеть наше приложение в списке доступных и само приложение будет доступно по адресу http://localhost:9763/wso2-health/1.0.0/

Можно попробовать получить пациента по номеру, либо зарегистрировать нового пациента.

Работа с базой

Исходный код приложения не так интересен - это более менее стандартное простое веб-приложение. Интересно, как осуществляется работа с базой. В WSO2 так, где в обычном JEE приложении использовался JPA, предлагается обращатсья к заранее созданным Data Services (которые мы создали в начале данного tutorial-а). Данное решение выглядит не самым эффективным (на самом деле нет никаких проблем с использованием того же Hibernate в WSO2 AS) - однако при построении "true" SOA приложений (особенно с оглядкой на модные сейчас microservices) это решение выглядит более "иделогически" правильным. Если нам потребуется работа с пациентами из какого-то другого приложения, работа с данными будет осуществляться через одни и те же, заранее написанные сервисы.

Итак, в коде приложения самым интересным выглядит классы QueryPatientDetailServlet и RegisterPatientServlet - а именно их методы createPayload (в котором формируется запрос к серверу) и parseResultFromDSS - где происходит разбор результата. Пока что никаких клиентов по WSDL не генерируется, формирование запроса, как и разбор результата происходят в ручную.

В заключение

Итак, для первого раза достаточно. Мы разобрались что такое WSO2 AS (tomcat), что такое web application for WSO2 (обычное веб-приложение), как создать сервис для работы с данными (при помощи WSO2 DSS) и как работать с этим сервисом из веб-приложения.

Дальше мы добавим авторизацию (с использованием WSO2 Indentity Server), проверку прав доступа к сервису данных (добавив в цепочку WSO2 ESB) и ряд других улучшений.