О начале обучения |
Реализация. Создание корпоративной сервисной шины
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 приведен модуль пространств имен.
ESQL-модуль | Описание |
---|---|
common | Объявление пространств имен и префиксов |
Хорошей практикой является указание укороченных префиксов для пространств имен, используемых в коде ESQL. При этом инструкции становятся более короткими и удобными для чтения. Пространства имен будут находиться в наборе сообщений Assessor, который мы создали ранее. Если есть какие-то пропущенные или дублирующиеся префиксы, сейчас можно изменить или добавить их. Одинаковым пространствам имен нужно присваивать одинаковые префиксы. Мы соблюдали осторожность при редактировании файлов схем, чтобы все они содержали разные префиксы перед их преобразованием в наборы сообщений. Результаты можно увидеть на рис. 9.109.
В навигаторе ресурсов выберите элемент Assessor Messageset Assessor, выберите файл messageSet.mset и перейдите на закладку XML1 в редакторе набора сообщений.
Добавьте пространства имен и префиксы из каждого набора сообщений в модуль 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
9.7.4 ESQL-код для обработки ошибок
В табл. 9.12 перечислены проверочные модули, которые нужно написать, и общий обработчик ошибок. Проверочные модули мало отличаются друг от друга.
На примере модуля Flow3_Validate показана одна из этих процедур.
Flow3_Validate
Все проверочные процедуры строятся по одному образцу:
- Настройка параметров вызова процедуры ValidateMessage в папке с глобальными
данными брокера Environment:
- SOAP-сообщение, которое ожидается в Environment.Message;
- флаг, показывающий, что сообщение-исключение задается в этом модуле, а не в общем обработчике ошибок SOAP;
- ссылки на папки, передаваемые процедуре ValidateMessage.
- Вызов процедуры 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 нужно изменить код, помеченный выше жирным шрифтом.
Поток | Сообщение | Поле 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