Транзакции JMS и платформа SOA. (перевод, часть 4)

Продолжение. См. предыдущую часть.

Что еще потребуется базе данных в "быстром старте"? Сервис, создающий базу данных (JmsTransactedDatabaseInitializer), должен быть развернут (deployed). Это решается через файл deployment.xml (он создаст очереди JBoss Messaging, которые потребуются для "быстрого старта"):

1.<jbossesb-deployment>
2.<depends>jboss.esb.quickstart.destination:service=Queue,name=quickstart_jms_transacted_Request_esbdepends>
3.<depends>jboss.esb.quickstart.destination:service=Queue,name=quickstart_jms_transacted_Request_gwdepends>
4.<depends>jboss.esb:service=JmsTransactedDatabaseInitializerdepends>
5.jbossesb-deployment>

И в заключении, файлы jbossesb-service.xml и quickstart-ds.xml должны быть включены в архивный файл приложения .esb "быстрого старта". Это реализуется свойством "additional.deploys" в файле "быстрого старта" build.xml и файлом ../conf/base-build.xml, который используется во всех "быстрых стартах".

1.cat -n build.xml | grep quick
2.&lt;property name="additional.deploys" value="jbossesb-service.xml quickstart-ds.xml" /&gt;

ОК, с базой данных у нас все. Теперь давайте посмотрим, как настроить "быстрый старт", чтобы воспользоваться поддержкой транзакций со стороны SOA-платформы JBossESB. Как обычно, все начинается с файла jboss-esb.xml.

В файле jboss-esb.xml

