суббота, 13 февраля 2016 г.

WebLogic JMS и работа с ним в ADF ( Creating Weblogic JMS Server and work with him in ADF)

Добрый день. В какой то момент у вас может появится необходимость обмена данными между вашими приложениями. Для этого можно использовать  Java Message Service (JMS).
Для Oracle Fusion Middleware продуктов используется  WebLogic JMS (описание на англ: https://docs.oracle.com/cd/E24329_01/web.1211/e24387/fund.htm#JMSPG116). Он интегрирован в  WebLogic Server.

Немного теории:

JMS - это  набор интерфейсов и классов  для рассылки сообщений, позволяющий приложениям, выполненным на платформе Java EE, создавать, посылать, получать и читать сообщения.
JMS поддерживает две модели обмена сообщениями: «Point-to-point» и «Publish-subscribe».

Point-to-point модель применяется, когда одному или нескольким senders(отправителям) необходимо послать сообщение одному адресату (receiver).Модель основана на message queue. Отправитель посылают сообщения в очередь, а получатель читает сообщения из очереди.

Publish-subscribe модель применима, когда одному или нескольким отправителям необходимо послать сообщение одному или нескольким получателям. Данная модель основана на понятии message topic.Издатели посылают сообщения в topic, и все подписчики данного topic получают эти сообщения.



Основная терминология JMS


ConnectionFactory – это объект, ответственный за создание JMS Connection через  JNDI. В случае point-to-point модели используется javax.jms.QueueConnectionFactory, в случае pub-sub модели – javax.jms.TopicConnectionFactory.

Connection – абстрактное представление реального соединения между клиентом JMS и Weblogic. В случае point-to-point модели используется javax.jms.QueueConnection, в случае pub-sub модели – javax.jms.TopicConnection.

Session – обьект, создаваемый JMS Connection и используемый клиентами для посылки и принятия сообщений. В случае point-to-point используется javax.jms.QueueSession, в случае pub-sub – javax.jms.TopicSession.

Destination – это либо queue, либо topic – в зависимости от используемой модели: javax.jms.Queue или javax.jms.Topic. Как и ConnectionFactory, destination связывается с деревом JNDI.

MessageProducer – обьект, который  посылает сообщения. В случае point-to-point модели это javax.jms.QueueSender, в случае pub-sub – javax.jms.TopicPublisher.

MessageConsumer – обьект, принимающий сообщения. В случае point-to-point модели это javax.jms.QueueReceiver, в случае pub-sub – javax.jms.TopicSubscriber.

Message– сообщение. О типах сообщений будет сказано ниже.

Типы сообщений:

StreamMessage – сообщение, содержащее сериализованный поток обьектов
MapMessage – сообщение, содержащее пары "ключ-значение"
TextMessage – сообщение, содержащее строку
XMLMessage – расширение TextMessage, используется для доставки XMLсообщений
ObjectMessage– сообщение, содержащее сериализованный обьект
ByteMessage – сообщение, содержащее поток байтов


Сообщения состоят из трех частей: заголовка сообщения, раздела свойств и собственно тела сообщения.

Заголовок сообщения содержит дополнительную информацию, которую разработчик может использовать в своем приложении. JMS предоставляет get и set методы для каждого поля заголовка. Некоторые из них устанавливаются  автоматически, другие могут быть использованы разработчиком приложения.

JMSCorrelationID - используется для кореляции сообщений.
JMSDeliveryMode - определяет сохраняемое сообщение или нет (PERSISTENT или NON_PERSISTENT).
JMSDeliveryTime -  устанавливается самое раннее время, когда сообщение может дойти к получателю.
JMSDestination - Определяет направление (queue или topic), к которому сообщение должно быть доставлено. Это поле устанавливается при создании producer-а или в качестве параметра перед отправкой .
JMSExpiration - определяет, когда сообщение устареет и будет удалено из системы. По умолчанию сообщение не устаревает никогда.
JMSMessageID  -  уникальный идентификатор сообщения. Он начинается с  "ID:"
JMSPriority - приоритет сообщения( от 0 до 9 ) .
JMSRedelivered  - устанавливается, если сообщение не было доставлено с первой попытки
JMSReplyTo  -может быть использован  для того, чтобы получатель знал, кому отсылать ответ.
JMSTimestamp  - содержит время, когда сообщение было отправлено. А WebLogic JMS пропишет время в сообщении, когда получит его.
JMSType  -поле может быть использовано для того, чтобы дать приложению информацию, как обращаться с данным сообщением. Тип здесь понимается как application-specific type.

Раздел свойств содержит пары "ключ-значение", которые могут быть использованы для пересылки определенных данных между producer и consumer. WebLogic Server поддерживает в использовании следующие JMS (JMSX) свойства:
JMSXUserID -  система генерирует свойство, которое идентифицирует пользователя отправляющего сообщение.
JMSXDeliveryCount -система генерирует свойство, в котором указывается количество попыток отправки сообщения
JMSXGroupID идентифицирует группу сообщений.
JMSXGroupSeq -порядковый номер сообщения в пределах группы

Зная структуру сообщений и модели обмен сообщений, осталось рассказать об основных понятиях Weblogic JMS.

JMS Server - это контейнер для  управления ресурсами  JMS модуля. JMS server требуется для создания JMS module
JMS module -  это модуль который содержит такие ресурсы как queues и topics Модуль JMS требуется для того, чтобы создать JMS queue.
Subdeployment - jms модули могут находиться  на нескольких экземплярах WebLogic сервера(targets-ах).  Ресурсы в JMS модуле , такие как queues и topics также могут находиться на сервере JMS или экземплярах сервера WLS.  Subdeployment представляет собой группировку targets-ов.
Connection Factory - connection factory в Weblogic JMS это ресурс который позволяет JMS клиентам создавать соединения к JMS destinations. 


Зная основные понятия, давайте настроим WebLogic JMS и  создадим ADF приложение  для работы с ним. Приступим. 

Начнем с WebLogic

Сначала нужно создать JMS Server. Он создается на вкладке Services->Messaging->JMS Servers


Вам предложат дать имя серверу  и выбрать тип работы с данными(сохранять или нет данные)


Далее вам нужно выбрать экземпляр  WebLogic сервера на котором будет находиться  JMS Server и нажать Finish.


После этого нужно создать JMS Module. Он создается на вкладке Services->Messaging->JMS Modules. В первом окне введите имя и нажмите Next.


Далее нужно выбрать необходимый вам target, нажать на Next, а потом Finish.


После этого нужно зайти в созданный JMS Module, открыть вкладку Subdeployment и нажать на New.

Дать ему имя

И выбрать сервер  который  мы создали ранее


Далее  нужно создать Connection Factory, для этого  в созданном JMS модуле нужно зайти на вкладку Configuration  и нажать New


Выбрать Connection Factory


Дать ему имя  и JNDI имя



Выбрать созданный ранее Subdeplyment и нажать Finish.


Теперь собственно можно создать саму Queue (или Topic).  Для этого нужно вернуться на вкладку Configuration в вашем JMS Module, там нажать на New, а потом Queue



Дать ему имя, JNDI имя и нажать на Finish.


Готово. Queue создан. Сейчас для нас важно знать jndi имена Connection Factory и Queue. В нашем случае это jms/ADFConnectionFactory и jms/ADFJMSQueue.

Теперь создадим приложение в котором будем отправлять и принимать сообщения

Создайте FusionWebApplication с jspx страницей, на которой будут 2 кнопки(Send Message, Read Message) , один inputtext (вводить сообщение) и один  outputtext(выводить полученное сообщение). Также создайте managed bean( для  написания в нем необходимого кода).

jspx должен выглядеть примерно так:



Теперь для работы с JMS нужно добавить две jar-ки :
 - javax.jms._1.1.4.jar  (для Jdeveloper 12.1.3.0.0 находится в Oracle_Home\oracle_common\modules)
 - weblogic.jar (Oracle_Home\wlserver\server\lib)


Теперь нам нужно отправить  и принять сообщение.
Общий алгоритм для Queue следующий :

Отправка:

1. Поиск ConnectionFactory  по jndi имени;
2. Создание соединения ;
3. Создание сессии;
4. Поиск Destination (queue) по jndi имени;
5.  Создание Producer (QueueSender);
6. Активизация соединения;
7. Создание сообщений;
8. Отправка сообщений;
9. Закрытые Producer, сессии и соединения;

Прием:

1. Поиск ConnectionFactory  по jndi имени;
2. Создание соединения  ;
3. Создание сессии;
4. Поиск Destination (queue) по jndi имени
5.  Создание Consumer (QueueReceiver)
6. Активизация соединения
7. Прием сообщений
8. Закрытые Producer, сессии и соединения


Для отправки и приема  код должен выглядеть так :


Рабочее приложение находится на github: https://github.com/JealousyM/jms-adf  commit : ddc165ed6ec81d901b5637e6b872fcdcbb39832e)

И теперь если запустить приложение, появится форма, через которую мы можем отправить и принять сообщение:


На WebLogic сервере в созданной очереди есть возможность просматривать небольшую статистику по Queue. И если отправить и принять сообщение, можно увидеть как меняется статистика :




А приложению возвращается сообщение : )