Опубликован: 14.08.2008 | Уровень: специалист | Доступ: платный
Лекция 9:

Реализация. Создание корпоративной сервисной шины

9.7.2 Динамическая установка пункта назначения SOAP/Http

В примере 9.15 модуль Flow7_Set_SOAP_address задает пункт назначения SOAP/http для использования узлом HTTPRequest при отправке запроса за оценку выбранному оценщику. URL оценщика (assessorURL) находится во входном сообщении потока Flow6, но он не копируется в сообщение Flow7, посылаемое оценщику, поэтому ESQL-код получает его из входного сообщения потока Flow6.

CREATE COMPUTE MODULE Flow7_Set_SOAP_address
 CREATE FUNCTION Main() RETURNS BOOLEAN
  BEGIN
   CALL CopyEntireMessage();
 -- Нам нужно задать URL AllocateAssessmentRequest. Определен
 --только URL AssessorAvailabilityRequest
 -- Быстрое исправление состоит в наличии соглашения об именах...
   SET OutputLocalEnvironment.Destination.HTTP.RequestURL =
    REPLACE(InputRoot.MRM.soap11:Body.fl6:actionAssessor.fl6:assessor.
            fl6:assessorURL,'Availability','DeliverAssessment');
   RETURN TRUE;
 END;
Пример 9.15. Вычислительный модуль Flow7_Set_SOAP_address

9.7.3 Объявления общих префиксов пространств имен

В табл. 9.11 приведен модуль пространств имен.

Таблица 9.11. Модуль общих пространств имен
ESQL-модуль Описание
common Объявление пространств имен и префиксов

Хорошей практикой является указание укороченных префиксов для пространств имен, используемых в коде ESQL. При этом инструкции становятся более короткими и удобными для чтения. Пространства имен будут находиться в наборе сообщений Assessor, который мы создали ранее. Если есть какие-то пропущенные или дублирующиеся префиксы, сейчас можно изменить или добавить их. Одинаковым пространствам имен нужно присваивать одинаковые префиксы. Мы соблюдали осторожность при редактировании файлов схем, чтобы все они содержали разные префиксы перед их преобразованием в наборы сообщений. Результаты можно увидеть на рис. 9.109.

В навигаторе ресурсов выберите элемент Assessor Messageset \to Assessor, выберите файл messageSet.mset и перейдите на закладку XML1 в редакторе набора сообщений.

Добавление префикса к объявлению пространства имен

увеличить изображение
Рис. 9.109. Добавление префикса к объявлению пространства имен
Примечание. Если используются схемы с одинаковыми пространствами имен, дублирующиеся пространства имен и префиксы отбрасываются брокером сообщений.

Добавьте пространства имен и префиксы из каждого набора сообщений в модуль common.eqsl, как показано в примере 9.16. Обратите внимание, что там, где у нас пространства имен дублируются, мы не можем объявлять дублирующиеся префиксы.

BROKER SCHEMA proxyAssessorSystem
DECLARE soap11  NAMESPACE 'http://schemas.xmlsoap.org/soap/envelope/';
DECLARE fl3     NAMESPACE 'http://broker.lgi.itso.assessavail';
DECLARE fl3a    NAMESPACE 'http://AssessorAvailabilityList.itso';
DECLARE fl7     NAMESPACE 'http://assessor.itso';
DECLARE fl8     NAMESPACE 'http://assbroker.lgi.itso';
DECLARE fl6     NAMESPACE 'http://broker.lgi.itso.allocreq';
DECLARE fl6a    NAMESPACE 'http://AllocateAssessorResponse.lgi.itso';
-- DECLARE fl4a NAMESPACE 'http://assbroker.lgi.itso';
-- DECLARE fl7a NAMESPACE 'http://assbroker.lgi.itso';
-- DECLARE f4   NAMESPACE 'http://assbroker.itso';
-DECLARE fl9    NAMESPACE 'http://broker.lgi.itso.assessrept';
Пример 9.16. Объявление пространств имен в файле common.esql
Совет. При изменении префиксов пространств имен или при редактировании файла common. esql предупреждающие сообщения могут непредсказуемым образом попадать в список задач, относящихся к нерешенным ссылкам на поля сообщений. Если перестройка всего рабочего пространства не помогает избавиться от предупреждений, закройте рабочее пространство, откройте его снова и опять полностью перестройте.

