Nody HTTP

Autor: Marcin Kasiński
21.01.2011 13:24:00 +0200

Message Broker posiada nody odpowiadające za komunikacje HTTP z i do Brokera. Nody te to:

HTTPRequest

Nod ten pozwala z brokera odpytać się zewnętrznego zasobu za pomocą HTTP.

HTTPInput

Nod ten pozwala na implementacje HTTP przez broker. Oczekuje on na zapytania HTTP z zewnątrz.

HTTPReply

Nod ten jest związany z HTTPInput i pozwala na wysłanie odpowiedzi HTTP po wcześniejszym przeprocesowaniu zapytania, które dotarło do noda HTTPInput.

HTTPRequest

Najważniejsze parametry noda HTTPRequest to:

  • Web Service URLParametr ten określa URL zdalnego Web Service
  • Message DomainOkreśla domenę przy parsowaniu. Możliwe opcje to XML, XMLNS, MRM i inne.
  • Message SetJeśli domenę określimy jako MRM, w tym polu wybieramy Message Set.

Jeśli chcemy możemy wartość Web Service URL ustawić dynamicznie w kodzie :

SET OutputLocalEnvironment.Destination.HTTP.RequestURL='http://...';

HTTPInput

Najważniejsze parametry noda HTTPInput to:

  • Path suffic for URLParametr ten określa URL pod jakim oczekujemy połączeń HTTP
  • Message DomainOkreśla domenę przy parsowaniu. Możliwe opcje to XML, XMLNS, MRM i inne.
  • Message SetJeśli domenę określimy jako MRM, w tym polu wybieramy Message Set.

HTTPReply

Nod HTTPReply służy tylko i wyłącznie do wysłania odpowiedzi HTTP. Nie ma zbyt wielu opcji. Najciekawsze to te związane z timeoutami.

Scenariusze

Poniżej zebrane zostało kilka możliwych scenariuszy wykorzystania nodów w przepływie.

Scenariusze - przepływ jako WebService

W tym scenariuszu zaimplementujemy WebService na brokerze. Będzie to prosty WebService, który będzie sumował dwie liczby i zwracał ich sumę. W tym scenariuszu przepływ będzie zawierał nod HTTPInput, Compute oraz HTTPReply. Jako domenę w nodzie HTTPInput ustawiamy MRM.


	CREATE COMPUTE MODULE WebServiceInput_Compute


	DECLARE tns NAMESPACE 
	'http://www.myserver.com.pl/WSPilot/SimpleTypes';

	DECLARE soapenv NAMESPACE 
	'http://schemas.xmlsoap.org/soap/envelope/'; 



	CREATE FUNCTION processAddInt() 

	BEGIN
	
	DECLARE v1 INTEGER;

	DECLARE v2 INTEGER;

	DECLARE v3 INTEGER;
	
	SET v1=InputRoot.MRM.soapenv:Body.
	tns:addInt.tns:intPair.v1;

	SET v2=InputRoot.MRM.soapenv:Body.
	tns:addInt.tns:intPair.v2;
	
	SET v3=v1+v2;

	SET OutputRoot.MRM.soapenv:Body.tns:addIntResponse.
	tns:addIntResult.v=v3;
	
	END; 



CREATE FUNCTION Main() RETURNS BOOLEAN

	BEGIN

	CALL CopyMessageHeaders();
	
	CALL processAddInt(); 
	
	RETURN TRUE;

	END;

Scenariusze - wywołanie WebService z przepływu

Pierwszym elementem w przepływie będzie nod MQInput pobierający komunikaty MQ z kolejki. Następnie znajduje się nod Compute. W pierwszej części w module deklarujemy namespaces używane w WebService

	DECLARE tns NAMESPACE 
	'http://www.myserver.com.pl/WSPilot/SimpleTypes';

	DECLARE soapenv NAMESPACE 
	'http://schemas.xmlsoap.org/soap/envelope/'; 

Następnie deklarujemy funkcje, która przygotuje request WebService zasilając go danymi z komunikatu MQ

	CREATE FUNCTION processAddIntRequest() 

	BEGIN

	SET OutputRoot.MRM.soapenv:Body.tns:addInt.
	tns:intPair.v1= XMLNS.REQUEST.DATA.V1;

	SET OutputRoot.MRM.soapenv:Body.tns:addInt.
	tns:intPair.v2= XMLNS.REQUEST.DATA.V2;

	END;

Następnie deklarujemy główną funkcje Main, a w niej w pierwszej części kopiujemy cały komunika i ustawiamy odpowiednie parametry Properties wskazujące na używany Message Set dla wywołania WebService.

	CALL CopyEntireMessage();

	SET OutputRoot.Properties.MessageSet = 'PHTM4NG002001';

	SET OutputRoot.Properties.MessageType = 'Envelope';

	SET OutputRoot.Properties.MessageFormat = 'XML1';

	SET OutputRoot.HTTPRequestHeader.SOAPAction = 
	InputRoot.XMLNS.REQUEST.DATA.SOAPACTION;

