- Преобразование сообщений позволяет JBossESB переводить полезные нагрузки сообщений (тело сообщения, а также вложения и свойства) из одной формы в другую, чтобы сообщение могло быть обработано различными службами.
- Маршрутизация сообщений позволяет JBossESB перемещать сообщения в файлы, в ресурсы JMS, такие как очереди, и через «шину» ESB между службами.
30-секундное введение в Smooks
Обычно Smooks называют движком трансформации, но это еще не все. Smooks — это действительно среда обработки более общего назначения, которая может работать с фрагментами сообщения. Smooks выполняет это с помощью «логики посетителя», где «посетитель» — это код Java, который выполняет определенное действие для определенного фрагмента сообщения. Это позволяет Smooks выполнять различные действия над разными фрагментами сообщений. Как говорится в проекте Smooks ( http://www.smooks.org/mediawiki/index.php?title=Why_Smooks_was_Created):
Smooks поддерживает следующие типы обработки фрагментов сообщений:
- Шаблонирование: Преобразование фрагментов сообщения с помощью XSLT или FreeMarker
- Java Binding: привязка данных фрагмента сообщения к объектам Java
- Разделение: разделение фрагментов сообщений и маршрутизация разделенных фрагментов по нескольким транспортам и пунктам назначения.
- Обогащение: «Обогащение» фрагментов сообщений данными из баз данных.
- Постоянство: сохранение данных фрагмента сообщения в базах данных
- Проверка: Выполните базовую или сложную проверку данных фрагмента сообщения.
Готовое действие SmooksAction платформы SOA предоставляет вам доступ ко всем этим возможностям Smooks.
JBossESB реализует несколько готовых действий для поддержки преобразования и маршрутизации сообщений. SmooksAction (org.jboss.soa.esb.smooks.SmooksAction) позволяет использовать мощный набор операций Smooks на платформе SOA. Преобразования, вероятно, являются первым типом операций, о которых вы думаете в Smooks, но с SmooksAction вы также можете использовать операции Smooks, такие как разбиение и маршрутизация полезных нагрузок сообщений.
Простое преобразование со смоки
Давайте рассмотрим очень простой пример, метко названный «transform_XML2XML_simple». Этот быстрый запуск выполняет преобразование сообщения путем применения XSLT (преобразования языка расширяемой таблицы стилей) к сообщению XML. Сообщение преобразуется в XML в другой форме. Интересные части файла быстрого запуска jboss-esb.xml:
<actions mep="OneWay">
<action class="org.jboss.soa.esb.actions.SystemPrintln" name="print-before">
<property name="message" value="[transform_XML2XML_simple] Message before transformation">
</property>
<action class="org.jboss.soa.esb.smooks.SmooksAction" name="simple-transform">
<property name="smooksConfig" value="/smooks-res.xml">
<property name="reportPath" value="/tmp/smooks_report.html">
</property>
<action class="org.jboss.soa.esb.actions.SystemPrintln" name="print-after">
<property name="message" value="[transform_XML2XML_simple] Message after transformation">
</property>
- Строка 1: эта строка не относится к преобразованиям, но стоит упомянуть. «mep» означает «шаблон обмена сообщениями». Шаблон, используемый этим быстрым стартом, является «односторонним» в том смысле, что запрашивающая сторона вызывает службу (отправляя ей сообщение), а затем не ожидает ответа.
- Строки 2-4, 9-24: эти строки просто приводят к записи сообщения в журнал сервера до и после его преобразования. (org.jboss.soa.esb.actions.SystemPrintln, кстати, является единственным готовым действием в группе действий Разное.)
- Строка 5: здесь мы указываем, что мы хотим вызвать SmooksAction
- Строка 6: И вот XSLT, который будет выполнен. Мы рассмотрим этот файл через минуту.
- Строка 7: эта строка на самом деле не в быстром старте. Я добавил свойство reportPath, чтобы мы могли просмотреть итоговый отчет. Обратите внимание, что для создания этого отчета требуются некоторые ресурсы обработки, поэтому его не следует использовать в производственных средах. Ниже приведены скриншоты этого отчета.
Теперь давайте посмотрим на smooks-res.xml:
<?xml version='1.0' encoding='UTF-8'?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.0.xsd">
<resource-config selector="OrderLine">
<resource type="xsl">
<![CDATA[<line-item>
<product><xsl:value-of select="./Product/@productId" /></product>
<price><xsl:value-of select="./Product/@price" /></price>
<quantity><xsl:value-of select="@quantity" /></quantity>
</line-item>]]>
</resource>
<param name="is-xslt-templatelet">true</param>
</resource-config>
</smooks-resource-list>
- Строка 2: упоминаемое здесь пространство имен — это определение XML-схемы Smooks
- Строка 4: элемент resource-config соответствует объекту org.milyn.cdr.SmooksResourceConfiguration [11]
- Строки 7-9. Эти операторы XPath (XML Path Language) определяют атрибуты productId и цены элемента Product, а также количественные атрибуты элемента OrderLine. XPath используется XSLT для поиска или ссылки на данные в документах XML.
Когда вы запустите этот быстрый запуск, вы увидите сообщение XML, как определено в SampleOrder.xml, отображаемое до и после его преобразования XSLT.
Маршрутизация на основе контента с помощью Smooks
Маршрутизация данных из одного места в другое является одной из самых основных и распространенных проблем, с которыми сталкивается любое сетевое программное приложение. Эта маршрутизация может принимать различные формы, такие как отправка электронной почты нужному получателю или сетевой трафик, направляемый по всему миру на основе имен систем, определенных в DNS. В контексте корпоративной сервисной шины, такой как JBossESB в платформе SOA, где все является либо сообщением, либо службой, маршрутизация означает получение сообщений, доставляемых нужным службам.
JBossESB Выбор маршрутизации
JBossESB поддерживает несколько действий для маршрутизации сообщений к сервисам прямо из коробки ( http://jboss-soa-p.blogspot.com/2009/09/works-great-right-out-of-box.html ), таких как :
- HttpRouter (org.jboss.soa.esb.actions.routing.HttpRouter) — HttpRouter направляет входящее сообщение на URL-адрес, указанный в определении действия.
- JMSRouter (org.jboss.soa.esb.actions.routing.JMSRouter) — это действие направляет входящее сообщение в JMS. Например, в очередь JMS, где служба может затем получить сообщение асинхронно. Чтобы найти правильную очередь или тему JMS, вы задаете значения для таких свойств, как jndi-name, initial-context-factory и jndi-URL в определении действия.
- StaticRouter (org.jboss.soa.esb.actions.StaticRouter) — как следует из его названия, этот маршрутизатор устанавливает статические маршруты, которые не изменяются в зависимости от содержимого сообщений или набора правил маршрутизации.
- StaticWiretap (org.jboss.soa.esb.actions.StaticWiretap) — Может быть, это фанат комиксов во мне, но это мое любимое имя для действия. Есть что-то в фильме о «прослушке». Вы можете почти вообразить Хамфри Богарта, сидящего в задней части бара и слушающего прослушиваемое действие SOA. (На черно-белой пленке, конечно.) На практике это не так уж увлекательно. Это действие реализует шаблон интеграции предприятия для прослушивания телефонных разговоров ( http://www.eaipatterns.com/WireTap.html ) . Цель прослушивания — проверить каждое сообщение, не влияя на работу цепочки действий. Это может быть полезным действием для отладки службы.
JBossESB и маршрутизация на основе контестов.
Все они очень полезны, но все они статичны по своей природе, поскольку, как только вы определяете путь для сообщений, это путь, по которому всегда идут сообщения. Например, можно использовать статический путь, чтобы сообщения из службы отдела продаж всегда отправлялись в службу управления складскими запасами. Но что, если у вас было несколько складов, на каждом из которых хранился разный набор продуктов? А что, если вы хотите иметь возможность динамически изменять маршрут сообщений? Например, что если вы хотите, чтобы маршрут, по которому идет сообщение, основывался на фактическом содержании сообщения? Ну, JBossESB также поддерживает несколько типов маршрутизации на основе контента (CBR).
Два относительно легких подхода (http://jbossesb.blogspot.com/2009/10/content-based-routing-in-jbossesb-just.html ) для контентной маршрутизации поддерживаются:
- Маршрутизация на основе содержимого XPath — обратите внимание, что это полностью определено в файле jboss-esb.xml. Никаких дополнительных файлов конфигурации не требуется.
- Маршрутизация на основе содержимого Regex — внешний файл конфигурации используется для определения выражений XPath, которые управляют маршрутизацией.
Теперь, если вы имеете дело с более сложным набором «правил маршрутизации», JBossESB поддерживает использование правил JBoss ( http://jboss-soa-p.blogspot.com/2009/07/when-content-knows-way- content-based.html ) для определения правил маршрутизации. Правила предоставляют вам богатый набор функций JBoss Drools для управления динамической маршрутизацией сообщений на основе их содержимого. JBoss Drools — это полная корпоративная платформа для разработки приложений на основе правил, рабочих процессов, администрирования и обработки событий. Он также обеспечивает интеграцию с JBossESB для поддержки маршрутизации на основе контента. Вы определяете контентный алгоритм маршрутизации в наборе правил.
Но подождите — это еще не все.
Контентно-ориентированная маршрутизация со Smooks
Вы можете подумать о JBoss Smooks ( http://www.smooks.org/) в первую очередь как инструмент для выполнения преобразований XML (например, для преобразования данных из CSV в XML), но его также можно использовать для маршрутизации на основе содержимого в JBossESB в платформе SOA. Некоторые вещи, которые Smooks позволяет вам делать с маршрутизацией на основе контента:
- Разделение сообщений — не просто маршрутизируйте все сообщение, но и разделяйте части сообщения, например, позиции заказа на продажу и направляйте их в отдельные службы.
- Еще более сложное разделение сообщений — например, разделите эти позиции заказа на продажу и затем объедините каждую из них с данными из других частей сообщения (скажем, с информацией клиента) перед выполнением маршрутизации сообщения. Это больше, чем просто извлечение фрагмента сообщения, поскольку извлеченные данные могут быть объединены или обработаны иным образом.
- Маршрутизация разделенных фрагментов сообщений в нескольких форматах — например, маршрутизация XML для одного сервиса, Java для другого, CSV-данные для другого.
- Высокая производительность — Smooks способен выполнять все разбиение и маршрутизацию сообщений (даже для нескольких адресатов и нескольких форматов) за один проход фильтрации сообщения. Это обеспечивает высокую производительность, так как нет необходимости оценивать несколько XPath несколько раз в одном сообщении. Smooks также способен эффективно обрабатывать большие (сделать это ДЕЙСТВИТЕЛЬНО БОЛЬШИЕ, как в> 50 МБ) сообщения.
- Сложные условия — Smooks не ограничивается только условиями, которые поддерживает XPath.
Лучший способ понять и оценить преимущества и гибкость контентной маршрутизации на JBossESB со Smooks — это увидеть ее в действии. Обратите внимание, что мы будем следовать традиции программирования, поскольку в качестве отправной точки мы возьмем быстрый старт и расширим его, чтобы выполнить наши требования.
Быстрый запуск называется: smooks_file_splitter_router
Теперь, как показывает название быстрого запуска , его цель — продемонстрировать как разделение файлов, так и маршрутизацию сообщений. Служба быстрого запуска «Splitter» использует файловый шлюз. Его слушатель файловой системы («fs-listener») использует Smooks org.jboss.soa.esb.smooks.splitting.FileStreamSplitter для разделения входящего XML-сообщения и маршрутизации фрагментов сообщения в службу Receiver.
Давайте внимательнее посмотрим, как это работает, а затем мы углубимся в краткий старт для выполнения некоторой дополнительной контентной маршрутизации.
Быстрый запуск инициируется «муравьедом» цели муравья. Это вызывает org.jboss.soa.esb.sample.quickstart.smooksfilesplitterrouter.InputOrderGenerator класс, который создает файл «SampleOrder.xml» для файлового шлюза. SampleOrder.xml содержит несколько заказов и имеет следующую форму:
<order id="332">
<header>
<customer number="123">Joe</customer>
</header>
<order-items>
<order-item id="1">
<product>1</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
<order-item id="2">
<product>2</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
<order-item id="3">
<product>3</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
<order-item id="4">
<product>4</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
<order-item id="5">
<product>5</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
<order-item id="6">
<product>6</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
<order-item id="7">
<product>7</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
<order-item id="8">
<product>8</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
<order-item id="9">
<product>9</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
</order-items>
</order>
Лучший способ понять, как работает быстрый запуск, — это внимательно посмотреть на поставщиков и сервисы, определенные в файле jboss-esb.xml. Обратите внимание, что в случае этого быстрого запуска, jboss-esb.xml фактически генерируется из jboss-esb-unfiltered.xml во время выполнения, чтобы включить специфическую для среды информацию, такую как имена каталогов. Вот jboss-esb-unfiltered.xml:
<?xml version = "1.0" encoding = "UTF-8"?>
<jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.1.0.xsd"
xmlnssi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.1.0.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.1.0.xsd"
parameterReloadSecs="5">
<providers>
<fs-provider name="FSprovider1">
<fs-bus busid="smooksFileChannel">
<fs-message-filter
directory="@INPUTDIR@"
input-suffix=".xml"
work-suffix=".esbWorking"
post-delete="true"
post-directory="@OUTPUTDIR@"
post-suffix=".sentToEsb"
error-delete="false"
error-directory="@ERRORDIR@"
error-suffix=".IN_ERROR"
/>
</fs-bus>
</fs-provider>
</providers>
<services>
<!--
Splitter Service...
-->
<service category="QS" name="Splitter" description="Splitter Service" invmScope="GLOBAL">
<listeners>
<!-- Splitting the message at the gateway via the FileStreamSplitter composer class allows us to
handle huge messages... -->
<fs-listener name="FileGateway" busidref="smooksFileChannel" is-gateway="true" schedule-frequency="2">
<property name="composer-class" value="org.jboss.soa.esb.smooks.splitting.FileStreamSplitter"/>
<property name="splitterConfig" value="/smooks-config.xml"/>
</fs-listener>
</listeners>
<actions mep="OneWay">
<action name="print" class="org.jboss.soa.esb.actions.SystemPrintln">
<property name="message" value="[Splitter] Message Split complete"/>
</action>
<!-- The next action is for Continuous Integration testing -->
<action name="testStore" class="org.jboss.soa.esb.actions.TestMessageStore"/>
</actions>
</service>
<!--
Receiver Service...
-->
<service category="QS" name="Receiver" description="Receiver Service" invmScope="GLOBAL">
<actions mep="OneWay">
<action name="print" class="org.jboss.soa.esb.actions.SystemPrintln">
<property name="message" value="[Receiver] Message Fragment Received"/>
</action>
</actions>
</service>
</services>
</jbossesb>
- Строки 7-24 — это определение шлюза файловой системы. Что интересно отметить здесь:
- Строки 11-12 — вот входной каталог. В зависимости от конфигурации слушатель будет прослушивать файлы с расширением .xml, созданные в каталоге INPUT.
- Строка 13 — пока файловый шлюз обрабатывает файл, он переименовывается, чтобы иметь расширение «esbWorking».
- Строки 14-16 — После обработки файл снова переименовывается, на этот раз имеет расширение «sentToEsb», а затем он удаляется.
- Строки 17-19 — И, если возникает ошибка, файл переименовывается с расширением «IN_ERROR» и сохраняется в каталоге ошибок.
Услуга «Разветвитель» определяется в строках 31-48. Самые интересные строки:
<fs-listener name="FileGateway" busidref="smooksFileChannel" is-gateway="true" schedule-frequency="2">
<property name="composer-class" value="org.jboss.soa.esb.smooks.splitting.FileStreamSplitter"/>
<property name="splitterConfig" value="/smooks-config.xml"/>
</fs-listener>
- Строка 35 — вот начало определения файлового шлюза.
- Строка 36. Обратите внимание, что когда файловый шлюз обнаруживает наличие файла, он вызывает Smooks org.jboss.soa.esb.smooks.splitting.FileStreamSplitter. И что этот класс делает с файлом?
- Строка 37 — разбивает сообщение на фрагменты в зависимости от условий и действий, определенных в файле smooks-config.xml.
Затем фрагменты сообщения направляются в службу Receiver, которая просто записывает сообщение в server.log.
В файле smooks-config.xml определены разделение и маршрутизация файлов, поэтому давайте более подробно рассмотрим их:
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd"
xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd"
xmlns:esbr="http://www.jboss.org/xsd/jbossesb/smooks/routing-1.0.xsd">
<params>
<param name="stream.filter.type">SAX</param>
</params>
<conditions>
<!-- route the even numbered order items -->
<condition id="routeItem"><!-- orderItem.itemId % 2 == 0 --></condition>
</conditions>
<!-- Capture some data from the message into the bean context... -->
<jb:bean beanId="header" class="java.util.Hashtable" createOnElement="order">
<jb:value property="orderId" data="order/@id"/>
<jb:value property="customerNumber" data="header/customer/@number"/>
<jb:value property="customerName" data="header/customer"/>
</jb:bean>
<jb:bean beanId="orderItem" class="java.util.Hashtable" createOnElement="order-item">
<jb:value property="itemId" data="order-item/@id"/>
<jb:value property="productId" data="order-item/product"/>
<jb:value property="quantity" data="order-item/quantity"/>
<jb:value property="price" data="order-item/price"/>
</jb:bean>
<!-- On each order-item, apply a template to the data captured into the bean context,
binding the templating result back into the bean context under the
beanId "orderItemFragment" to be routed by the following ESB Router... -->
<ftl:freemarker applyOnElement="order-item">
<condition idRef="routeItem" />
<ftl:template>/orderitem-split.ftl</ftl:template>
<ftl:use>
<ftl:bindTo id="orderItemFragment" />
</ftl:use>
</ftl:freemarker>
<!-- On each order-item, route the "orderItemFragment" bean to the -->
<esbr:routeBean beanIdRef="orderItemFragment" toServiceCategory="QS" toServiceName="Receiver" routeOnElement="order-item">
<condition idRef="routeItem" />
</esbr:routeBean>
</smooks-resource-list>
Как мы описали минуту назад, выполняются два основных действия: разбиение входящего сообщения на фрагменты, а затем маршрутизация полученных фрагментов в сервисы. Давайте посмотрим, как выполняется разбиение. Напомним, что файл sampleOrder.xml включает эти элементы XML.
<order id='332'>
<header>
<customer number="123">Joe</customer>
</header>
<order-items>
<order-item id='1'>
<product>1</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
(followed by more order-items)
Помните, как мы говорили о способности Smooks эффективно обрабатывать большие сообщения? На этом этапе важно отметить, что когда Smooks разбивает сообщение XML, он обрабатывает каждый orderItem по одному и одновременно сохраняет в памяти только один orderItem. Это один из способов, с помощью которых Smooks может эффективно обрабатывать большие сообщения.
- Строки 17-21 — Как показывают комментарии, это захватывает данные из сообщения и извлекает свойства orderId, customerName и customerNumber (обратите внимание на использование xPath для навигации по исходному сообщению XML) в заголовок (org.jboss.soa.esb). .sample.quickstart.smooksfilesplitterrouter.Header) bean.
- Строки 22-27 — И то же самое относится к элементам заказа.
- Строки 30-38. И здесь Smooks берет bean-компоненты header и orderItems и использует шаблон Freemarker ( http://freemarker.sourceforge.net/ ) для создания bean-компонента orderItemFragment, имеющего эту организацию:
<orderitem id="${orderItem.itemId}" order="${header.orderId}">
<customer>
<name>${header.customerName}</name>
<number>${header.customerNumber}</number>
</customer>
<details>
<productId>${orderItem.productId}</productId>
<quantity>${orderItem.quantity}</quantity>
<price>${orderItem.price}</price>
</details>
Обратите внимание, что Smooks может объединять элементы из bean-компонентов header и orderItems в bean-компонент orderItemFragment.
Итак, давайте рассмотрим, как Smooks направляет фрагменты сообщений в сервисы.
- Строки 11-14 — Во-первых, Smooks устанавливает условие («routeItem»), которое должно быть выполнено для того, чтобы сообщение было маршрутизировано. В этом примере значение элемента orderItem.itemId должно быть четным числом.
- Строки 41 — И вот где фактически начинается маршрутизация. Эта строка определяет атрибуты для маршрутизатора JBoss ESB («routeBean»). Атрибуты, определенные для этого быстрого запуска:
- beanIdRef — это ссылки на bean-компонент, который будет перенаправлен на предполагаемый сервис
- toServiceCategory — категория этой службы, как определено в файле быстрого запуска jboss-esb.xml
- toServiceName — И имя этой службы («Receiver»), опять же, как определено в файле быстрого запуска jboss-esb.xml
- routeOnElement — И, наконец, элемент содержимого, используемый для определения маршрута, по которому следуют сообщения. В случае быстрого старта это элемент заказа.
Хороший способ взглянуть на маршрутизацию на основе контента с помощью Smooks состоит в том, что новые сообщения создаются из данных в виде фрагментов в исходном исходном сообщении. В случае быстрого старта мы хотим направить данные от каждого в сообщении. В этом случае, так как routeOnElement является элементом порядка, когда фильтр обработки Smooks достигает конца каждого фрагмента элемента порядка, он направляет сообщение в «куда-то», то есть конец фрагмента используется для запуска маршрутизации. (Большое спасибо Тому Ф. за это резюме!)
- Строка 42 — идентификатор условия, которое должно соответствовать, чтобы произошла маршрутизация. Этот идентификатор («routeItem») соответствует условию маршрутизации, определенному в строке 13.
Один атрибут, который явно не определен в этом кратком обзоре, это «routeBefore». Этот атрибут позволяет вам контролировать, когда происходит маршрутизация. Это может быть либо (в начале) определенный фрагмент сообщения, обработанный Smooks, либо после (в конце) он обработал фрагмент. По умолчанию используется значение after, поэтому быстрый запуск не определяет атрибут явно.
Обратите внимание, что полный набор атрибутов, управляющих маршрутизацией к службам JBossESB с помощью Smooks, определен в файле routing-1.0.xsd, который развернут на сервере платформы SOA в: smooks.esb / META-INF / xsd / jbossesb / smooks / routing -1.0.xsd
Заключительные мысли
Хорошо, давайте рассмотрим, что случилось. Быстрый старт продемонстрировал две особенности интеграции между Smooks и JBossESB в платформе SOA; разбиение файлов и маршрутизация. Сначала быстрый старт взял один и, возможно, очень большой XML-файл и разделил его содержимое на два отдельных bean-компонента, а затем объединил элементы этих двух bean-компонентов в новый bean-компонент. Когда Smooks выполнял это разделение и преобразование данных из одной формы в другую, он делал это последовательно, когда одновременно в памяти находился только один экземпляр, чтобы он мог эффективно обрабатывать даже большое количество экземпляров. Затем Smooks обнаружил элемент во вновь созданном компоненте и, основываясь на содержимом этого элемента, направил созданный компонент в сообщении в службу ESB.
И — обратите внимание, что для быстрого запуска этих задач не было необходимости писать большое количество нового пользовательского кода. Файл конфигурации Smooks и файл шаблона FreeMarker вместе с вызовом класса org.jboss.soa.esb.smooks.splitting.FileStreamSplitter — все, что было необходимо для быстрого запуска. Smooks и JBossESB в платформе SOA сделали все остальное!
Благодарности
Как всегда, я хочу поблагодарить команду и сообщество JBoss SOA Platform (особенно Тома Феннэлли и Кевина Коннера) за их своевременную рецензию на этот пост в блоге!
Рекомендации
- http://www.smooks.org/
- http://smooks.org/mediawiki/index.php?title=V1.4:Smooks_v1.4_User_Guide#Basic_Processing_Model
- http://smooks.org/mediawiki/index.php?title=V1.4:Smooks_v1.4_User_Guide#Splitting_.26_Routing
- http://smooks.org/mediawiki/index.php?title=Smooks_v1.4_Examples#Huge_Message_Processing_.2F_Splitting_.26_Routing
- http://community.jboss.org/wiki/ComplexSplittingEnrichmentandRoutingofHugeMessages
- http://jboss-soa-p.blogspot.com/2009/09/works-great-right-out-of-box.html
- http://jboss-soa-p.blogspot.com/2009/07/when-content-knows-way-content-based.html