Try OpenEdge Now
skip to main content
Web Services
Creating ABL Clients to Consume OpenEdge SOAP Web Services : Handling SOAP Message Headers in ABL : Invoking a header handler
 

Invoking a header handler

The following procedure fragment shows how ABL 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.
Assume the SOAP response message returned by this operation has a header containing database object and transaction state information for the transaction that was started. The example SOAP message, in SOAP header structure, 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. 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:

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.