Kolejnym krokiem jest wywołanie zadeklarowanej wcześniej funkcji processAddIntRequest, ustawienie URL WebService jaki będziemy odpytywali oraz kopiujemy cały blok MQMD do Environment.

	CALL processAddIntRequest(); 

	SET OutputLocalEnvironment.Destination.HTTP.RequestURL=
	InputRoot.XML.REQUEST.DATA.URL;

	SET Environment.myMQMD=InputRoot.MQMD;

W ten sposób przygotowaliśmy zapytanie WebServise. Następnym elementem przepływy jest nod HTTPRequest, a zaraz za nim następny nod Compute, którego celem jest interpretacja odpowiedzi. W pierwszej części w module deklarujemy ponownie namespaces używane w WebService


	DECLARE tns NAMESPACE 
	'http://www.myserver.com.pl/WSPilot/SimpleTypes';

	DECLARE soapenv NAMESPACE 
	'http://schemas.xmlsoap.org/soap/envelope/'; 

Następnie deklarujemy funkcje, która przygotuje komunikat MQ zawierający odpowiedź pobrany z WebService

	
CREATE FUNCTION processAddIntResponse() 

	BEGIN

	SET OutputRoot.XML.DATA.RESULT=

	InputRoot.MRM.soapenv:Body.tns:addIntResponse.
	tns:addIntResult.v;

	END;

Następnie deklarujemy główną funkcje Main, a w niej w pierwszej części kopiujemy cały komunika i czyścimy wcześniej ustawione odpowiednie parametry Properties wskazujące na używany Message Set dla wywołania WebService.

	CALL CopyEntireMessage();


	SET OutputRoot.Properties.MessageSet = '';

	SET OutputRoot.Properties.MessageType = '';

	SET OutputRoot.Properties.MessageFormat = '';

Dalej w funkcji Main usuwamy niepotrzebne już bloki danych HTTPRequestHeader, MRM, HTTPResponseHeader

	SET OutputRoot.HTTPRequestHeader=null;

	SET OutputRoot.MRM=null;

	SET OutputRoot.HTTPResponseHeader=null;	

W kolejnej części funkcji Main tworzymy domenę MQMD zaraz po loku Properties, kopiujemy do bloku MQMD wcześniej zapisany w Environment blok myMQMD, ustawiamy parametr MsgType na MQMT_REPLY, parametr CorrelId na podstawie wejściowego MsgId, ustawiamy cel komunikatu oraz wywołujemy wcześniej zadeklarowaną funkcje processAddIntResponse.


CREATE NEXTSIBLING OF OutputRoot.Properties DOMAIN 'MQMD';

	SET OutputRoot.MQMD=Environment.myMQMD;

	SET OutputRoot.MQMD.CorrelId=Environment.myMQMD.MsgId;

	SET OutputRoot.MQMD.MsgType=MQMT_REPLY;


	SET OutputLocalEnvironment.Destination.MQ.
	DestinationData[1].queueName=
	Environment.myMQMD.ReplyToQ;

	SET OutputLocalEnvironment.Destination.MQ.
	DestinationData[1].queueManagerName=
	Environment.myMQMD.ReplyToQMgr;

	CALL processAddIntResponse(); 

Dalej w przepływie mamy nod MQOutput ustawiony parametr Destination mode na Destination List, który wyśle odpowiedź MQ do odpowiednio zadeklarowanej wcześniej kolejki.

Scenariusze - wywołanie MQ z przepływu implementującego WebService

W tym scenariuszu na brokerze będzie zdeployowany WebService, który na podstawie danych wejściowych będzie zapytanie wysyłał do odpowiedniej kolejki MQ i z drugiej strony będzie oczekiwał na odpowiedź MQ. Po otrzymaniu odpowiedzi MQ przepływ bedzie wysyłał odpowiedz WebService. Pierwszym elementem przepływu jest nod HTTPInput, którego zadaniem jest oczekiwanie na zapytania WebService. Następnym elementem jest nod Compute, którego zadaniem jest przygotowanie komunikatu MQ. W pierwszej części w module deklarujemy ponownie namespaces używane w WebService


	DECLARE tns NAMESPACE 
	'http://www.myserver.com.pl/WSPilot/SimpleTypes';

	DECLARE soapenv NAMESPACE 
	'http://schemas.xmlsoap.org/soap/envelope/'; 

Wewnątrz tego modułu tworzymy domenę MQMD, XMSNS, kopiujemy LocalEnvironment, który zawiera identyfikator zapytania WebService RequestIdentifier, które musimy przekazać dalej oraz wskazujemy kolejkę docelową aplikacji.

	CREATE NEXTSIBLING OF OutputRoot.Properties DOMAIN 'MQMD';

	CREATE NEXTSIBLING OF OutputRoot.MQMD DOMAIN 'XMLNS';

	SET OutputLocalEnvironment.Destination.MQ.
	DestinationData[1].queueName='MQSI.MK_Q.OUT';

	SET OutputLocalEnvironment=InputLocalEnvironment;
	

