Sobre a Amostra Aggregation

A amostra Aggregation demonstra uma operação de agregação simples de quatro vias que utiliza os nós AggregateControl, AggregateRequest e AggregateReply. Ela contém três fluxos de mensagens para implementar uma agregação de quatro vias: FanOut, RequestReplyApp e FanIn.

Fluxo de Mensagens FanOut

Esse fluxo toma a mensagem de pedido que chega, gera quatro mensagens de pedido diferentes, envia-as no pedido/resposta e inicia o rastreio da operação de agregação.

Fluxo FanOut de Agregação
O Terminal de controle do nó AggregateControl não está conectado e o Modo de Transação do nó MQInput é configurado para Sim. Você pode saber mais sobre as razões desse design em Estendendo a Amostra Aggregation.

O fluxo FanOut contém os nós AggregateControl e AggregateRequest, os quais são usados para iniciar o processamento de agregação. O nó AggregateControl propaga a mensagem de pedido para cada uma das quatro ramificações que estão conectadas a seu terminal de Saída (em nenhuma ordem definida). Cada ramificação possui um nó BuildRequest Compute para gerar o pedido individual. O seguinte código ESQL é utilizado no nó BuildRequest1 Compute:

CREATE COMPUTE MODULE FanOut_CreateRequest1
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
SET OutputLocalEnvironment = InputLocalEnvironment;
CALL CopyQuarter(InputRoot, OutputRoot, 0);
RETURN TRUE;
END;
END MODULE;

O procedimento CopyQuarter copia os cabeçalhos da mensagem de entrada e, em seguida, extrai um quarto dos elementos <SaleList>. No exemplo fornecido, oito elementos <SaleList> são fornecidos; cada mensagem de pedido contém dois elementos <SaleList>. O exemplo a seguir mostra o código ESQL para este procedimento:

CREATE PROCEDURE CopyQuarter(IN input REFERENCE, 							 IN
output REFERENCE, 							 IN jumps INTEGER) BEGIN 	CALL
CopyMessageHeaders(input, output); 	CREATE LASTCHILD OF output DOMAIN
'XMLNSC'; 	CREATE LASTCHILD OF output.XMLNSC NAME 'SaleEnvelope';
	DECLARE xmlIn REFERENCE TO input.XMLNSC.SaleEnvelope; 	DECLARE