01.xml version = "1.0" encoding = "UTF-8"?>
03.   
04. <providers>
05.   <jms-jca-provider name="JBossMessaging" connection-factory="XAConnectionFactory">
06. 
07.     <jms-bus busid="quickstartGwChannel">
08.       <jms-message-filter
09.         dest-type="QUEUE"
10.         dest-name="queue/quickstart_jms_transacted_Request_gw"
11.         transacted="true"
12.     />
13.     jms-bus>
14.     <jms-bus busid="quickstartEsbChannel">
15.       <jms-message-filter
16.         dest-type="QUEUE"
17.         dest-name="queue/quickstart_jms_transacted_Request_esb"
18.         transacted="true"
19.     />
20.     jms-bus>
21.     <activation-config>
22.       
23.       <property name="dLQMaxResent" value="5"/>
24.     activation-config>
25. 
26.   jms-jca-provider>
27. providers>
28. 
29. <services>
30.   <service
31.     category="JMSSecuredESB"
32.     name="SimpleListener"
33.     description="JMS Secured quickstart sample">
34.     <listeners>
35.       <jms-listener name="JMS-Gateway"
36.         busidref="quickstartGwChannel"
37.         is-gateway="true"/>
38.       <jms-listener name="jmssecured"
39.         busidref="quickstartEsbChannel"/>
40.     listeners>
41.     <actions mep="OneWay">
42. 
43.       <action name="printMessage" class="org.jboss.soa.esb.actions.SystemPrintln">
44.         <property name="message" value="JMS Transacted Quickstart entered. Message body"/>
45.         <property name="printfull" value="false"/>
46.       action>
47. 
48.       <action name="insertDBAction" class="org.jboss.soa.esb.samples.quickstart.jmstransacted.test.DBInsertAction">
49.         <property name="datasource-name" value="java:JmsTransactedDB"/>
50.         <property name="db-insert-sql" value="insert into jms_transacted_table(data_column) values(?)"/>
51.       action>
52. 
53.       
57.       <action name="throwExceptionAction" class="org.jboss.soa.esb.samples.quickstart.jmstransacted.test.ThrowExceptionAction">
58.         <property name="rollbacks" value="5"/>
59.       action>
60. 
61.       <action name="printMessageDone" class="org.jboss.soa.esb.actions.SystemPrintln">
62.         <property name="message" value="JMS Transacted Quickstart processed successfully. Message body"/>
63.         <property name="printfull" value="false"/>
64.       action>
65. 
66.       
67.       <action name="testStore" class="org.jboss.soa.esb.actions.StoreMessageToFile"/>
68.     actions>
69.   service>
70. services>
71. 
72.jbossesb>

  • Строка 2. - Прежде, чем мы пойдем дальше, мы должны посмотреть на XSD (XML schema definition) для файла jboss-esb.xml. Определение схемы доступно здесь: http://anonsvn.jboss.org/repos/labs/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd. Если вы хотите преуспеть в работе с SOA-платформой, будет хорошей идей ознакомиться с XSD, т.к. в нем все элементы для работы с файлом jboss-esb.xml. Двумя основными элементами являются, конечно же, провайдеры и сервисы. Давайте посмотрим сначала на провайдеров. Поддерживается два типа провайдеров.Планирование провайдеров определяется планированием слушателей, которые принимают сообщения из очередей (вы догадались). В отличии от провайдеров шин (bus providers), таких как jms-jca-providers, используемых в "быстром старте", тут нам нужно ассоциироваться со слушателями, которые принимают поставляемые им сообщения. [7]
  • Строка 5. - Вот начало нашего jms-jca-provider. Обратите внимание на то, что XAConnectionFactory предоставляет поддержку для распределенных транзакций.
  • Строки 7-13. -Это ссылка на канал и JMS очередь, которые будут использоваться, когда JMS сообщение будет отправлено в JMS-шлюз (JMS gateway), как заложено логикой "быстрого старта". На секунду остановимся и поговорим о том, в каком виде данные перемещаются в и через SOA-платформу JBossESB. Одной из главных функций, осуществляемых JBossESB, является маршрутизация сообщений между сервисами. (Я говорил об этом, и повторю это снова; запомните это, что в ESB все является либо сообщением, либо сервисом.) Сообщения, которыми оперируют JBossESB, являются org.jboss.soa.esb.message.Message. Конечные точки сервисов (service endpoints), которые могут управлять (process) сообщениями в этой форме, описываются как сущности "ESB-совместимые" ("ESB-aware"). Все это хорошо для сервисов и приложений, которые были разработаны и описаны в этом формате, но как на счет других сервисов, включая  приложения, которые были написаны давно и которые взаимодействуют посредством других, не ESB-совместимых форматов? JBossESB обрабатывает подключения сервисов, которые взаимодействуют посредством не ESB-совместимых форматов - через слушатели шлюзов (gateway listeners). Эти слушатели перенаправляют входящие сообщения от  источников за пределами ESB - к ESB-сервисам. Эти слушатели шлюзов у ESB-шин (как правило, они называются "шлюзами") -  поддерживают различные форматы сообщений, такие как файлы, FTP, и JMS. Эти шлюзы принимают сообщения в не ESB-совместимом формате  Эти шлюзы принимать сообщения в ESB не-известно формате на ESB, а затем преобразовать их (на самом деле, они обертывают первоначальные сообщения), перед отправкой их своим сервисам командных потоков сообщений (service's action pipeline).
  • Строка 11. - Помните, мы хотим, чтобы сервис обрабатывал сообщение, с поддержкой при этом транзакций.
  • Строки 14-20. - Шлюзы предназначены для того, что JBossESB общался со внешними источниками данных. Шлюзы сами по себе не перемещают данные по ESB. Таким образом, для каждого канала шлюза (Gateway channel), который мы определили - мы должны определить соотв. ESB-совместимый канал, который будет использоваться для маршрутизации сообщения в ESB.
  • Строка 21. - Определяем в ноде "activation-config" - как мы будем делать связь (link) с JCA. В этом "быстром старте" еще интересно свойство "dLQMaxResent". Как показывает комментарий в листинге - "DLQMaxResent" контролирует число попыток JCA-адаптера переслать это сообщение, перед тем, как очередь отправки остановит свою работу. Этот сервис JBossESB пересылает сообщение еще раз, в том случае, когда оно попало в очередь недоставленных сообщений. (JMS транспорт обычно имеет очередь недоставленных сообщений, т.к. JBoss Messaging поставляется с набором  преконфигурированных установок в destinations-service.xml, включающих в себя: < mbean code="org.jboss.jms.server.destination.Queue" name="jboss.messaging.destination:service=Queue,name=DLQ"). В этом быстром старте JCA-адаптер будет пытаться отправить сообщение 5 раз.
После того, как мы определили наши провайдеры, мы можем определить наши сервисы.

(продолжение следует)

Транзакции JMS и платформа SOA. (перевод, часть 3)

Продолжение. См. предыдущую часть.

Быстрый старт - в деталях

Транзакция в "быстром старте" включает себя две вещи - сообщение JMS и запись в базу данных. Давайте начнем с изучения подключения к базе данных HSQLDB, которая используется в "быстром старте". Во-первых, нам необходимо создать источник данных для определения подключения к базе данных.

В файле: quickstart-ds.xml:

01.<datasources>
02.<local-tx-datasource>
03.<jndi-name>JmsTransactedDB</jndi-name>
04.<connection-url>jdbc:hsqldb:hsql://localhost:1706</connection-url>
05.<driver-class>org.hsqldb.jdbcDriver</driver-class>
06.<user-name>sa</user-name>
07.<password></password>
08.<min-pool-size>5</min-pool-size>
09.<max-pool-size>20</max-pool-size>
10.<idle-timeout-minutes>0</idle-timeout-minutes>
11.<depends>jboss:service=JmsTransactedDB</depends>
12.<prepared-statement-cache-size>32</prepared-statement-cache-size>
13.</local-tx-datasource>
14. 
15.<mbean code="org.jboss.internal.soa.esb.dependencies.HypersonicDatabase"
16.name="jboss:service=JmsTransactedDB">
17.<attribute name="Port">1706</attribute>
18.<attribute name="BindAddress">localhost</attribute>
19.<attribute name="Database">JmsTransactedDB</attribute>
20.<attribute name="Silent">true</attribute>
21.<attribute name="Trace">false</attribute>
22.<attribute name="No_system_exit">true</attribute>
23.<attribute name="DataDir">${jboss.server.data.dir}</attribute>
24.</mbean>
25.</datasources>

Некоторые пояснения (исправил неточности, ниже. - Прим. перев.):
  • Строка 2. - Мы опеределяем local-tx-datasource так, чтобы можно было использовать JCA-подключение с поддержкой транзакций. [6]
  • Строка 3. - Мы используем JNDI-имя, для ссылки на этот источник данных (datasource).
  • Строки 5-13. - драйвер класса базы данных, соединение, URL, логин/пароль и т.д., для подключения к базе данных.
  • Строка 15. -Интерфейс MBean для работы СУБД Hypersonic в той же самой виртуальной Java-машине, в которой работает и JBoss. Запомним, что здесь у нас название сервиса, а так же JNDI-имя, все это нам скоро потребуется.
 ОК, у нас есть datasource, который нужен для подключения к базе данных HSQLDB, и это нам нужно в режиме поддержки транзакций. Что теперь? Мы должны гарантировать, что наша база данных на самом деле существует, прежде чем мы попытаемся ее использовать! К счастью, у SOA платформы есть класс, который может инициализировать базу данных при развертывании (deployed) .esb-приложения.

В файле jbossesb-service.xml:

01.<?xml version="1.0" encoding="UTF-8"?>
02. 
03.<server>
04.<mbean code="org.jboss.internal.soa.esb.dependencies.DatabaseInitializer"
05.name="jboss.esb:service=JmsTransactedDatabaseInitializer">
06.<attribute name="Datasource">java:/JmsTransactedDB</attribute>
07.<attribute name="ExistsSql">select * from jms_transacted_table</attribute>
08.<attribute name="SqlFiles">
09.hsqldb/create.sql
10.</attribute>
11.<depends>jboss.jca:name=JmsTransactedDB,service=DataSourceBinding</depends>
12.</mbean>
13.</server>

В этом файле есть несколько (3) интересных вещей:
  • Строка 4. - Этот MBean создается при запуске базы данных. Как его подключить к базе данных? Смотри строку 6.
  • Строка 6. - Это ссылка на наш datasource. Обратите внимание на JNDI-имя, которое мы определили в datasource. Как сделать, чтобы DatabaseInitializer знал, какую искать схему в базе данных? Смотри строку 9.
  • Строка 9. - Вот ссылка на файл из "быстрого старта" - src/hsqldb/create.sql. Этот файл создает очень простую таблицу в нашей базе данных, для использования в "быстром старте".
В файле src/hsqldb/create.sql:

1.create table jms_transacted_table
2.(
3.unique_id INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,
4.data_column VARCHAR(255) NOT NULL
5.);

(см. продолжение)