Добрый день. Вопрос №1 Какова стоимость получения диплома о мини-МБА по данному курсу? Или ориентироваться на указанную на сайте? Вопрос №2 Возможно ли начать обучение без потери результатов, не отправив документы на зачисление, а отправку выполнить позже? |
Реализация. Создание корпоративной сервисной шины
9.7 Создание кода ESQL для потоков сообщений
Последний этап конфигурирования потоков сообщений в брокере – это написание ESQL-кода для вычислительных узлов. Чтобы просмотреть все созданные нами для потоков ESQL-модули, откройте свойства любого вычислительного узла и нажмите кнопку Browse (Обзор) ( рис. 9.106).
На рис. рис. 9.107 показан список ESQL-модулей, необходимых для proxyAssessorSystem, плюс модуль объявлений, common.esql.
Нам нужно написать 14 ESQL-модулей. Может показаться, что это очень много кода, но этот код делится лишь на такие четыре категории, как:
- Реализация агрегации SOAP/http, для которой 5-я версия брокера не имеет готовой поддержки (6 модулей).
- Обработка ошибок. С помощью этого кода мы пытаемся ввести несколько больше диагностической информации в стандартные средства вывода данных об ошибках (6 модулей).
- Конструирование SOAP-адреса для отправки запроса на отчет выбранному оценщику.
- Повышение удобства чтения кода путем определения префиксов пространств имен в модуле common.esql.
На рис. 9.108 приводятся 15 связующих узлов, которые выполняют большую часть посреднических функций и манипуляций с данными и не требуют написания ESQL-кода.
9.7.1 ESQL-функции, поддерживающие агрегацию
В табл. 9.10 перечислены семь ESQL-модулей, необходимых для конкретных потоков сообщений.
Flow4_PrepareMQ
В примере 9.9 входное сообщение копируется в выходную папку с удалением HTTP-заголовков и заменой их новым MQMD.
CREATE COMPUTE MODULE Flow4_PrepareMQ CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN SET OutputRoot = InputRoot; SET OutputRoot.HTTPInputHeader = null; SET OutputRoot.HTTPResponseHeader = null; CREATE NEXTSIBLING OF OutputRoot.Properties domain 'MQMD'; SET OutputRoot.MQMD.StrucId = MQMD_STRUC_ID; -- create MQMD SET OutputRoot.MQMD.Version = MQMD_CURRENT_VERSION; SET OutputRoot.MQMD.Format = ' '; SET OutputRoot.MQMD.MsgType = MQMT_DATAGRAM; RETURN TRUE; END;Пример 9.9. Flow4_PrepareMQ
Flow4_Fan_Out
В примере 9.10 представлен ESQL-код для модуля Flow4_Fan_out. Код имеет восемь частей.
Почти весь код (за исключением данных в SQL-инструкциях Insert и ссылках LocalEnvironment) сгенерирован с помощью функции автозаполнения (Autocomplete), так что этот код написать гораздо проще, чем кажется на первый взгляд.
- Объявление локальных переменных.
- Цикл while, в котором перебираются оценщики в списке оценщиков.
- Копирование InputLocalEnvironment в OutputLocalEnvironment.
- Задание пункта назначения SOAP/http в папке LocalEnvironment для динамического использования в узле HTTPRequest.
- Копирование данных сообщения-запроса к оценщику из входного сообщения в выходное сообщение.
- Передача сообщения для каждого оценщика и его папки LocalEnvironment далее по потоку сообщений.
CREATE COMPUTE MODULE Flow4_Fan_Out CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN DECLARE numberOfAssessors INTEGER CARDINALITY (InputRoot.MRM.soap11:Body. fl3:requestAssessorAvailability.fl3:assessorList.fl3:assessors[]); DECLARE assessorCount INTEGER 0; WHILE assessorCount < numberOfAssessors DO -- Эти инструкции должны быть в цикле, т.к. при передаче OutputRoot очищается CALL CopyMessageHeaders(); SET OutputLocalEnvironment = InputLocalEnvironment; SET OutputRoot.MQMD.MsgType = MQMT_REQUEST; SET OutputRoot.MQMD.ReplyToQ = 'AggIn'; SET OutputRoot.MQMD.Report = MQRO_COPY_MSG_ID_TO_CORREL_ID; SET assessorCount = assessorCount + 1; -- Адрес SOAP/Http для узла RequestHttp в качестве пункта назначения SET OutputLocalEnvironment.Destination.HTTP.RequestURL = InputRoot. MRM.soap11:Body. fl3:requestAssessorAvailability.fl3:assessorList.fl3:assessors[assessorCount]. fl3:assessorURL; -- Копирование данных сообщения из списка (f17 – синоним f14 – то же пространство имен) -- Выходные поля должны быть в том же порядке, что и элементы SET OutputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: claimID = InputRoot.MRM.soap11:Body.fl3:requestAssessorAvailability.fl3: claimID; SET OutputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: assessorID= InputRoot.MRM.soap11:Body.fl3:requestAssessorAvailability.fl3: assessorList. fl3:assessors[assessorCount].fl3:assessorID; SET OutputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: cardet. fl7:makeOfCar = InputRoot.MRM.soap11:Body.fl3:requestAssessorAvailability.fl3: makeOfCar; SET OutputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: cardet. fl7:registration = 'JB 007'; -- Fixup as the registration wasn't provided SET OutputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: location = InputRoot.MRM.soap11:Body.fl3:requestAssessorAvailability.fl3:location; SET OutputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: reqDate = InputRoot.MRM.soap11:Body.fl3:requestAssessorAvailability.fl3: requiredDate; SET OutputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: responseTime= InputRoot.MRM.soap11:Body.fl3:requestAssessorAvailability.fl3: responseTime; PROPAGATE; END WHILE; -- Все сообщения передаются явно, поэтому пустое сообщение не передается RETURN FALSE; END;Пример 9.10. Вычислительный модуль Flow4_Fan_Out
Flow4_Control_Message
Вычислительный узел Flow4_Control_Message передает выходное сообщение с терминала Control узла Aggregate Control на узел MQOutput, который помещает его в очередь, предназначенную для узла AggregateReply.
Все, что нам нужно сделать в этом модуле, – это создать сообщение WebSphere MQ и передать ему сообщение, переданное от узла Aggregate Control в виде неструктурированного XML-сообщения.
CREATE COMPUTE MODULE Flow4_PrepareMQControl CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN SET OutputRoot.MQMD.StrucId = MQMD_STRUC_ID; SET OutputRoot.MQMD.Version = MQMD_CURRENT_VERSION; SET OutputRoot.XML = InputRoot.XML; RETURN TRUE; END; END MODULE;Пример 9.11. Вычислительный модуль Flow4_PrepareMQControl
Flow4_Save_AssessorRequest
После генерации сообщения-запроса мы сохраняем запрос к оценщику в базе данных CLAIMASSESSOR, чтобы у нас было записанное узлом AggregateRequest значение msgid. Обратите внимание, что мы сохраняем URL оценщика в Local Environment.
CREATE COMPUTE MODULE Flow4_Save_AssessorRequest CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN CALL CopyEntireMessage(); SET OutputLocalEnvironment = InputLocalEnvironment; -- Сохраняем сообщение в таблице CLAIMASSESSOR INSERT INTO Database.EMERGE.CLAIMASSESSOR (claimID, assessorID, assessorURL,location, reqdate, makeofcar, registration, replytoq, replytoqmgr, correlid) VALUES ( InputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: claimID, InputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: assessorID, InputLocalEnvironment.Destination.HTTP.RequestURL, InputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: location, InputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: reqDate, InputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: cardet.fl7:makeOfCar, InputRoot.MRM.soap11:Body.fl7:requestAssessorAvailability.fl7: cardet.fl7:registration, 'NoReplytoQ', 'NoReplytoQmgr', -- Сохранение корреляционного маркера из id сгенерированного сообщения InputLocalEnvironment.WrittenDestination.MQ.DestinationData.msgId); RETURN TRUE; END;Пример 9.12. Flow4_Save_AssessorRequest
Flow3a_Prepare_Reply
Узел Flow3a_Prepare_Reply получает ответы с информацией о готовности от оценщиков. Его функция – извлечь для узла Aggregate Reply идентификатор ответа и создать сообщение-запрос WebSphere MQ, которое будет послано узлу MQ Reply для возврата реального сообщения-ответа с правильной корреляционной информацией. В примере 9.13 приводится SQL-код, решающий эти задачи.
CREATE COMPUTE MODULE Flow3a_Prepare_Reply CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN SET OutputRoot = InputRoot; SET OutputRoot.HTTPInputHeader = null; SET OutputRoot.HTTPResponseHeader = null; -- Создание MQ-сообщения-запроса – оно будет преобразовано в ответ в MQReply CREATE NEXTSIBLING OF OutputRoot.Properties domain 'MQMD'; SET OutputRoot.MQMD.StrucId = MQMD_STRUC_ID; -- create MQMD SET OutputRoot.MQMD.Version = MQMD_CURRENT_VERSION; SET OutputRoot.MQMD.Format = ' '; SET OutputRoot.MQMD.Report = MQRO_COPY_MSG_ID_TO_CORREL_ID; SET OutputRoot.MQMD.MsgType = MQMT_REPLY; -- Тот же msgid как в сообщении-запросе, сохраненном в таблице Claim- Assessor. MQReply скопирует его в correlid SET OutputRoot.MQMD.MsgId = THE (SELECT ITEM A.correlid FROM Database.EMERGE.CLAIMASSESSOR AS A WHERE A.assessorID = InputRoot.MRM.soap11:Body.fl8:assessorAvailability.fl8:assessorID AND A.claimID = InputRoot.MRM.soap11:Body.fl8:assessorAvailability.fl8:claimID); SET OutputRoot.MQMD.ReplyToQ = 'AggIn'; RETURN TRUE;Пример 9.13. Вычислительный модуль Flow3a_Prepare_Reply
Этот код очищает все HTTP-данные, создает MQMD и конфигурирует его как сообщение-запрос с исходным MsgId.
Flow3a_Generate_Output3a
Модуль Flow3a_Generate_Output3a создает результирующее сообщение Flow3a, включающее список оценщиков, возвращаемый процессу ExternalClaimAssessor.
Объединенное сообщение сохраняется в массиве ComIbmAggregateReplyBody. Flow4. По некоторым причинам нужно переустановить значение MessageSet в свойствах (Properties). Значение то же, которое мы устанавливали для всех входных папок.
CREATE COMPUTE MODULE Flow3a_Generate_Output3a CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN -- Сколько ответов получено? Папка Flow4 определена в узле Aggregate Request? DECLARE noofreplies INTEGER CARDINALITY(InputRoot.ComIbmAggregateReplyBody.Flow4[]); DECLARE replyno INTEGER 1; DECLARE assessorID INTEGER; SET OutputRoot.Properties = InputRoot.ComIbmAggregateReplyBody.Flow4.Properties; SET OutputRoot.Properties.MessageSet = 'PIJ0MIK002001'; IF noofreplies > 0 THEN SET OutputRoot.MRM.soap11:Body.fl3a:AvailableAssessorsList.claimID = InputRoot.ComIbmAggregateReplyBody.Flow4[replyno].MRM.soap11:Body.fl8: assessorAvailability.fl8:claimID; WHILE noofreplies >= replyno DO SET assessorID = InputRoot.ComIbmAggregateReplyBody. Flow4[replyno]. MRM.soap11:Body.fl8:assessorAvailability.fl8:assessorID; SET OutputRoot.MRM.soap11:Body.fl3a:AvailableAssessorsList.resultAssessor- Collection[ replyno].assessorEstimations.assessorID = assessorID; -- assessorURL отсутствует в ответе, поэтому нужно брать его из базы данных SET OutputRoot.MRM.soap11:Body.fl3a:AvailableAssessorsList.resultAssessor- Collection[ replyno].assessorEstimations.assessorURL = THE (SELECT ITEM A.assessor URL FROM Database.EMERGE.CLAIMASSESSOR AS A WHERE A.assessorID = assessorID); SET OutputRoot.MRM.soap11:Body.fl3a:AvailableAssessorsList.resultAssessorCo llection[replyno].assessorEstimations.preCost = InputRoot.ComIbmAggregateReplyBody.Flow4[replyno]. MRM.soap11:Body.fl8:assessorAvailability.fl8:predCost; SET OutputRoot.MRM.soap11:Body.fl3a:AvailableAssessorsList.resultAssessorCo llection[replyno].assessorEstimations.preDate = InputRoot.ComIbmAggregateReplyBody.Flow4[replyno]. MRM.soap11:Body.fl8:assessorAvailability.fl8:predDate; SET replyno = replyno + 1; END WHILE; RETURN TRUE; ELSE -- Не передавать сообщение, если ответов нет RETURN FALSE; END IF; END;Пример 9.14. Вычислительный модуль Flow3a_Generate_Output3a