В статье рассказывается, как можно использовать интерфейс
хореографии Web-сервисов для объединения различных Web-сервисов в
реальный бизнес-процесс. На примере онлайновой компании, торгующей
акциями, автор рассматривает сложности, возникающие при использования
языка WSDL для интеграции бизнес-процессов, и объясняет, как можно
применять хореографию для решения этих сложностей.
Введение
По мере того, как все больше компаний обращаются к модной сегодня
технологии Web-сервисов, исследователи прогнозируют, что Web-сервисы
смогут обеспечивать больше, чем просто одностороннее взаимодействие.
Общая тенденция состоит в увеличении значимости композитных приложений,
и корпорации все больше используют Web-сервисы как часть более сложных
взаимодействий процессов. Так называемая хореография Web-сервисов (Web
Service Choreography - WSC) предназначена именно для этой цели.
Интерфейс хореографии Web-сервисов (Web Service Choreography
Interface - WSCI) - это описательный язык интерфейсов на основе XML,
который работает "в связке" с языком описания Web-сервисов (Web
Services Description Language - WSDL). Его цель - позволить корпорациям
использовать возможности Web-сервисов для создания бизнес-процессов,
отражающих постоянно меняющиеся требования современного бизнеса.
Корпорации могут представлять свои прикладные программы и ресурсы в
виде Web-сервисов для того, чтобы другие компании могли оперативно
находить и использовать их в своих бизнес-процессах. Создание
бизнес-процесса требует не только ясного определения моделей
взаимодействия для всех его компонентов, но и нахождения способов
выражения стандартных взаимодействий бизнес по схеме "бизнес-бизнес".
Далее в предлагаемой статье рассматривается, как обычная онлайновая
компания, торгующая акциями, использует Web-сервисы и язык WSDL для
оказания услуг, демонстрируются недостатки этого подхода и то, как они
могут быть преодолены с помощью WSC. Цель настоящей статьи - объяснить,
что такое WSC, дать информацию о возможностях этой технологии и
рассказать о некоторых ее особенностях.
Онлайновая компания, использующая Web-сервисы
Необходимость и роль WSC лучше всего можно увидеть на простом
примере торговли акциями. Для краткости автор предлагает рассмотреть
основные действия, из которых состоит этот процесс. Все шаги покупки и
продажи акций не будут рассматриваться, т.к. это выходит за рамки
статьи. Вместо этого предлагается простой пример приложения для
торговли акциями. На рис. 1 показаны все шаги бизнес-процесса,
необходимого для того, чтобы продавать и покупать акции, используя
онлайновое Web-приложение.
Рис. 1. Бизнес-процесс торговли акциями
Пример использования
Онлайновое приложение для торговли акциями получает информацию об
акциях от стороннего Web-сервиса, например, xmethods.net, и
предоставляет ее пользователю. Пользователь может выбрать те акции,
которые его заинтересовали, и запросить более детальную информацию.
Онлайновая торговая компания использует один из сторонних Web-сервисов
для получения этой информации.
После того, как пользователь выбрал акции для покупки, он делает
заказ. Онлайновое приложение использует один из своих внутренних
процессов для покупки акций на рынке. Затем онлайновое приложение для
торговли акциями просит пользователя подтвердить заказ на покупку и
устанавливает определенный период, в течение которого пользователь
должен подтвердить свой заказ. Если этого не будет сделано в течение
минуты, то пользователь получает уведомление о том, что время истекло.
После подтверждения заказа онлайновое приложение для торговли
акциями снимает необходимую сумму со счета пользователя. Для этого оно
использует один из существующих сторонних Web-сервисов. Оно использует
один Web-сервис для проверки кредитной карты, а другой - для снятия
денег. Оба этих шага должны быть обработаны как логическая
единица всей работы; сбой одного из сервисов приведет к тому, что
пользователь получит сообщение о невозможности выполнить операцию.
Если кредитная карта успешно проходит проверку, а средства без проблем
списываются со счета пользователя, онлайновое приложение осуществляет
покупку требуемого числа акций на рынке. Пользователь может размещать
более одного заказа; каждый из них будет обрабатываться как отдельная
логическая единица.
Заказ на продажу включает такие же шаги, как и заказ на покупку.
Пользователь размещает заказ и подтверждает его, когда это необходимо.
После этого онлайновое приложение размещает заказ на продажу и
переводит деньги на счет пользователя после проверки счета покупателя.
Для того чтобы увеличить число бизнес-каналов и иметь возможность
сотрудничать с другими системами, онлайновая торговая компания может
представить приложение Купить/Продать (Buy/Sell) как Web-сервис. В
случае простого Web-сервиса шаги, перечисленные выше, могут быть
преобразованы ("мэппированы") в операции в WSDL-файле. Используя
программное обеспечение для Web-сервисов, например, редактор Microsoft
VBA или внешнее приложение, вызывающее Web-сервис, пользователь может
вызывать эти операции, описанные на WSDL, для того, чтобы разместить
заказ на продажу или покупку. Пример того, как выполнить эту задачу с
помощью VBA, можно найти по следующей ссылке: http://www.microsoft.com/office/previous/xp/webservices/toolkit.asp. На рис. 1 показаны операции, описанные на WSDL, и мэппирование между бизнес-процессами.
Проблемы WSDL
Хорошо разработанный Web-сервис для покупки и продажи акций работает
нормально, если все процессы являются атомарными или, другими словами,
у них нет общих состояний. Но в этом случае выполнение ряда ключевых
требований к интеграции бизнес-процессов обеспечивает только
посредством WSDL (рис. 2). Ниже перечислены эти основные требования:
Рис. 2. Торговля акциями с помощью WSDL
- Последовательность процессов
Клиент сервиса, использующий Web-сервис купить/продать, может вызывать
операции в любой последовательности. Например, клиент может обратиться
к операции перевода денег до вызова операций размещения заказов на
продажу или покупку (placeBuyOrder или placeSellOrder).
WSDL не препятствует вызову операций в любом порядке. Приложение
Web-сервиса, использующее WSDL, должно удовлетворять этому путем
определенной логики, описанной выше.
- Взаимосвязь сообщений
Взаимосвязь - это простая идея, которая состоит в том, что при обмене
сообщениями (т.е. при отправке письма кому-либо и получении позднее
ответа на него) используется некоторый общий элемент данных в
возвращаемом экземпляре сообщения для его связи с экземпляром исходного
сообщения. При взаимодействии бизнес-процессов очень важно понимать и
описывать взаимосвязь между экземплярами сообщений. У WSDL нет
возможностей для задания взаимосвязи между экземплярами сообщений.
Другими словами, WSDL не поддерживает состояние между операциями. При
обычной интеграции бизнес-процессов для обеспечения совместного
процесса процессы обычно используют одно состояние. Все операции,
описанные с помощью WSDL, не не имеют состояния.
В приведенном выше примере, когда пользователь в качестве следующего
шага размещает заказ на покупку, приложение Web-сервиса требует
подтверждения заказа. Пользователь может захотеть изменить количество
акций или дату покупки. Если заказ изменился, его необходимо размещать
снова. Такой обмен сообщениями может происходить несколько раз, и
пользователь может разместить несколько заказов на покупку, или,
другими словами, осуществить несколько диалогов с приложением
Web-сервиса. Но Web-сервис, использующий только WSDL, не обладает
возможностью задания взаимосвязи между экземплярами сообщений.
- Единица работы
Для того чтобы Web-сервис мог быть частью длительного обмена
сообщениями, важно иметь возможность четко устанавливать время
реального начала обмена сообщениями и его прекращения, а также
определять, какая часть этого обмена может рассматриваться как
транзакция.
В этом примере операции размещения заказа на покупку (placeBuyOrder) и его подтверждения (confirmBuyOrder), а также процесс снятия денег (debit money)
должны осуществляться как одна единица работы. Web-сервис должен
успешно выполнить все три операции; в противном случае пользователю
придется восстанавливать операции до состояния, соответствующего началу
их выполнения. Эти операции не могут быть использованы для
распределенных транзакций, выраженных с помощью WSDL. В WSDL рамки
транзакции ограничены отдельными операциями и не могут охватывать более
одной операции.
- Обработка исключений
Хотя WSDL использует код ошибки для генерации любого исключения, он не
работает с модельными признаками, такими как проверка определенного
сообщения, объявление об истечении времени ожидания исключения или
объявление исключения только для некоторого набора операций, а не для
всего Web-сервиса.
Для взаимодействия процессов необходимо иметь соответствующий модельный
признак для исключения. В приведенном выше примере, если пользователь
не подтверждает заказ на покупку или продажу в течение минуты,
Web-сервис генерирует исключение о превышении времени ожидания.
- Контекст
При взаимодействии бизнес-процессов важно, чтобы у них был общий
контекст для обмена информацией. Эта информация может быть набором
деклараций, исключительных событий или свойств транзакций. У WSDL нет
никаких возможностей для того, чтобы процессы работали в рамках
контекста.
Как WSC может помочь
WSC помогает справиться со всеми вышеназванными сложностями,
возникающими при интеграции процессов, путем использования WSDL как
базовой основы и расширяя его функциональные возможности (рис. 3). В
следующих разделах объясняется, как WSCI справляется с этими
недостатками.
Рис. 3. Торговля акциями с помощью WSC
Контекст
При агрегировании нескольких сервисов для создания составного
бизнес-сервиса они должны иметь общий контекст. Элемент контекста
(<context>) формирует среду для выполнения определенных действий.
Он также следит за тем, чтобы набор действий выполнялся как единая
группа и чтобы все действия в рамках контекста могли иметь общий набор
деклараций, исключительных событий и свойств транзакций.
Определение контекста имеет локальные свойства и определения
локальных процессов. Локальные свойства доступны только для действий,
выполняемых в рамках этого контекста. Определения локальных процессов
указывают именно те процессы, которые могут быть инициированы в рамках
данного контекста. Для того чтобы вызвать внутренний процесс или
осуществить его генерацию, он должен находиться в рамках такого
контекста, где видимы определения локальных процессов.
В листинге 1, приведенном ниже, определение локального процесса
имеет различные контексты для продажи и покупки акций. Если в процессе
покупки акций случается ошибка, то она не выходит за рамки этого
процесса. А, например, если контексты не определены, то ошибка в
процессе продажи может прервать доступ пользователя к Web-сервису
вместо того, чтобы перенаправить это состояние в состояние продажи (placeSellOrder). Ниже приведен фрагмент определения WSCI:
Листинг 1. Пример элемента контекста
<context>
<foreach select="ns1:arrayOfStockList/leg[position()>1]">
<process name = "PlaceBuyOrder" instantiation = "other">
<action name = "PlaceBuyOrder"
role= "tns:trader"
operation= "tns:placeBuyOrder">
</action>
</process>
</foreach>
<process name = "ConfirmBuyOrder" instantiation = "other">
<action name = "ConfirmBuyOrder"
role= "tns:trader"
operation= "tns:confirmBuyOrder" >
<correlate correlation = "
defs:buyStockCorrelation" instantiation= "true" />
</action>
<exception>
<onTimeout property = "
tns:confirmationTime"
type= "duration"
reference="tns:PlaceBuyOrder@end">
<compensate transaction = "tns:reverseBuyOrders"/>
</onTimeout>
</exception>
</process>
<process name="transferMoney" instantiation="other">
<action name = "cashTransaction"
role= "tns:trader"
operation= "tns:debitMoney" >
</action>
</process>
<exception>
<onMessage>
<action name = "reverseBuyOrders"
role= "tns:trader"
operation= "tns:cancelBuyOrder">
</action>
<fault code = "tns:creditCardTxFaultCode"/>
</onMessage>
</exception>
</context>
Определение последовательности процессов
Для
того чтобы элементарные бизнес-процессы вызывались в определенной
последовательности и были сгруппированы в рамках более глобального
бизнес-процесса, WSC использует последовательность элементов
интерфейса. Как видно из названия, это действие обеспечивает вызов
системой процессов в определенной последовательности. Когда
пользователь сервиса хочет купить акции, элемент интерфейса вызывает
операцию перевода денег раньше, чем собственно процесс покупки. Это
достигается определением всех операций, вызываемых последовательно, в
рамках элемента последовательности (<sequence>), как это показано
в листинге 2.
Листинг 2. Пример элемента последовательности
<sequence>
<!-- Web service Choreography Sequence -->
<operation name="placeBuyOrder">
<input message="buySellOrderRequest"/>
<output message="buySellOrderResponse"/>
</operation>
<operation name="confirmBuyOrder">
<input message="buySellOrderResponse"/>
<output message="buySellOrderResponse"/>
</operation>
<operation name="debitMoney">
<input message="creditCardDetails"/>
<output message="debitMoneyResponse"/>
</operation>
</sequence>
Взаимосвязь сообщений
В WSC можно неявно создавать экземпляры при поступлении сообщений за
сервисом. Экземпляры, созданные в WSC, идентифицируются с помощью
ключевых полей внутри сообщений с данными. В рассматриваемом примере
важно установить взаимосвязь между процессами подтверждения заказа на
покупку (confirmBuyOrder) и его размещения (placeBuyOrder),
поскольку каждый из них может произойти раньше другого. Когда запрос на
подтверждение заказа посылается пользователю сервиса, то клиент может
изменить свой заказ (например, поменять количество акций из-за
изменения цены) и разместить заказ на покупку еще раз. Такой обмен
сообщениями между клиентом и Web-сервисом может происходить
неоднократно.
Клиент сервиса может разместить несколько заказов на покупку, что, в
свою очередь, будет сопровождаться несколькими сериями обмена
сообщениями. Каждая такая серия должна быть идентифицирована. Для этого
используется операция идентификации заказа (placeOrderID).
При наличии такого механизма пользователь сервиса может разместить
сколько угодно заказов на покупку, и каждый из них будет участвовать в
своей серии обмена сообщениями. Для каждой серии создается свой placeOrderID.
Для этого определяется элемент взаимодействия (<correlation>)
и свойство (property) со своим ID. Как показано в листинге 3, в данном
случае им может быть код акций.
Листинг 3. Пример элемента взаимодействия
<correlation name = "buysellCorrelation"
property = "tns:placeOrderId" />
Единица работы
WSCI использует элемент транзакции (<transaction>) для
моделирования поведения Web-сервиса и обрабатывает некоторое число
действий как одну единицу работы. Web-сервис использует транзакцию WSCI
для того, чтобы сообщать другим сервисам о своей возможности полностью
выполнить эти действия или восстановить их в состояние, предшествующее
выполнению.
В примере, связанном с продажей или покупкой акций, онлайновая
торговая компания вступает во взаимодействие с различными
Web-сервисами, которые предоставляют сторонние организации (например,
Web-сервис кредитных карт). Если возникает исключительная ситуация или
Web-сервис не может выполнить транзакцию ни с каким из сторонних
провайдеров, то он должен вернуться к предыдущему состоянию. Это
достигается с помощью использования элементов транзакции и компенсации
(<compensation>). В листинге 4 показан пример соответствующего
кода.
Листинг 4. Пример элемента транзакции
<transaction name = "reverseBuyOrder"= "atomic">
<compensation>
<action name = "reverseBuyOrder"= "tns:trader"=
"tns:reverseBuyOrder"/>
</compensation>
</transaction>
Транзакция может быть вызвана в элементе компенсации в том случае, когда возникает исключительная ситуация:
<onTimeout property = "tns:confirmationTime"= "duration"=
"tns:PlaceBuyOrder@end">
<compensate transaction = "tns:reverseBuyOrder"/>
</onTimeout>
Обработка исключений
В интеграции бизнес-процессов обработка исключений и выбор
соответствующего пути важны так же, как и обработка стандартных
вариантов. Для этого WSCI использует элементы исключений
(<exception>). WSCI позволяет декларировать исключительное
поведение, которое демонстрирует Web-сервис в определенный момент
хореографии. Декларация исключительного поведения является частью
определения контекста и связанных с ним исключений и содержит набор
действий, выполняемых Web-сервисом в ответ на эти исключения.
Исключения - это модельный признак WSCI, созданный для моделирования
исключительного поведения Web-сервиса в определенный момент обмена
сообщениями. При этом они не обязаны представлять какой-либо
технический сбой.
WSCI может сгенерировать исключение на основе сообщения о сбое из
WSDL, содержания сообщения или какого-либо события (например,
превышения лимита ожидания). Появление такого исключения вызывает
отмену текущего контекста после выполнения действий, связанных с этим
исключением. Таким образом, WSCI поддерживает концепцию
"восстанавливаемых исключений" (recoverable exceptions), которые не
вызывают отмены всей хореографии (что похоже на концепцию throw/catch в
JavaTM). Но появление сбоя, для которого не определено
никакого исключительного поведения, вызывает отмену контекста и
появления сбоя в родительском контексте. Более абстрактно, исключение,
связанное с обработкой поведения, определенного в родительском
контексте, может работать как поведение по умолчанию для всех своих
потомков, и наоборот: исключение, связанное с обработкой поведения,
определенного в дочернем контексте, может замещать исключение,
связанное с обработкой поведения, определенного в своем родителе.
Как показано в листинге 5, если подтверждение заказа занимает более
минуты, приложение выдает сообщение о превышении лимита ожидания. В WSC
это осуществляется с помощью операции о превышении этого лимита.
Элемент превышения лимита ожидания (<onTimeout>) фактически
является событийным элементом, который используется внутри элемента
исключения. Через минуту возникает событие превышения лимита ожидания,
и система использует элемент компенсации для возвращения к прежнему
состоянию размещения заказа на покупку (placeBuyOrder).
Листинг 5. Пример исключения и элемента превышения лимита ожидания
<exception>
<onTimeout property = "tns:expiryTime"
type = "duration"
reference="tns:ReserveSeats@end">
<compensate transaction = "tns:seatReservation"/>
</onTimeout>
</exception>
Прочие особенности WSCI
В таблице 1 перечислен ряд других полезных возможностей WSCI. Полный список доступен в документации по WSCI.
Таблица 1. Элементы WSCI
Название элемента |
Краткое описание |
Пример |
Выбор (selector) |
Элемент выбирает значение свойства из сообщения. Он полезен для преобразования сложного сообщения в набор свойств. |
Элемент выбора может быть использован для получения общего числа акций из сообщения обо всех акциях (getAllStocksResponse):
<selector property = "tns:stockCount"
element = "tns: ArrayOfStockList
xpath = "count (./StockList)" />
|
Вызов (call) |
Элемент вызывает произвольную
операцию (например, вызов стороннего Web-сервиса) в процессе выполнения
действия. Это атомарный элемент, и действие не может быть выполнено,
если не выполняется вызываемый процесс. |
Если приложение
должно записать все транзакции для операций аудита и согласования, то
для этого может быть вызван произвольный процесс:
<process name = "DebitMoney" instantiation = "other">
<action name = "debitMoney"
role = "tns:trader"
operation = "tns:debitMoney">
</action>
<call process = "auditTransactions"/>
</action>
</process> |
Все действия (all activity) |
Этот элемент похож на
элемент последовательности. Все операции, определенные в элементе
последовательности, выполняются, но операции, определенные в этом
элементе, могут быть выполнены непоследовательно. |
В этом примере заказ на покупку и снятие денег могут быть выполнены в любом порядке:
<all>
<operation name="confirmBuyOrder">
<input message="buySellOrderResponse"/>
<output message="buySellOrderResponse"/>
</operation>
<operation name="debitMoney">
<input message="creditCardDetails"/>
<output message="debitMoneyResponse"/>
</operation>
</all>
|
Для каждого (foreach) |
Элемент выполняет действия в условном цикле. Он похож на элемент цикла в языке Java. |
Элемент выполняет операцию размещения заказа на продажу (PlaceSellOrder) для каждого набора акций в общем списке (arrayOfStocks):
<foreach select="ns1:arrayOfStockList/leg[position()>1]">
<process name = "PlaceSellOrder" instantiation = "other">
<action name = "PlaceSellOrder"= "tns:trader"= "tns:placeSellOrder">
</action>
</process>
</foreach> |
Переход (switch) |
Элемент осуществляет условный
выбор действия из списка действий. Порядок условий очень важен; первым
выполняется условие, значение которого истинно. Элемент похож на
условный элемент языка Java (case statement). |
Элемент
выполняет соответствующее действие, когда значение условия истинно.
Если условие не выполняется, элемент осуществляет операцию отказа.
<switch>
<case>
<condition>tns:reverseBuyOrder</condition>
<action name = "reverseBuyOrder"
role = "tns:trader"
operation = "tns:reverseBuyOrder"/>
</case>
<default>
<action name = "confirmBuyOrder"
role = "tns:trader"
operation = "tns:confirmBuyOrder"/>
</default>
</switch> |
До того, как (until) |
Элемент выполняет все
действия на основе значения оператора Boolean. Он выполняет эти
действия как минимум один раз. Элемент похож на элемент языка Java
"делай пока" (do while). |
<until>
<condition>tns:creditCardProcessed</condition>
<process name = "DebitMoney" instantiation = "other">
<action name = "debitMoney"
role = "tns:trader"
operation = "tns:debitMoney">
</action>
</process>
</until> |
Пока (while) |
Элемент выполняет все действия на
основе значения оператора Boolean. При этом они могут быть выполнены
как один или более раз, так и ни одного. Элемент похож на элемент языка
Java "пока" (while). |
<while>
<condition>tns:creditCardProcessed</condition>
<process name = "DebitMoney" instantiation = "other">
<action name = "debitMoney"
role = "tns:trader"
operation = "tns:debitMoney">
</action>
</process>
</while> |
Задержка (delay) |
Элемент выполняет действие с
определенным периодом задержки. Если в процессе выполнения этого
действия возникает исключительная ситуация, то оно может быть завершено
раньше указанного времени. |
<exception>
<delay property = "tns:delayTime"
type = "duration"
reference="tns:delayBuyingStock">
</delay>
</exception> |
Вызов (call) |
Элемент инициирует процесс и ждет окончания его выполнения. Он полезен для вызова внутренних процессов. |
<call process = "tns:audit" /> |
Генерирование (spawn) |
Элемент инициирует процесс, но не ждет его окончания. |
<Spawn process = "tns:logBuyTransaction" /> |
Объединение (join) |
Элемент ждет окончания
выполнения генерированного процесса. Если нет никаких экземпляров или
все они уже выполнены, действие завершается. |
<join process = "tns:logBuyTransaction" /> |
Выводы
До сегодняшнего дня не существовало стандартного способа описать
поток сообщений, который проходит через Web-сервис, участвующий в
хореографическом взаимодействии с другими сервисами. BEA Systems,
Intalio, SAP AG и Sun Microsystems создали WSCI для решения этой
проблемы. В статье на простом примере были описаны некоторые основные
функции WSCI. Но это только небольшая часть информации. Для того чтобы
лучше понять WSCI, нужно ознакомиться с его спецификацией и попробовать
написать простое приложение.
Ресурсы
- Спецификация интерфейса хореографии Web-сервисов (Web Service Choreography Interface).
- Сайт журнала Web Services Journal.
- Обзор инструментов Office XP для работы с Web-сервисами: как использовать Web-сервисы в редакторе Microsoft VBA (Office XP Web Services Toolkit Tour).
- "Книжный магазин разработчика" (Developer Bookstore): книги по технической тематике, в том числе по Web-сервисам (Web services titles).
- Блоги разработчиков (developerWorks blogs).
- Статьи и пособия по созданию приложений для Web-сервисов (SOA and Web services).
Об авторе
Джером Джозефрай (Jerome Josephraj) живет в Эссексе (графство Англии). Его статья "Struts и Web-сервисы" (Struts and Web Services) была опубликована на сайте IBM. Он также является официальным рецензентом "Справочного руководства по Jakarta Struts" (Jakarta Struts Cookbook) и готовящейся книги "Web-сервисы, сейчас" (Web Service, Now). С ним можно связаться по адресу: jerome_josephraj@hotmail.com.