Aggregation 샘플은 Aggregate Control, Request 및 Reply 노드를 사용하는 단순한 네 가지 방법의 집계 조작을 예시합니다. 이 샘플은 네 가지 방법의 집계를 구현하는 세 개의 메시지 플로우인 FanOut, RequestReplyApp 및 FanIn을 포함합니다.
이 플로우는 수신되는 요청 메시지를 가져오고 네 개의 서로 다른 요청 메시지를 생성하며 이들 메시지를 요청/응답에 송신하고 집계 조작의 추적을 시작하는 플로우입니다.
AggregateControl 노드의 Control 터미널이 연결되어 있지 않으며 MQInput 노드의 트랜잭션 모드가
예로 설정되어 있는 점에 유의하십시오. Aggregation 샘플 확장에서 이 설계의 이유에 대해 자세히
알아볼 수 있습니다.
FanOut 플로우에는 Aggregate Control 및 Request 노드가 들어 있으며, 이들 노드는 집계 처리를 시작하는 데 사용됩니다. Aggregate Control 노드는 해당 Out 터미널로 연결된 네 개의 각 분기로 요청 메시지를 전달합니다(순서는 정의되지 않음). 각 분기에는 개별 요청을 생성하기 위한 "BuildRequest" Compute 노드가 있습니다. BuildRequest1 Compute 노드에서 다음 ESQL이 사용됩니다.
CREATE COMPUTE MODULE FanOut_CreateRequest1
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
SET OutputLocalEnvironment = InputLocalEnvironment;
CALL CopyQuarter(InputRoot, OutputRoot, 0);
RETURN TRUE;
END;
END MODULE;
CopyQuarter 프로시저는 입력 메시지로부터 메시지 헤더를 복사한 후 <SaleList> 요소의 4등분 중 하나를 추출합니다. 제공된 예에서는 8개의 <SaleList> 요소가 있어 각 요청 메시지는 이들 요소 중 두 개를 포함하게 됩니다. 이 프로시저에 대한 ESQL은 다음과 같습니다.
CREATE PROCEDURE CopyQuarter(IN input REFERENCE,
IN output REFERENCE,
IN jumps INTEGER)
BEGIN
CALL CopyMessageHeaders(input, output);
CREATE LASTCHILD OF output DOMAIN 'XML';
CREATE LASTCHILD OF output.XML NAME 'SaleEnvelope';
DECLARE xmlIn REFERENCE TO input.XML.SaleEnvelope;
DECLARE xmlOut REFERENCE TO output.XML.SaleEnvelope;
IF LASTMOVE(xmlOut) <> TRUE THEN
THROW USER EXCEPTION CATALOG 'WMQIv600' MESSAGE 2949 VALUES ('could not create output message');
END IF;
DECLARE invoices INTEGER CAST (xmlIn.Header.SaleListCount AS INTEGER);
DECLARE quarter INTEGER invoices/4;
IF invoices <> (quarter*4) THEN
THROW USER EXCEPTION CATALOG 'WMQIv600' MESSAGE 2949 VALUES ('not divisible by 4', invoices);
END IF;
IF jumps > 3 THEN
THROW USER EXCEPTION CATALOG 'WMQIv600' MESSAGE 2949 VALUES ('too many jumps', jumps);
END IF;
DECLARE count INTEGER 1;
DECLARE copyRef REFERENCE TO xmlIn.SaleList[(jumps*quarter)+count];
WHILE count <= quarter DO
SET xmlOut.SaleList[count] = copyRef;
MOVE copyRef NEXTSIBLING;
SET count = count + 1;
END WHILE;
END;
입력 메시지에서 출력 메시지로 적절한 수의 <SaleList> 요소가 복사되기 전에 입력 상태에 대한 초기 확인이 필요합니다. (<SaleList> 요소의 수는 4등분으로 나뉘어져야 하며, 필요한 4등분은 0, 1, 2 또는 3으로 선택됩니다.)
CopyMessageHeaders 프로시저는 CopyQuarter 프로시저에서 호출될 때 새 Compute 노드를 위해 생성된 ESQL에 제공된 표준 CopyMessageHeaders 프로시저를 기초로 합니다. 최대한 재사용하기 위해 ESQL 파일의 범위로 옮겨졌으며 모든 Compute 노드가 동일한 프로시저를 호출할 수 있게 되었습니다.
이렇게 범위를 다시 지정하는 것은 중요한 영향을 미치며 프로시저를 변경할 필요가 있습니다. Compute 노드에서 OutputRoot 참조는 InputRoot에서 OutputRoot로 메시지 트리 요소가 복사될 때 도메인 정보가 보존되는지 자동으로 확인하는 특별한 등록 정보를 포함하고 있습니다. 그러나 이 경우, OutputRoot가 참조로서 외부 프로시저에 전달되므로 도메인 정보는 명시적으로 보존되어야 합니다. 다음 CREATE LASTCHILD 명령을 추가하여 이를 수행할 수 있습니다.
CREATE PROCEDURE CopyMessageHeaders(IN input REFERENCE,
IN output REFERENCE)
BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER CARDINALITY(input.*[]);
WHILE I < J DO
CREATE LASTCHILD OF output DOMAIN FIELDNAME(input.*[I]); -- preserve domain information
SET output.*[I] = input.*[I];
SET I = I + 1;
END WHILE;
END;
"BuildRequest" Compute 노드는 Compute 노드를 로컬 환경 및 메시지 전달로 설정하여 요청 메시지를 생성한 후, MQOutput 노드에 의해 AGGR_SAMPLE_REQUEST 큐로 출력됩니다. (이 샘플에서는 간단하게 하기 위해 네 개의 요청을 모두 동일한 큐에 넣었지만 실제 응용프로그램에서는 현실적이지 않을 수 있습니다.) 각 Aggregate Request 노드에는 Aggregate Reply 노드가 집계된 응답 메시지에 여러 응답을 추가할 때 사용하는 구성 매개변수로서 FolderName이 지정되어 있습니다. "Request1"은 입력 메시지의 첫 번째 4등분을 사용하고 "Request2"는 두 번째 4등분을 사용하며 나머지 요청도 계속 이와 같이 사용합니다.
MQOutput 노드는 GGR_SAMPLE_REPLY를 요청 메시지의 ReplyTo 큐로 지정하도록 설정되었으며, 이는 RequestReplyApp 메시지 플로우에서 사용됩니다.
네 개의 요청 메시지가 모두 출력되면 Aggregate Control 노드는 집계의 상태를 내부적으로 브로커에 저장합니다. 이를 수행하기 위한 단계는 다음과 같습니다.
다른 방법으로 이를 수행할 수도 있습니다. 자세한 정보는 샘플 확장을 참조하십시오.
이 전체 플로우는 MQInput 노드에서 transactionMode가 YES로 설정된 트랜잭션 하에서 수행되어야 하는데, 이는 응답이 수신되기 전에 마지막 조작(집계 조작 상태 저장)이 완료될 경우 가장 효율적이기 때문입니다.
집계 조작으로부터 요청 메시지를 정상 처리하는 백엔드 서비스 응용프로그램을 시뮬레이션하는 데 이 플로우를 사용합니다. 실제 시스템에서 이는 다른 메시지 플로우 또는 기존 응용프로그램일 수 있지만 Aggregation 샘플에 이렇게 복잡한 레벨은 필요하지 않으므로 플로우는 올바른 요청/응답 처리에 필요한 최소 레벨만 포함합니다. 이 플로우는 FanOut 플로우에서 MQOutput 노드가 쓰는 동일한 큐에서 읽고 FanIn 플로우에서 입력 노드가 읽어오는 큐로 출력합니다. 그리고 두 개의 플로우 사이에 메시징 브릿지를 제공합니다. 메시지는 리플라이-투 큐(FanOut 플로우의 MQOutput 노드에 의해 설정된)로 넣어집니다.
RequestReplyApp 플로우는 bar 파일에서 세 개의 추가 인스턴스와 함께 지정되어 총 네 개의 스레드가 됩니다. 이는 모두 네 개의 요청이 가능한 신속하게 처리되도록 합니다.
이 플로우는 RequestReplyApp 플로우에서 모든 응답을 수신하여 이들 응답을 단일 출력 메시지로 집계합니다. Aggregate Reply 노드의 출력 메시지는 MQOutput 노드에 의해 출력될 수 없으므로
데이터를 큐에 쓸 수 있는 형식으로 개조하기 위해 Compute 노드가 추가됩니다.
FanIn 메시지 플로우 또한 RequestReplyApp 플로우와 동일한 이유로 세 개의 추가 인스턴스를 가지고 있습니다. 브로커가 처음 세 개의 수신되는 응답을 내부적으로 저장하고 저장된 집계 상태는 갱신됩니다. 네 번째 응답이 처리될 때 이들 세 개의 저장된 응답이 추출되어 모두 네 개의 응답 메시지가 출력 메시지에 빌드됩니다. 이 메시지는 큐로 출력될 수 있는 상태가 아니므로 "BuildReply" Compute 노드는 이를 수정하기 위해 다음 ESQL을 호출합니다.
CREATE COMPUTE MODULE FanIn_BuildReply
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
SET OutputRoot.Properties = InputRoot.Properties;
CREATE NEXTSIBLING OF OutputRoot.Properties DOMAIN 'MQMD';
SET OutputRoot.MQMD.StrucId = MQMD_STRUC_ID;
SET OutputRoot.MQMD.Version = MQMD_CURRENT_VERSION;
CREATE LASTCHILD OF OutputRoot DOMAIN 'XML';
CREATE LASTCHILD OF OutputRoot.XML NAME 'ComIbmAggregateReplyBody';
DECLARE next INTEGER 1;
DECLARE repliesIn REFERENCE TO InputRoot.ComIbmAggregateReplyBody.*[next];
DECLARE repliesOut REFERENCE TO OutputRoot.XML.ComIbmAggregateReplyBody;
WHILE next <= 4 DO -- 4-way aggregation
CREATE LASTCHILD OF repliesOut NAME FIELDNAME(repliesIn);
SET repliesOut.*[next].ReplyIdentifier = CAST(repliesIn.Properties.ReplyIdentifier AS CHAR);
SET repliesOut.*[next].SaleEnvelope = repliesIn.XML.SaleEnvelope;
MOVE repliesIn NEXTSIBLING;
SET next = next + 1;
END WHILE;
RETURN TRUE;
END;
END MODULE;
이 ESQL은 집계 요청 ID 및 폴더를 유지보수하면서 입력 메시지의 ComIbmAggregateReplyBody에서 출력 메시지의 XML 트리로 데이터를 복사하기 전에 기본 MQMD를 추가합니다. 응답의 순서는 지정되어 있지 않습니다.
집계 메시지 플로우를 구동시키는 데 사용되는 테스트 메시지는 고객의 송장 세부사항이 들어 있는 간단한 XML 메시지입니다. 이 메시지에는 8개의 개별 <SaleList> 요소로 대략 8KB의 데이터가 들어 있습니다.
<SaleEnvelope>
<Header>
<SaleListCount>8</SaleListCount>
</Header>
<SaleList>
<Invoice>
<Initial>K</Initial><Initial>A</Initial>
<Surname>Braithwaite</Surname>
<Item><Code>00</Code><Code>01</Code><Code>02</Code>
<Description>Twister</Description>
<Category>Games</Category>
<Price>00.30</Price><Quantity>01</Quantity>
</Item>
<Item><Code>02</Code><Code>03</Code><Code>01</Code>
<Description>The Times Newspaper</Description>
<Category>Books and Media</Category>
<Price>00.20</Price><Quantity>01</Quantity>
</Item>
<Balance>00.50</Balance><Currency>Sterling</Currency>
</Invoice>
<Invoice>
<Initial>T</Initial><Initial>J</Initial>
<Surname>Dunnwin</Surname>
<Item><Code>04</Code><Code>05</Code><Code>01</Code>
<Description>The Origin of Species</Description>
<Category>Books and Media</Category>
<Price>22.34</Price><Quantity>02</Quantity>
</Item>
<Item><Code>06</Code><Code>07</Code><Code>01</Code>
<Description>Microscope</Description>
<Category>Miscellaneous</Category>
<Price>36.20</Price><Quantity>01</Quantity>
</Item>
<Balance>81.84</Balance><Currency>Euros</Currency>
</Invoice>
</SaleList>
<SaleList>....</SaleList>
<SaleList>....</SaleList>
<SaleList>....</SaleList>
<SaleList>....</SaleList>
<SaleList>....</SaleList>
<SaleList>....</SaleList>
<SaleList>....</SaleList>
<Trailer>
<CompletionTime>12.00.00</CompletionTime>
</Trailer>
</SaleEnvelope>