xmlOut REFERENCE TO output.XMLNSC.SaleEnvelope; 	IF LASTMOVE(xmlOut)
<> TRUE THEN 		THROW USER EXCEPTION CATALOG 'BIPv610' MESSAGE
2959 VALUES ('impossível criar mensagem de saída'); 	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 'BIPv610' MESSAGE
2959 VALUES ('não divisível por 4', invoices); 	END IF;	 	 	IF jumps
> 3 THEN 		THROW USER EXCEPTION CATALOG 'BIPv610' MESSAGE 2959
VALUES ('muitos saltos', 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;

Algumas verificações iniciais sobre o status de entradas acontecem (o número dos elementos <SaleList> devem ser divisíveis por quatro e o quarto necessário é selecionado por 0, 1, 2 ou 3) antes do número apropriado dos elementos <SaleList> ser copiado a partir da mensagem de entrada na mensagem de saída.

O procedimento CopyMessageHeaders, conforme chamado no procedimento CopyQuarter, é baseado no procedimento CopyMessageHeaders de padrão fornecido, fornecido no ESQL gerado para um novo nó Compute. Para maximizar a reutilização, este procedimento CopyMessageHeaders é movido para o escopo do arquivo ESQL, sendo assim, todos os nós Compute podem chamar o mesmo procedimento.

Esse novo escopo possui uma implicação importante, necessitando de uma alteração para o procedimento. Em um nó Compute, a referência OutputRoot tem propriedades especiais que asseguram automaticamente que as informações do domínio sejam preservadas quando os elementos da árvore de mensagens forem copiados de InputRoot para OutputRoot. No entanto, nesse caso, OutputRoot é transmitido como uma referência para um procedimento externo, portanto, as informações do domínio devem ser explicitamente preservadas. Esta preservação é cumprida pela adição do comando CREATE LASTCHILD:

CREATE PROCEDURE CopyMessageHeaders(IN input REFERENCE,
IN output REFERENCE)
BEGIN
DECLARE I INTEGER 2;
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;

Após o nó BuildRequest Compute ter gerado a mensagem de pedido configurando o nó Compute para Pass LocalEnvironment and Message, ele é enviado por um nó MQOutput para a fila AGGR_SAMPLE_REQUEST. (Para simplificar este exemplo, todos os quatro pedidos são colocados na mesma fila, mas este cenário não é, provavelmente, verdadeiro para uma aplicação real.) Cada nó AggregateRequest possui um nome de pasta especificado como um parâmetro de configuração, que é usado pelo nó AggregateReply quando anexar várias respostas na mensagem de resposta agregada. O nó AggregateRequest1 usa o primeiro quarto da mensagem de entrada, o nó AggregateRequest2 usa o segundo quarto, e assim por diante.

Os nós MQOutput estão configurados para especificar AGGR_SAMPLE_REPLY como a fila ReplyTo nas mensagens de pedido, que é usado pelo fluxo de mensagens RequestReplyApp.

Após todas as quatro mensagens de resposta terem sido enviadas, o nó AggregateControl armazena o estado da agregação internamente no intermediário, como mostrado nas etapas a seguir:

Para descobrir sobre outras formas de cumprir este cenário, consulte Estendendo a amostra.

O fluxo completo deve ser feito em uma transação, com o Modo de Transação configurado para SIM no nó MQInput, porque ele será mais eficiente caso a última operação (o armazenamento do estado de operação de agregação) for concluída antes de quaisquer respostas sejam recebidas.

Fluxo de Mensagens RequestReplyApp

Utilize este fluxo para simular os aplicativos de serviço de backend que normalmente processam as mensagens de pedido da operação de agregação. Em um sistema real, estes aplicativos de serviço backend podem ser outros fluxos de mensagens ou aplicativos existentes, mas esse nível de complexidade não é necessário para a amostra Aggregation, o fluxo contém o mínimo necessário para o processamento correto de pedido/resposta. Esse fluxo lê a partir da mesma fila que os nós MQOutput no fluxo FanOut gravam, e ele envia à fila da qual o nó de entrada no fluxo FanIn lê, ela fornece uma ponte de sistema de mensagens entre os dois fluxos. As mensagens são colocadas em sua fila de resposta (conforme definido pelos nós MQOutput no fluxo FanOut).

Fluxo de Resposta
O fluxo RequestReplyApp é especificado com três instâncias adicionais no arquivo broker archive (BAR), resultando em quatro encadeamentos no total, o que garante que os quatro pedidos sejam processados o mais rapidamente possível.

Fluxo de Mensagens FanIn

Esse fluxo recebe todas as respostas a partir do fluxo RequestReplyApp, e agrega-as em uma única mensagem de saída. A mensagem de saída a partir do nó AggregateReply não pode ser enviada por um nó MQOutput, portanto, um nó Compute é incluído para ajustar os dados dentro de um formato no qual eles possam ser gravados em uma fila.
Fluxo de Fan-in de Agregação

O fluxo de mensagens FanIn também pode ter três instâncias adicionais, pelas mesmas razões do fluxo RequestReplyApp. As três primeiras respostas que chegam são armazenadas internamente pelo servidor intermediário e o estado da agregação armazenada é atualizado. Quando a quarta resposta é processada, as três respostas armazenadas são extraídas e as quatro mensagens de resposta são construídas em uma mensagem de saída. Essa mensagem não está em um estado no qual ela possa ser enviada para uma fila, portanto, o nó BuildReply Compute invoca o seguinte 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.Version = MQMD_CURRENT_VERSION;
		CREATE LASTCHILD OF OutputRoot DOMAIN 'XMLNSC'; 		CREATE LASTCHILD
OF OutputRoot.XMLNSC NAME 'ComIbmAggregateReplyBody'; 		DECLARE next
INTEGER 1; 		DECLARE repliesIn REFERENCE TO
InputRoot.ComIbmAggregateReplyBody.*[next]; 		DECLARE repliesOut
REFERENCE TO OutputRoot.XMLNSC.ComIbmAggregateReplyBody; 		WHILE next
<= 4 DO -- agregação de 4 vias 			CREATE LASTCHILD OF repliesOut
NAME FIELDNAME(repliesIn); 			SET repliesOut.*[next].ReplyIdentifier
= CAST(repliesIn.Properties.ReplyIdentifier AS CHAR); 			SET
repliesOut.*[next].SaleEnvelope = repliesIn.XMLNSC.SaleEnvelope;
			MOVE repliesIn NEXTSIBLING; 			SET next = next + 1; 		END WHILE;
		RETURN TRUE; 	END; END MODULE;

O ESQL inclui um MQMD rudimentar antes de copiar os dados de ComIbmAggregateReplyBody na mensagem de entrada para uma árvore XML na mensagem de saída, enquanto mantém os identificadores e pastas do pedido agregado. A ordem das respostas não é especificada.

Mensagem de Teste

A mensagem de teste que é utilizada para conduzir o fluxo de mensagens de agregação é uma mensagem XML que contém detalhes da fatura para um cliente. Ela contém aproximadamente 8 KB de dados, em oito elementos <SaleList> separados.

<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>

Voltar para Home da Amostra