Następnie usuwamy pola Properties związane z WebService, ustawiamy odpowiednie pola MQMD, tworzymy zapytanie MQ na podstawie danych wejściowych i usuwamy zbędne pola HTTPInputHeader oraz MRM.


	SET OutputRoot.Properties.MessageSet = '';

	SET OutputRoot.Properties.MessageType = '';

	SET OutputRoot.Properties.MessageFormat = '';


	SET OutputRoot.MQMD.StrucId = MQMD_STRUC_ID; 

	SET OutputRoot.MQMD.Version = MQMD_CURRENT_VERSION; 

	SET OutputRoot.MQMD.Format = MQFMT_STRING;

	SET OutputRoot.MQMD.Expiry= 300; --30 sekund

	SET OutputRoot.MQMD.ReplyToQ = 'MQSI.MK_Q.IN';


	SET OutputRoot.XMLNS.DATA.v1=InputRoot.MRM.
	soapenv:Body.tns:addInt.tns:intPair.v1;

	SET OutputRoot.XMLNS.DATA.v2=InputRoot.MRM.
	soapenv:Body.tns:addInt.tns:intPair.v2;

	SET OutputRoot.HTTPInputHeader=null;

	SET OutputRoot.MRM=null;	

Następnie w przepływie znajduje się nod MQOutput, który wysyła zapytanie do aplikacji MQ, a zaraz za nim nod Compute, którego zadaniem jest wrzucenie dodatkowego komunikatu MQ zawierającego identyfikator zapytania WebServices do kolejki. W module Compute w pierwszej częsci kopiujemy Properties, MQMD oraz wskazujemy kolejkę w której zapisywane są identyfikatory zapytania WebService.

	SET OutputRoot.Properties = InputRoot.Properties;

	SET OutputRoot.MQMD = InputRoot.MQMD;


	SET OutputLocalEnvironment.Destination.MQ.
	DestinationData[1].queueName='MQSI.MK_Q.HTTP';

Następnie ustawiamy pole CorrelId komunikaty HTTP przepisując pole MsgId z wcześniej wysłanego komunikatu do kolejki aplikacyjnej oraz tworzymy treść komunikatu zawierającego identyfikator zapytania WebService.

	SET OutputRoot.MQMD.CorrelId= 
	InputLocalEnvironment.WrittenDestination.
	MQ.DestinationData.msgId;
	
	SET OutputRoot.XMLNS.HTTP.RequestIdentifier= 
	InputLocalEnvironment.Destination.HTTP.RequestIdentifier;

Następnie mamy nod MQOutput którego zadaniem jest wrzucenie komunikatu do dedykowanej kolejki HTTP. Druga część przepływu odpowiada za odebranie komunikatu MQ odpowiedzi skorelowaniu go z komunikatem zawierającym identyfikator HTTP i wysłaniu odpowiedzi WebService do pytającego. Pierwszym elementem tej części jest nod MQInput oczekujący na kolejce w której pojawiają się odpowiedzi z aplikacji. Zaraz za nim jest nod MQGet z odpowiednio ustawionym parametrem wait interval oraz zaznaczonym polu Get By correlation ID i oczekującym na kolejce HTTP. Oznacza to, że nod pobierze z kolejki tylko komunikat którego Correlation Id jest identyczne jak Correlation Id odczytanego komunikatu odpowiedzi MQ. Jeśli aplikacja MQ ustawi Correlation Id odpowiedzi wstawiając w to miejsce message Id zapytania to nod MQGet zwróci odpowiedni komunikat HTTP. Po wyjściu z noda jeśli odczyta on komunikat procesowanie trafi do noda Compute. W pierwszej części w module znów deklarujemy namespaces używane w WebService


	DECLARE tns NAMESPACE 
	'http://www.myserver.com.pl/WSPilot/SimpleTypes';

	DECLARE soapenv NAMESPACE 
	'http://schemas.xmlsoap.org/soap/envelope/'; 



Następnie w głównej funkcji Main kopiujemy całe drzewo komunikatu, Ustawiamy odpowiednie pola Properties związane z Message Set Odpowiedzi WebService, generujemy treść odpowiedzi na podstawie odczytanego komunikatu odpowiedzi, ustawiamy odpowiednio Identyfikator zapytania WebService, z którym chcemy skorelować odpowiedź oraz usuwamy wszystko co znajduje sie wewnątrz Environment.

	SET OutputRoot.Properties = InputRoot.Properties;


	SET OutputRoot.Properties.MessageSet = 'PHTM4NG002001';

	SET OutputRoot.Properties.MessageType = 'Envelope';

	SET OutputRoot.Properties.MessageFormat = 'XML1';

	SET OutputRoot.MRM.soapenv:Body.tns:addIntResponse.
	tns:addIntResult.v=InputRoot.XMLNS.RESPONSE.DATA.V;


	SET OutputLocalEnvironment.Destination.HTTP.RequestIdentifier =
 CAST(Environment.XMLNS.HTTP.RequestIdentifier AS BLOB); 


	SET Environment= null;

Następnie przepływ kończymy nodem HTTPReply wysyłającym odpowiedź WebService.


powrót
Zachęcam do przedstawienia swoich uwag i opinii w polu komentarzy.

Komentarze

Dodaj Komentarz