|
Добрый день. Вопрос №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


