260 likes | 443 Vues
Handling SOAP Headers. Overview. When you complete this lesson you should be able to:. Describe what a SOAP Header is Describe some reasons for using a SOAP Header Write 4GL code to handle SOAP Headers in SOAP Request messages Write 4GL code to handle SOAP Headers in SOAP Response messages.
E N D
Overview When you complete this lesson you should be able to: • Describe what a SOAP Header is • Describe some reasons for using a SOAP Header • Write 4GL code to handle SOAP Headers in SOAP Request messages • Write 4GL code to handle SOAP Headers in SOAP Response messages
SOAP Response message with Header <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:NewCoInfo soapenv:mustUnderstand="0" xmlns:ns1="http://localhost:8080/axis/services"> <ns1:AuthCode>Progress123456789</ns1:AuthCode> </ns1:NewCoInfo> </soapenv:Header> <soapenv:Body> <ns2:SValidateCustomerResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://DefaultNamespace"> <ns2:SValidateCustomerReturn xsi:type="xsd:string">Hoops </ns2:SValidateCustomerReturn> </ns2:SValidateCustomerResponse> </soapenv:Body> </soapenv:Envelope>
SOAP Processing steps <Envelope> <Header> {contains entry or entries} </Header> <Body> <operation> {contains input parameters} </operation> </Body> <Envelope> Execute SOAP Request Handler 2 RUN operation in hPortType (… parameters …) NO-ERROR. Web service provider 3 1 4 6 <Envelope> <Header> {contains entry or entries} </Header> <Body> <operation_Response> {contains output parameters} </operation_Response> </Body> <Envelope> Execute SOAP Response Handler 5
Handling a SOAP Response <Envelope> <Body> <SValidateCustomer> {contains iCustNum} </SValidateCustomer> </Body> <Envelope> RUN SValidateCustomer in hPortType (iCustNum,c CustName) NO-ERROR. Web service provider 2 1 4 6 <Envelope> <Header> {contains AuthCode} </Header> <Body> <SValidateCustomer_Response> {contains output parameters} </SValidateCustomer_Response> </Body> <Envelope> If valid custNum, then let them have AuthCode 3 ResponseHandler: get the AuthCode 5
Coordinating use of SOAP Headers hPortType CreatePO_funclib NewCo Web service funclibID CustomerName funclibID funclibID Release_funclib hPortTypefunclib
Setting up the Response callback CREATE SERVER hServer. lReturn = hServer:CONNECT( "-WSDL http://localhost:8080/axis/services/urn:OpenEdgeServices:NewCoService2?wsdl -SOAPEndpointUserid training -SOAPEndpointPassword helps"). IF lReturn = NO THEN DO: MESSAGE "Could not connect to WebService service" VIEW-AS ALERT-BOX INFO BUTTONS OK. APPLY “CLOSE”:U TO THIS-PROCEDURE. RETURN. END. RUN NewCoService2 SET hPortType ON SERVER hServer. IF NOT VALID-HANDLE(hPortType) THEN DO: MESSAGE "Could not establish portType“ VIEW-AS ALERT-BOX INFO BUTTONS OK. APPLY “CLOSE”:U TO THIS-PROCEDURE. RETURN. END. /* set up for handling SOAP Headers */ hPortType:SET-CALLBACK-PROCEDURE("RESPONSE-HEADER","ResponseHandler").
Setting up the Request callback CREATE SERVER hServer. lResult = hserver:CONNECT(“. . ."). . . . RUN NewCoService2 SET hPortType ON SERVER hServer. . . . hPortType:SET-CALLBACK-PROCEDURE("RESPONSE-HEADER“, "ResponseHandler"). hPortType:SET-CALLBACK-PROCEDURE("REQUEST-HEADER", "RequestHandler").
Using multiple portTypes RequestHandler: Put the UUID <Envelope> <Header> { contains UUID} </Header> <Body> <CustomerName> {contains iCustNum} </CustomerName> </Body> <Envelope> 7 FUNCTION CustomerNumber RETURNS INTEGER (INPUT CHARACTER) IN hfunclibPortType.. RUN CreatePO_funclib in hPortType NO-ERROR. cCustName = CustomerName(iCustNum) NO-ERROR. Web service provider 8 2 1 4 9 <Envelope> <Header> {contains funclibID} </Header> <Body> <CustomerName_Response> {contains UUID} </CustomerName_Response> </Body> <Envelope> 6 Load the procedure library, funclib & generate UUID 10 3 ResponseHandler: get the UUID 5
Lifetime of a handler HandlerA is used only once to/from Web service HandlerA hPortType:SET-CALLBACK-HANDLER (HandlerA…). RUN OperationA in hPortType (…). hPortType:SET-CALLBACK-HANDLER (HandlerB…). RUN OperationB in hPortType (…). . . . to/from Web service HandlerB HandlerB is used for operations in hPortType until further notice
Reuse or create a SOAP Header? Saved “as is” and re-used hPortType CreatePO_funclib NewCo Web service funclibID CustomerName MyfunclibID Created by your application funclibID Release_funclib hPortTypefunclib
Saving the SOAP-HEADER for re-use DEFINE VARIABLE g_hSOAPHeader AS HANDLE NO-UNDO. . . . PROCEDURE ResponseHandler: DEFINE INPUT PARAMETER hSOAPHeader AS HANDLE NO-UNDO. DEFINE INPUT PARAMETER cLocalNamespace AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER cOperationLocalName AS CHARACTER NO-UNDO. g_hSOAPheader = hSOAPHeader. END PROCEDURE.
Re-using a SOAP-HEADER DEFINE VARIABLE g_hSOAPHeader AS HANDLE NO-UNDO. . . . PROCEDURE RequestHandler: DEFINE OUTPUT PARAMETER hSOAPHeader AS HANDLE NO-UNDO. DEFINE INPUT PARAMETER cLocalNamespace AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER cOperationName AS CHARACTER NO-UNDO. DEFINE OUTPUT PARAMETER lDeleteOnDone as LOGICAL NO-UNDO. hSOAPHeader = g_hSOAPheader. END PROCEDURE.
SOAP-HEADER:NUM-HEADER-ENTRIES SOAP-HEADER:NUM-HEADER-ENTRIES is 2 1 2
SOAP-HEADER:GET-HEADER-ENTRY DEFINE VARIABLE hHeaderEntryRef as HANDLE NO-UNDO. CREATE OBJECT hHeaderEntryRef. hSOAPHeader:GET-HEADER-ENTRY(hHE,2). hHeaderEntryRef:GET-NODE(hRoot).
Handling a Response SOAP message • Check if SOAP Header has an element • Create the X-NODEREF objects that will be used to parse the element • Create a SOAP-HEADER-ENTRYREF • Get the value of the first element in the Header • Get the root node of the first element • Parse the element and save value(s) for your application • Delete any X-NODEREF objects created to parse the element of the SOAP-HEADER-ENTRYREF
Handling a Request SOAP message • Create the X-DOCUMENT and X-NODEREF objects that will be used to create the element • Create the SOAP-HEADER object • Create a SOAP-HEADER-ENTRYREF • Add the SOAP-HEADER-ENTRYREF to the SOAP-HEADER • Create the root element and child elements of the entry • Set the node of the SOAP-HEADER-ENTRYREF to the root element • Set lDeleteOnDone (if appropriate to do) • Delete any objects created (except for SOAP-HEADER object)
Summary You should now be able to: • Describe what a SOAP Header is • Describe some reasons for using a SOAP Header • Write 4GL code to handle SOAP Headers in SOAP Request messages • Write 4GL code to handle SOAP Headers in SOAP Response messages