Release 10.1A: OpenEdge Development:
Web Services

> ## Invoking a header handler

> The following procedure fragment shows how the 4GL might specify and invoke a header handler for the SOAP message described in the previous sections, in this case returned as a SOAP response message:

> Invocation of a header handler
>     /*** PROCEDURE: Start transactions on an order. ***/
>     DEFINE INPUT PARAMETER OrderNum AS INTEGER.
>     DEFINE OUTPUT PARAMETER hOrderSvc AS HANDLE.
>     DEFINE OUTPUT PARAMETER gcUUID AS CHARACTER.
>     /* Create hOrderSvc server handle and connect to order Web service. */
>     .
>     .
>     .
>     /* Create hPortType procedure handle and map port type to it. */
>     .
>     .
>     .
>     /* Set up response header handler. */
>     hPortType:SET-CALLBACK-PROCEDURE( "RESPONSE-HEADER",
>                                       "TransactionResponseHandler",
>                                       THIS-PROCEDURE ).
>     /* Start a transaction on an order. */
>     RUN startTransaction( "ORDER", OrderNum ) IN hPortType NO-ERROR.
>     .
>     .
>     .

> This fragment specifies the response header handler for an internal procedure named `TransactionResponseHandler` that is defined in the current external procedure context. Then, it invokes a `startTransaction` procedure as the first operation. As the name and parameters imply, this operation begins a transaction on the order (perhaps automatically retrieved or created, as necessary) with the specified order number.

> One can imagine that the SOAP response message returned by this operation has a header containing database object and transaction state information for the transaction that was started. Our typical SOAP message contains just such information, including an ID for the order (the `<q1:OrderInfoID>` element) and some values identifying the transaction that is managing the order (the `<t:Transaction>` element).

> The following internal procedure defines the `TransactionResponseHandler` callback procedure for the header handler. In this case, the handler locates the `<uuid>` element in the `OrderInfoID` header entry within the SOAP header referenced by the SOAP header object handle parameter, `hSOAPHeader`:

> Definition of a header handler procedure
>     /*
>     This response handler looks for a header entry named "OrderInfoID" and
>     assumes that it contains an element named "uuid". The handler saves away
>     the value of "uuid". This routine assumes that the SOAP header is no longer
>     needed after the callback completes.
>     */
>     PROCEDURE TransResponseHandler:
>       DEFINE INPUT PARAMETER hSOAPHeader AS HANDLE.
>       DEFINE INPUT PARAMETER cOperationNamespace AS CHARACTER.
>       DEFINE INPUT PARAMETER cOperationLocalname AS CHARACTER.
>       DEFINE VARIABLE hsheEntry AS HANDLE.
>       CREATE SOAP-HEADER-ENTRYREF hsheEntry IN WIDGET-POOL "soap".
>       DEFINE VARIABLE hxnTemp AS HANDLE.
>       DEFINE VARIABLE hxnWorkRoot AS HANDLE.
>       DEFINE VARIABLE hxnTemp2 AS HANDLE.
>       CREATE X-NODEREF hxnTemp IN WIDGET-POOL "soap".
>       CREATE X-NODEREF hxnTemp2 IN WIDGET-POOL "soap".
>       CREATE X-NODEREF hxnWorkRoot IN WIDGET-POOL "soap".
>       /* Walk the SOAP-HEADER's list of header entries, */
>       /* looking for the "OrderInfoID" header entry     */
>       DEFINE VARIABLE idx AS INTEGER.
>       REPEAT idx = 1 TO hSOAPHeader:NUM-HEADER-ENTRIES:
>         hSOAPHeader:GET-HEADER-ENTRY(hsheEntry, idx).
>         IF hsheEntry:LOCAL-NAME = "OrderInfoID" AND
>            hsheEntry:NAMESPACE-URI =
>                        "http://www.example.com/webservices/OrderInfo"
>         THEN DO:
>           /* Get the X-noderef side of the hsheEntry
>              so we can navigate its body.            */
>           hsheEntry:GET-NODE(hxnWorkRoot).
>           hxnWorkRoot:GET-CHILD(hxnTemp, 1). /* hxnTemp is now uuid node */
>           hxnTemp:GET-CHILD(hxnTemp2,1). /* hxnTemp2 is text node of uuid */
>           gcUUID = hxnTemp2:NODE-VALUE.  /* save the text content */
>         END.
>       END.
>       /* Delete all objects created in this procedure. */
>       DELETE WIDGET-POOL "soap".
>       /* Delete the SOAP header freeing all of its memory. */
>       DELETE OBJECT hSOAPHeader.
>     END PROCEDURE.

> It then saves the `uuid` string value to an `OUTPUT` parameter(`gcUUID`)defined globally in the calling procedure context. This is all accomplished using methods and attributes of the SOAP header object, SOAP header entry object, and x-noderef objects to access the parsed XML DOM tree of the SOAP header.

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095