9.7.4 ESQL-код для обработки ошибок

В табл. 9.12 перечислены проверочные модули, которые нужно написать, и общий обработчик ошибок. Проверочные модули мало отличаются друг от друга.

Таблица 9.12. Проверочные ESQL-модули
ESQL-модуль Описание
Flow3_Validate "Специфичная для потока" проверка входного сообщения
Flow4a_Validate
Flow6_Validate
Flow7a_Validate
Flow8_Validate
fault_identify_fault Общий обработчик SOAP-ошибок

На примере модуля Flow3_Validate показана одна из этих процедур.

Flow3_Validate

Все проверочные процедуры строятся по одному образцу:

  1. Настройка параметров вызова процедуры ValidateMessage в папке с глобальными данными брокера Environment:
    • SOAP-сообщение, которое ожидается в Environment.Message;
    • флаг, показывающий, что сообщение-исключение задается в этом модуле, а не в общем обработчике ошибок SOAP;
    • ссылки на папки, передаваемые процедуре ValidateMessage.
  2. Вызов процедуры ValidateMessage и проверка возвращаемого флага.
    • передача Inputroot на Outputroot, если проверка проходит успешно;
    • если проверка заканчивается неудачно, генерируется исключение со специфическими данными об ошибке, которое будет перехватываться входным узлом в начале потока и передаваться в общий обработчик ошибок.

Мы используем типичное сообщение об ошибке SOAP для хранения исключения, поскольку не все WSDL, с которыми мы работаем, будут иметь интерфейс ошибок. Ошибка должна возвращаться, только если Web-служба имеет интерфейс ошибок.

В примере 9.17 показан код для проверки в потоке Flow3.

CREATE COMPUTE MODULE Flow3_Validate
  CREATE FUNCTION Main() RETURNS BOOLEAN
  BEGIN
    DECLARE xInputRoot REFERENCE TO InputRoot;
    SET Environment.Message = 'requestAssessorAvailability';
-- В следующей инструкции регистрируется факт, что Web-служба генерирует
-- свое сообщение об исключении, а не использует ошибку SOAP по умолчанию
    SET Environment.SOAP.Fault.FaultOption = 'CustomizedFault';
    DECLARE xEnvironment REFERENCE TO Environment;
-- Проверка сообщения
    CALL ValidateMessage(xInputRoot, xEnvironment);
    IF Environment.SOAP.Fault.FaultCode = ' ' THEN
      SET OutputRoot = InputRoot;
    ELSE
-- Web-служба генерирует свое сообщение об ошибке... Это оно, и за
-- ним идет путь исключения
      SET Environment.soap11:Body.Fault.faultstring =
      'Flow3 input message validation failed... claimID ' ||
      CAST(InputBody.soap11:Body.fl3:requestAssessorAvailability.fl3:
claimID AS
      CHARACTER);
      THROW USER EXCEPTION VALUES ('Flow3 Input validation failed');
    END IF;
    RETURN TRUE;
END;
Пример 9.17. ESQL-модуль Flow3_Validate
Оставшаяся часть проверочных модулей

Скопируйте код из примера Flow3_Validate и внесите изменения, показанные в табл. 9.13, в каждую из копий.

В каждой ESQL-реализации вычислительного узла Validate нужно изменить код, помеченный выше жирным шрифтом.

Таблица 9.13. Вставка переменных в процедуры проверки
Поток Сообщение Поле ClaimID
Flow3 requestAssessorAvailability fl3:requestAssessorAvailability.fl3:claimID
Flow4a assessorAvailability fl4a:assessorAvailability.fl4a:claimID
Flow6 actionAssessor fl6:actionAssessor.fl6:claimID
Flow7a assessorResponse fl7a:assessorResponse.fl7a.claimID
Flow8 receiveAssessorReport fl8:receiveAssessorReport.fl8:claimID
Fault_Identify_Fault

Модуль Fault_Identify_Fault (пример 9.18) предназначен для форматирования пакета с данными об ошибке SOAP, содержащего полезные для диагностики сведения. Модуль Main – это просто выход, если пакет уже создан. Выходные данные посылаются узлу HttpReply для возврата SOAP-клиенту, в противном случае вызывается процедура FaultProc, которая создает пакет с данными об ошибке.

CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
  IF Environment.SOAP.Fault.FaultCode = 'FaultReceived' THEN
-- Получена ошибка от другой Web-службы.... копируем данные на выход
    SET OutputRoot = InputRoot;
    ELSE
      CALL FaultProc();
    END IF;
    RETURN TRUE;
END;
Пример 9.18. Вычислительный модуль Fault_Identify_Fault – модуль Main

Процедура faultproc, приведенная в примере 9.19, содержит восемь разделов. Она компонует сведения об ошибке, в зависимости от того, какая информация об этой ошибке доступна.

CREATE PROCEDURE FaultProc()
BEGIN
-- 1. Для Web-службы требуется типичное сообщение об ошибке SOAP
  CALL CopyMessageHeaders();
  SET OutputRoot.HTTPInputHeader = null;
  SET OutputRoot.HTTPResponseHeader = null;
-- 2. Укажем подходящие значения для неопознанной ошибки в конфигура-
-- ционных данных службы
  IF Environment.SOAP.Fault.FaultCode IS NULL OR
     Environment.SOAP.Fault.FaultCode = ' '
  THEN
    SET Environment.SOAP.Fault.FaultActor ='proxyAssessorSystem';
    SET Environment.SOAP.Fault.FaultCode = 'Server';
    SET Environment.SOAP.Fault.FaultString = 'Server error in SOAP Web
        service';
  END IF;
-- 3. Создадим выходное сообщение об ошибке SOAP (MRM)
  SET OutputRoot.Properties.MessageSet = 'Assessor';
  SET OutputRoot.Properties.MessageType = 'Envelope';
  SET OutputRoot.Properties.MessageFormat = 'XML1';
-- 4. Выводится MRM-сообщение. Добавим стандартный SOAP-конверт
-- Явно добавим пространство имен к значению кода ошибки
-- Поместим в данные об ошибке тело исходного сообщения (если возмож-
-- но... )
-- 5. Web-служба требует пользовательского сообщения об ошибке
  IF Environment.SOAP.Fault.FaultOption = 'CustomizedFault' THEN
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.faultcode =
        'soap11'||':'||
        Environment.SOAP.Fault.FaultCode;
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.faultstring =
        Environment.SOAP.Fault.FaultString;
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.faultactor =
        Environment.SOAP.Fault.FaultActor;
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.detail =
        Environment.soap11:Body;
  ELSE
-- 6. Web-служба требует заданное по умолчанию сообщение об ошибке SOAP
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.faultcode = 'soap11'||':'||
        Environment.SOAP.Fault.FaultCode;
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.faultstring =
        Environment.SOAP.Fault.FaultString;
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.faultactor =
        Environment.SOAP.Fault.FaultActor;
  IF InputExceptionList.ParserException.ParserException.ParserException.
     Number=5117
  THEN
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.detail.OriginalBody =
          'Input message is not valid XML';
  ELSE
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.detail.OriginalBody =
        InputRoot.*[<];
  END IF;
-- 7. Проверяем, является ли список исключений результатом выполнения 
-- ESQL THROW...
  IF InputExceptionList.RecoverableException.RecoverableException.User-
     Exception.Number = 2951 THEN
-- 8. Если нет, выводим список исключений в сообщение об ошибке SOAP
  ELSE
    SET OutputRoot.MRM.soap11:Body.soap11:Fault.detail.ExceptionList =
        InputExceptionList;
  END IF;
  END IF;
END;
Пример 9.19. Вычислительный модуль Fault_Identify_Fault – Faultproc
Илья Макаренко
Илья Макаренко
О начале обучения
Александр Медов
Александр Медов
Здравствуйте, какова полная сумма предоставленной услуги с печатью документа и отправкой по почте?
Надежда Белякова
Надежда Белякова
Россия
Pavel Pelevin
Pavel Pelevin
Украина, Одесса