Web Services Addressing (WS-Addressing) is a newly supported standard in IBM® WebSphere® CICS® Transaction Server (TS) V4.1. Web service applications can use this standard to take advantage of new message exchange patterns, transport-neutral addressing, and reference properties. In this article, you'll look at a simple franchise business scenario that illustrates the new WS-Addressing support, and learn how to implement a WS-Addressing SOA application using the CICS WS-Addressing APIs.
- Development environment
- Platform: CICS TS V4.1 on z/OS
- Programming language: COBOL
- CICS Web service-related concepts
- Resources that CICS uses to support Web services, including PIPELINE, URIMAP, WEBSERVICE, and TCPIPSERVICE. With these resources, you can define the process that enables a Web service to run on CICS.
- Web Service Assistant tool DFHWS2LS, which supports COBOL, PL/I, C, and C++ on CICS TS V4.1. DFHWS2LS is used to create language structures from WSDL and to produce the WSBind file that CICS requires to process service requests and responses.
- CICS APIs that support Web services, such as INVOKE SERVICE.
- CICS APIs that support WS-Addressing, including WSACONTEXT BUILD, WSACONTEXT GET, WSACONTEXT DELETE, and WSAEPR CREATE.
- WS-Addressing Context -- a data area that is used to hold WS-Addressing MAPs constructed via the WSACONTEXT API, or by the DFHWSADH pipeline header handler from the MAPs
held in the SOAP header during a request or received response. WSACONTEXTs can be built, interrogated, and deleted via the WSACONTEXT API functions
BUILD,GET, andDELETE. During an outbound request or response, the WSACONTEXT is used to populate the SOAP header.
WS-Addressing provides a standard framework for specifying the endpoints of a SOAP message. This framework is transport-neutral and improves interoperability between Web services by defining a standard way to address these services and to provide addressing information in SOAP messages. SOAP messages can be sent over a variety of transport mechanisms, including HTTP and WMQ, each of which stores destination information for the message in a different way. The WS-Addressing specification introduces message addressing properties (MAPs) and endpoint references (EPRs), which are the core concepts of WS-Addressing.
Message addressing properties are a set of well-defined WS-Addressing properties that can be represented as elements in SOAP headers. MAPs provide a standard way of conveying a variety of information -- the endpoint to which message replies must be directed, for instance, or information about the relationship that the message has with other messages.
The MAPs are: To, Action, From, ReplyTo, FaultTo, MessageID, and RelatesTo. From, ReplyTo, and FaultTo are EPRs (more on which momentarily), and To is a URI address in the SOAP header and an EPR in the WS-Addressing Context. MessageID and RelatesTo are universally unique identifiers (UUIDs), and Action is a string.
An endpoint reference is a specific type of MAP that provides a standard mechanism to encapsulate information about specific endpoints. Endpoint references can be sent to other parties and used to target the Web service endpoint that they represent. Thus, EPRs can be used to propagate information between a service and its clients -- an ability that's exploited in this tutorial. An EPR can contain a URI address, reference parameters, and metadata to describe the EPR.
WS-Addressing is a core Web service specification that is employed by other specifications, including WS-RM (Reliable Messaging) and WS-AT (Atomic Transactions). It provides a number of advantages to an SOA application:
- It makes transport-neutral addressing possible, which means that endpoint locations are no longer tied to the transport mechanisms that reach them.
- Endpoint references encapsulate the address of the endpoint, the parameters required on a request, and the metadata of the endpoint. This allows parameters to be passed to, but not tied to, the transport.
- New message exchange patterns can be constructed using asynchronous exchanges.
- Responses can be routed according to response type: normal or fault.
- Messages can be related to other messages.
WS-Addressing support in CICS TS V4.1
CICS supports the following recommendation specifications:
- W3C WS-Addressing 1.0 -- Core
- W3C WS-Addressing 1.0 -- SOAP Binding
- W3C WS-Addressing 1.0 -- Metadata
These specifications are identified by the http://www.w3.org/2005/08/addressing namespace. For interoperability, CICS also supports the following submission specification:
- W3C WS-Addressing -- Submission. This specification is identified by the
http://schemas.xmlsoap.org/ws/2004/08/addressingnamespace.
For more information on all of these specifications. see the Resources section below.
Use the submission specification only if you must interoperate with a client or Web service provider that only implements the submission specification.
CICS provides WS-Addressing support via a new pipeline handler, DFHWSADH, and new CICS APIs, WSACONTEXT and WSAEPR. You will see how these are set up and used in the sample application.
The DFHWS2LS utility recognizes WS-Addressing WSDL extensions and stores any WS-Addressing data in the WS-Bind files.
For more information on these topics, see the CICS TS V4.1 information center.
Overview of sample application
Franchising is a business model in which a company lets other companies use its business model and marketing initiatives. The franchisee company pays an initial fee and monthly fees based on revenues. The parent company also provides the franchisee with training to ensure that the franchisee conforms to the business model.
Our scenario involves a fictitious company called Acme Garden Structures (AGS), a multinational supplier of garden buildings such as sheds, summer houses, and log cabins. The main selling outlet for AGS is the Web, backed by marketing in individual countries. The garden structures that AGS produces are not manufactured in one place. Instead, to reduce transport costs, AGS uses the franchise model, producing the specification of the garden structures that many franchises around the world build and deliver to local customers. All stages of the order process are tracked so that a customer can log in to the AGS Website and view their order status.
Franchisee systems can be implemented on any Web services platform supporting WS-Addressing. In this tutorial, AGS systems are implemented in CICS. The sample franchisee systems are also implemented in CICS, but in a real-world setup the franchisee system implementations would be varied; which is when the power of SOA comes to the fore.
The AGS application is implemented as an SOA application, enabling it to interact with many heterogeneous franchisee systems. The AGS application exposes four Web services: AGSOrder, AGSConfig, AGSProblemResolution, and AGSTracking. The franchise applications (AGSFranchise) each expose a single Web service in accordance with AGS WSDL. The overall architecture is illustrated in Figure 1:
Figure 1. System architecture

Here are descriptions of the Web services:
- AGSOrder: Accepts orders and to queries existing orders. In accepting an order, AGSOrder uses AGSConfig to locate a suitable franchise to satisfy the order. Using the franchise's EPR, the order is placed with the franchise service AGSFranchise.
- AGSConfig: Accepts and stores franchisee details, including the types of garden structures they produce, and, most importantly, an EPR containing details on how to call the franchise's AGSFranchise service. The service is also used to find franchises that can satisfy an order.
- AGSTracking: Finds the current status of an order and also accepts status updates. As an order progresses, the franchisee service AGSFranchise sends order update messages.
- AGSProblemResolution: Accepts faults that can occur in the ordering and production stages and returns an ordered list of faults to be resolved.
- AGSFranchise: Accepts orders from AGSOrder. The service's responses are directed to the AGSTracking service. The service also calls the AGSTracking service to update the status of an order as the order progresses.
- Client: The client application is a simple test program that drives AGSOrder.
Using WS-Addressing in this scenario allows AGSOrder to dynamically select the franchise system with which it will place an order, and to use a pre-registered EPR to call the franchise Web service, passing an order number as a reference parameter. The transports to the franchise systems can be a mix of HTTP and WMQ. The overall system operates as follows:
- A customer browses the AGS online catalog and places an order. (In this tutorial, a simple client is used to simulate this function.)
- The order is sent to AGSOrder, which uses the customer's address and requirements to select a suitable franchise from AGSConfig.
- Using AGSConfig, the selected franchise's order system EPR is sought. The franchises register their order services' EPR with the config service periodically. This EPR details how to contact the franchisee using the Address element and may include some fixed reference parameters relevant to the franchise.
- The AGS system constructs a ReplyTo EPR for its order tracking service.
- The To, ReplyTo, and FaultTo EPRs are updated with the AGS order number as a reference parameter. This identifies all messages as pertaining to a particular order.
- A WS-Addressed order request is made to the selected franchise with the WS-Addressing MAPs placed in the SOAP header.
- The franchise accepts the order and replies using the ReplyTo EPR that the order has been accepted.
- At all stages of the order, the ReplyTo EPR is used to send order updates to the AGS order tracking service. As a result, the franchisee system stores the EPR for later use.
- Problems may occur with the order as a result of technical difficulties, supply constraints, or other issues. In such a case, an assured message is sent to the problem resolution service (PRS). Customer representatives use the PRS to investigate and resolve the problem with the franchise.
- Customers can view their order status through a submit request from the AGS online Website.
Figure 2 illustrates the complete flow of order information within the application:
Figure 2. Order flow

Designing Web services interfaces in WSDL
The AGS application consists of five services: AGSOrder, AGSConfig, AGSTracking, AGSFranchise, and AGSProblemResolution. In this tutorial, the implementation of the AGSProblemResolution service is left as an exercise for the reader. To implement the AGS application, you need to determine the interfaces of each service and construct WSDL for each. Here is a chart of the information flow within the application:
Figure 3. Detailed flowchart

The application walks through the following steps:
- Franchise services (FS) register their own EPRs with AGSConfig.
- AGSConfig responds to confirm that the registration was successful.
- A customer uses the AGS Website to place an order. The Website calls the AGSOrder service
placeOrder, passing along theName,Address,Structure, andColor. - AGSOrder returns an order number.
- AGSOrder uses the customer's
AddressandStructureto find a franchise using AGSConfig (locateFranchiseEPR). - AGSConfig returns the EPR.
- AGSOrder uses the returned EPR to address the FS and call
processOrder. The order number is used as a reference parameter. - The FS replies to AGSTracking (
trackOrderStatus) with either an order accepted status or a fault status. - If an FS has a system fault, then a fault message is sent to AGSProblemResolution
registerProblemvia the FaultTo EPR. If an application fault occurs (for example, if a structure cannot be built), FS generates a fault and sends it to AGSProblemResolution via the FaultTo EPR. - The FS stores the FaultTo EPR like the ReplyTo EPR. If at any time a problem occurs with the order, the AGSFranchise service can call
AGSProblemResolutionwith the order problem using the FaultTo EPR as its To destination. - For an accepted order, the order status is checked.
- The FS system periodically sends a one-way request to the AGSTracking
trackOrderStatus(using the ReplyTo EPR as a To EPR) with a status update at significant times (structure built, structure delivered, etc.). The EPR contains a reference parameter with the order number to identify the order. - The status of the order is returned from AGSTracking to AGSOrder.
- The customer requests the status of the order via the Website, which calls AGSOrder
trackOrder.trackOrdercreates a WS-Addressed call to AGSTrackinggetOrderTracking. The response is returned to the customer via AGSOrder.
From these steps, you will need the following methods and parameters:
- AGSConfig:
registerFranchise REQ(Franchise, Geography, Structure, EPR)locateFranchiseEPR REQ(Geography, Structure) RESP(Franchise, EPR)- AGSOrder, called via the AGS Website:
placeOrder REQ(Customer Name, Structure, Color, Geography) RESP(Order number)trackOrder REQ(Order number) RESP(Date, status)- AGSFranchise:
processOrder REQ(Customer Name, Structure, Color, Geography) RESP(Date, Status) RefParam=OrderNumber ReplyTo=AGSTracking FaultTo=AGSProblemResolutionupdateOrderStatus REQ(Order number, Date, Status)(called by franchisee systems)- AGSTracking:
trackOrderStatus REQ(Date, Status) RefParam=OrderNumbergetOrderTracking REQ(order number) RESP(Date, Status)- AGSProblemResolution:
problem REQ(SOAPFault)-- This interface is left for the reader to implement.
You must use WSDL files to describe the Web services and their interfaces. These files use WS-Addressing metadata extensions to provide WS-Addressing actions to the request messages. The WS-Addressing action MAP is similar to the SOAP action and denotes the action that the Web service must perform. In order to use WS-Addressing metadata, the
http://www.w3.org/2005/08/addressing schema must be imported. The WSDL snippet in Listing 1 shows the WS-Addressing WSDL metadata action:
Listing 1. WSDL segment
<input message="ags:registrationMsg" wsam:action=
"http://ags.example.ibm.com/registerEPR"/>
...
<input message="ags:locateEPRReqMsg" wsam:action=
"http://ags.example.ibm.com/locateEPR"/>
|
Here, wsam:action defines the actions that the service is expecting from the SOAP message header, and the operations that the service will take when it receives an action.
For a complete description of the WSDL, Download WSADEMO.zip at the bottom of the article and unzip it to see the WSDL files AGSOrderService, AGSConfigService, AGSTrackingService, and AGSFranchiseService. In the next few sections, you will create each of the Web services in the sample application.
Creating the AGSOrder service: Overview
To create the ASGOrder service, begin by establishing the service logic. AGSOrder is the core of the whole AGS IT system and accepts the request sent from the client. There are two kinds of request:
placeOrder and trackOrder. Here is the program flowchart for the service:
Figure 4. AGSOrder flowchart

AGSOrder uses the WSACONTEXT API to get the Action MAP sent from the client. During the execution of the Web service pipeline, the WS-Addressing header handler, DFHWSADH, processes the MAPs in the SOAP header and places them in a data area called the WS-Addressing Context or WSACONTEXT. The WSACONTEXT API can be used to interrogate the context and return MAPs sent by the caller.
If the Action is placeOrderReq, the program gets the input parameters from the container. There are four parameters: name,
structure, color, and geography. AGSOrder sends these parameters to AGSConfig to find a suitable franchise to satisfy the order. Getting the returned EPR of the franchise, AGSOrder uses the EPR to build a To EPR and construct a ReplyTo EPR using the AGSTracking service EPR. The To, ReplyTo, and FaultTo EPRs are updated with the order number.
In the WS-Addressing core specification, the To MAP is of type URI and contains a simple URI address, and reference parameters are held separately in the SOAP header. But in the WSACONTEXT, the To MAP is stored as an EPR containing the address and the reference parameters.
If the Action is trackOrderReq, the program gets the input parameters from the container. There is only one parameter: OrderNumber. AGSOrder passes the order number to AGSTracking and gets the order status.
Creating the AGSOrder service: Detailed steps
Using DFHWS2LS (JCL DFHORDP and DFHORDR), process AGSOrderService.wsdl to create the WSBind files required by CICS to process the requests and responses, along with the COBOL copybooks for the AGSOrder service. This process generates the copybooks in Listings 2 through 5:
Listing 2. AGSORP01
03 placeOrderReq. 06 name PIC X(256). 06 structure PIC X(256). 06 color PIC X(256). 06 geography PIC X(256). |
Listing 3. AGSORP02
03 trackOrderReq. 06 orderNumber PIC X(256). |
Listing 4. AGSORQ01
03 placeOrderResp. 06 orderNumber PIC X(256). |
Listing 5. AGSORQ02
03 trackOrderResp. 06 orderDate PIC X(256). 06 orderStatus PIC X(256). |
After the language structures are produced, the AGSOrder service can be written as the program AGSORDER. The key elements of the program are shown in the next few listings.
Listing 6 contains the main line of AGSOrder. AGSOrder can take one of two operations, as determined by the Action parameter in the request WSACONTEXT:
one is placeOrder and the other is TrackOrderStatus:
Listing 6. AGSOrder main line
A-MAIN-PROCESSING SECTION.
* Initialise any variables and information
PERFORM B010-INIT-PROC.
* Get Action from the WSACONTEXT
PERFORM C010-GET-REQUEST-ACTION.
* If the client sends a placeorder request
IF ACTION-OPTION(1:40) = ACTION-PLACEORDER
THEN
PERFORM C020-GET-REQUEST-ORDER-DATA
PERFORM C030-FORWARD-ORDER-REQUEST
PERFORM C040-PUT-ORDER-NUMBER
ELSE
* If the client sends a trackorder request
IF ACTION-OPTION(1:40) = ACTION-TRACKORDER
PERFORM C050-GET-REQUEST-ORDER-STATUS
PERFORM C060-GET-ORDER-STATUS
PERFORM C070-PUT-ORDER-STATUS
ELSE PERFORM X-GENERIC-ABEND
END-IF
END-IF.
A-MAIN-PROCESSING-EXIT.
GOBACK.
|
Use the ASSIGN CHANNEL command shown in Listing 7 to get the name of the current channel the Web service is using for later use:
Listing 7. ASSIGN CHANNEL
B010-INIT-PROC.
* Initialise any variables and information
EXEC CICS ASSIGN
CHANNEL(CURRENT-CHANNEL)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the WSACONTEXT GET command shown in Listing 8 in a service provider to get the MAPs sent by the service requester.
ACTION specifies an output area to contain the Action MAP of the request. REQCONTEXT specifies that the program is to fetch the MAPs from the addressing context containing the request that is created by the pipeline header handler from MAPs in the SOAP header:
Listing 8. WSACONTEXT GET
C010-GET-REQUEST-ACTION.
* Retrieve the action value from WSACONTEXT with WS-A API
EXEC CICS WSACONTEXT GET REQCONTEXT
ACTION(ACTION-OPTION)
RESP(resp)
RESP2(resp2)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the GET CONTAINER command shown in Listing 9 to retrieve data from a named channel container. PI-DFHWS-DATA is the container that holds the top-level data structure that is mapped to and from a SOAP request. WORKING-ROOT-DATA1 is the high-level language data structure:
Listing 9. GET CONTAINER
C020-GET-REQUEST-ORDER-DATA.
* Retrieve the content of root container of the request
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(WORKING-ROOT-DATA1)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the PUT CONTAINER command shown in Listing 10 to place the structure type and geography in the named channel container, PI-DFHWS-DATA.
The CHANNEL parameter is the channel name to which the container belongs. You must use a different channel here to distinguish the inbound channel and the outbound channel, so the inbound and outbound data will not be confused:
Listing 10. PUT CONTAINER
C030-FORWARD-ORDER-REQUEST.
* Locate a franchise and forward the order request to it
MOVE STRUCTURE OF WORKING-ROOT-DATA1
TO structure OF locateEPRReq.
MOVE GEOGRAPHY OF WORKING-ROOT-DATA1
TO geography OF locateEPRReq.
EXEC CICS PUT CONTAINER(PI-DFHWS-DATA)
CHANNEL(OUTBOUND-CHANNEL)
FROM(locateEPRReq)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the WSACONTEXT BUILD command shown in Listing 11 to insert or replace WS-Addressing MAPs in the addressing context. CHANNEL specifies the name of the channel that is holding the addressing context. TOEPR is the destination EPR to which the SOAP message is sent. The Address field of the endpoint reference is specified as a URI in the EPRFROM option. EPRFROM is an input data value that contains a complete or partial endpoint reference that is to be placed in the addressing context. In this case, you supply the URI of the AGSConfig service:
Listing 11. WSACONTEXT BUILD
* Construct the TO EPR in the WSACONTEXT using WSA API
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
TOEPR
ADDRESS
EPRFROM(AGSCFGURI)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the INVOKE SERVICE command shown in Listing 12 to call a service from a CICS application. SERVICE specifies the name of the service.
CHANNEL specifies the name of the channel that is used to pass the containers that hold the data mapped by the application data structure. On return, the same channel holds the response from the Web service. OPERATION specifies a data area that contains the name of the operation that is to be invoked.
The name of the operation is contained in the WSDL for the target Web service:
Listing 12. INVOKE SERVICE
* Invoke AGSCFG Service
EXEC CICS INVOKE
SERVICE(AGSCFGSERVICE)
CHANNEL(OUTBOUND-CHANNEL)
OPERATION(AGSCFGOPERATION)
RESP(RESP)
RESP2(RESP2)
END-EXEC
*
* ... COBOL code ...
*
|
After invoking the Web service, use the GET CONTAINER command shown in Listing 13 to get the response:
Listing 13. GET CONTAINER
* Get the return value
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
CHANNEL(OUTBOUND-CHANNEL)
INTO(locateEPRResp)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* Get the franchise EPR
EXEC CICS GET CONTAINER(EPR-xml-cont OF locateEPRResp)
CHANNEL(OUTBOUND-CHANNEL)
INTO(EPR-TEMP)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Having located a franchise that can satisfy the order, you use its EPR to call the franchisee service. Use the WSACONTEXT BUILD command shown in Listing 14 to construct the WSACONTEXT. The ReplyTo EPR is the EPR to which the SOAP response message is returned and REFPARMS is the reference parameter entity of the EPR:
Listing 14. WSACONTEXT BUILD
* Construct the TO EPR and put them into WSACONTEXT
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
TOEPR
ALL
EPRFROM(EPR-TEMP)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
TOEPR
REFPARMS
EPRFROM(REFER-ORDER-NUMBER)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* Construct the REPLYTO EPR and put it into WSACONTEXT
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
REPLYTOEPR
ADDRESS
EPRFROM(TRACKING-SERVICE)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* Construct the REFERENCE PARAMETER and put it into WSACONTEXT
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
REPLYTOEPR
REFPARMS
EPRFROM(REFER-ORDER-NUMBER)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* Construct the FAULTTO EPR and put it into WSACONTEXT
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
FAULTTOEPR
ADDRESS
EPRFROM(PROBLEM-RESOLUTION-SERVICE)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
FAULTTOEPR
REFPARMS
EPRFROM(REFER-ORDER-NUMBER)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
After constructing the WSACONTEXT, you invoke the franchise Web service. The request pipeline is invoked and the WS-Addressing handler transforms the WSACONTEXT into SOAP header elements.
Upon return, the addressing pipeline handler puts the response SOAP header MAPS into the response WSACONTEXT. The order number is returned to the caller that completes the
processOrder action:
Listing 15. PUT RESPONSE
* Invoke Service AGSFranchise
EXEC CICS INVOKE
SERVICE(AGSFRANSERVICE1)
CHANNEL(OUTBOUND-CHANNEL)
OPERATION(AGSCFROPERATION)
RESP(RESP)
RESP2(RESP2)
END-EXEC
*
* ... COBOL code ...
*
* Response order number to client
MOVE ORDER-NUMBER-CHARS TO RESP-ORDER-NUMBER.
EXEC CICS PUT CONTAINER(PI-DFHWS-DATA)
FROM(RESP-ORDER-NUMBER)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Listing 16 shows how to process the trackingOrder action. Extract the client input order number using the GET CONTAINER command, then put the order number into the outbound channel and construct WSACONTEXT using the tracking service URI. Invoke the trackingOrder service to get the status of the order and return it to the client:
Listing 16. TRACKINGORDER ACTION
C050-GET-REQUEST-ORDER-STATUS.
* Get the OrderNumber sent by the client
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(WORKING-ROOT-DATA2)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* Put the Order Number into OUTBOUND-CHANNEL
EXEC CICS PUT CONTAINER(PI-DFHWS-DATA)
CHANNEL(OUTBOUND-CHANNEL)
FROM(WORKING-ROOT-DATA2)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* Construct the TO EPR and put it into WSACONTEXT
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
TOEPR
ADDRESS
EPRFROM(TRACKING-SERVICE)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
MOVE orderNumber OF WORKING-ROOT-DATA2(1:18)
TO ORDER-NUMBER-CHARS.
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
TOEPR
REFPARMS
EPRFROM(REFER-ORDER-NUMBER)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* Invoke Service AGSTracking
EXEC CICS INVOKE
SERVICE(AGSTRACKINGSERV)
CHANNEL(OUTBOUND-CHANNEL)
OPERATION(AGSTRACKOPERATION)
RESP(RESP)
RESP2(RESP2)
END-EXEC
C060-GET-ORDER-STATUS.
* Get order status
MOVE SPACES TO ORDER-STATUS-VALUE.
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(ORDER-STATUS-VALUE)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
C070-PUT-ORDER-STATUS.
* Construct the output
* Send to status back to client
MOVE ORDER-STATUS-VALUE TO RESP-ORDER-STATUS.
EXEC CICS PUT CONTAINER(PI-DFHWS-DATA)
FROM(RESP-ORDER-STATUS)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Creating the AGSConfig service: Overview
AGSConfig is the configuration service for AGS. It holds details about the franchises and the products that the franchises build. It accepts the register request sent from each franchise and records the necessary information, including franchise name and location, product type, and Web service EPR in the AGM corporate VSAM file. AGSOrder uses AGSConfig to find a suitable franchise for each order. AGSConfig returns the EPR of the franchise that is found for each search request; this EPR is then used to call the franchise's AGSFranchise service. Here is the program flowchart for the service:
Figure 5. AGSConfig flowchart

AGSConfig uses the WS-Addressing API to get the Action parameter from the request WSACONTEXT. If the Action is LocateEPR, the program gets two input parameters from the container: structure and geography. AGSConfig uses these parameters to find a suitable franchise and return its EPR.
If the Action is RegisterEPR, the program gets five input parameters from the container: franchise, geography,
structure-num, structure-cont, and EPR. AGSConfig gets the structure information and records what kind of product this franchise can produce in the VSAM file. Using name, geography, structure-num, structure-cont, and
EPR, AGSConfig constructs a record of the newly joined franchise and writes the record into the VSAM file.
Creating the AGSConfig service: Detailed steps
Using DFHWS2LS (JCL AGSCFGP and AGSCFGR), you must first process AGSConfigService.wsdl to create the WSBind files required by CICS to process the requests and responses, along with the COBOL copybooks for the AGSConfig service. This process generates the copybooks shown in Listings 17 through 19:
Listing 17. AGSCFP01
03 registrationReq.
06 franchise PIC X(256).
06 geography PIC X(256).
06 structure-num PIC S9(9) COMP-5 SYNC.
06 structure-cont PIC X(16).
06 EPR.
09 EPR-xml-cont PIC X(16).
09 EPR-xmlns-cont PIC X(16).
01 AGSCFP01-structure.
03 structure PIC X(256).
|
Listing 18. AGSCFP02
03 locateEPRReq. 06 geography PIC X(256). 06 structure PIC X(256). |
Listing 19. AGSCFQ02
03 locateEPRResp.
06 franchise PIC X(256).
06 EPR.
09 EPR-xml-cont PIC X(16).
09 EPR-xmlns-cont PIC X(16).
|
You also need to construct the data structure of the VSAM file record for franchise information, as shown in Listing 20:
Listing 20. AGSCFGCP
03 FRAN-NAME PIC X(30). 03 FRAN-STRUCT-TYPE PIC X(8). 03 FRAN-GEOGRAPHY PIC X(2). 03 FRAN-EPR PIC X(2048). |
After the language structures are produced, the AGSConfig service can be written as the program AGSCFG. The key elements of the program are illustrated in the next few listings.
Listing 21 contains the main line of AGSConfig, which can take one of two operations, as determined by the Action in the request message WSACONTEXT:
locateEPR and registerEPR:
Listing 21. AGSConfig main line
A-MAIN-PROCESSING SECTION.
* Initialise any variables and information
PERFORM B010-INIT-PROC.
* get Action from the WSACONTEXT
PERFORM C010-GET-HEADER-ACTION.
* find suitable franchise request from AGSOrder
IF ACTION-OPTION(1:36) = ACTION-LOCATE
THEN
PERFORM C020-GET-LOCATEEPR-DATA
PERFORM C030-BROWSE-READ-VSAM-FILE
PERFORM C040-PUT-CONTAINER-REPLY-EPR
ELSE
* register franchise request from franchise
IF ACTION-OPTION(1:38) = ACTION-REGISTER
PERFORM C050-GET-REGISTEREPR-DATA
PERFORM C060-GET-STRUCT-EPR-DATA
PERFORM C070-FILL-NEW-RECORD
PERFORM C080-WRITE-VSAM-FILE
ELSE PERFORM X-GENERIC-ABEND
END-IF
END-IF.
A-MAIN-PROCESSING-EXIT.
GOBACK.
|
Next, initialize variables and information using the ASSIGN CHANNEL API:
Listing 22. ASSIGN CHANNEL
B010-INIT-PROC.
* Initialise any variables and information
EXEC CICS ASSIGN
CHANNEL(CURRENT-CHANNEL)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Listing 23 shows how to use the WSACONTEXT GET command in a service provider to get the MAPs sent by the service requester:
Listing 23. WSACONTEXT GET
C010-GET-HEADER-ACTION.
* Retrieve the action value from WSACONTEXT with WS-A API
EXEC CICS WSACONTEXT GET REQCONTEXT
ACTION(ACTION-OPTION)
RESP(resp)
RESP2(resp2)
END-EXEC.
*
* ... COBOL code ...
*
|
For the Action registerEPR, use the GET CONTAINER command shown in Listing 24 to retrieve data from the named channel container
PI-DFHWS-DATA, which holds the top-level data structure that is mapped to and from a SOAP request. WORKING-ROOT-DATA1 is
AGSCFP01, which represents the register information:
Listing 24. GET CONTAINER
C050-GET-REGISTEREPR-DATA.
* Retrieve the content of root container of the request
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(WORKING-ROOT-DATA1)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
STRUCTURE-CONT is the container that contains the types of products that the franchise can provide. EPR-XML-CONT contains the EPR of the service that the franchise provides. The loop in the code is used to mark the kind of product the franchise can provide. The types of products are represented with a flag byte 8 bits long, with each bit representing a product type. If the franchise can provide a product, the appropriate bit is set to 1; otherwise, it is set to 0, as shown in the logic in Listing 25:
Listing 25. AGSConfig logic
C060-GET-STRUCT-EPR-DATA.
* Get structure types when franchise registering
EXEC CICS GET CONTAINER(STRUCTURE-CONT)
INTO(STRUCT-TYPE)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
IF RESP NOT = DFHRESP(NORMAL)
THEN
PERFORM X-GENERIC-ABEND
END-IF.
* Record franchise products types
PERFORM WITH TEST BEFORE UNTIL STRUCTURE-NUM = 0
MOVE CURRENT-POS TO START-POS
MULTIPLY 256 BY START-POS
ADD 1 TO START-POS
EVALUATE STRUCT-TYPE(START-POS:5)
WHEN STRUCT-SHEDS
MOVE '1' TO STRUCT-TEMP(1:1)
WHEN STRUCT-HOUSE
MOVE '1' TO STRUCT-TEMP(2:1)
WHEN STRUCT-CABIN
MOVE '1' TO STRUCT-TEMP(3:1)
END-EVALUATE
SUBTRACT 1 FROM STRUCTURE-NUM
ADD 1 TO CURRENT-POS
END-PERFORM.
* Get EPR of the franchise service
MOVE STRUCT-TEMP TO FRAN-STRUCT-TYPE OF NEW-RECORD.
EXEC CICS GET CONTAINER(EPR-XML-CONT OF registrationReq)
INTO(EPR-TEMP)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Next, create a new franchise record:
Listing 26. Create a franchise record
C070-FILL-NEW-RECORD.
* Construct data according to the structure of the VSAM file
MOVE FRANCHISE OF WORKING-ROOT-DATA1
TO FRANCHISE-TEMP.
MOVE FRANCHISE-TEMP(1:30)
TO FRAN-NAME OF NEW-RECORD.
MOVE GEOGRAPHY OF WORKING-ROOT-DATA1
TO GEOGRAPHY-TEMP.
MOVE GEOGRAPHY-TEMP(1:2)
TO FRAN-GEOGRAPHY OF NEW-RECORD.
MOVE EPR-TEMP
TO FRAN-EPR OF NEW-RECORD.
*
* ... COBOL code ...
*
|
Write the newly created record into the VSAM file using the WRITE FILE command, as shown in Listing 27, to complete the registerEPR action:
Listing 27. WRITE FILE
C080-WRITE-VSAM-FILE.
* Write file
MOVE FRAN-NAME OF NEW-RECORD TO PRIID.
EXEC CICS WRITE
FILE(FILE-NAME)
FROM(NEW-RECORD)
RIDFLD(PRIID)
RESP(WR-RESP-CODE)
END-EXEC.
*
* ... COBOL code ...
*
|
For the locateEPR Action, use the GET CONTAINER command shown in Listing 28 to retrieve data from the named channel container
PI-DFHWS-DATA, which holds the top-level data structure that is mapped to and from a SOAP request.
WORKING-ROOT-DATA2 is AGSCFP02, which represents the search information:
Listing 28. GET CONTAINER
C020-GET-LOCATEEPR-DATA.
* Retrieve the content of root container of the request
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(WORKING-ROOT-DATA2)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
WORKING-ROOT-DATA2 holds the search condition from AGSOrder. The VSAM file is opened, and then you start reading it to search for a suitable franchise:
Listing 29. READ VSAM FILE
C030-BROWSE-READ-VSAM-FILE.
* Initialize search condition
MOVE STRUCTURE OF WORKING-ROOT-DATA2 TO STRUCT-VALUE.
MOVE GEOGRAPHY OF WORKING-ROOT-DATA2
TO GEOGRAPHY-VALUE.
* STRUCT-VALUE IS THE STRUCTURE REQUIRED BY USER
EVALUATE STRUCT-VALUE(1:5)
WHEN STRUCT-SHEDS
MOVE 1 TO STRUCT-POS
WHEN STRUCT-HOUSE
MOVE 2 TO STRUCT-POS
WHEN STRUCT-CABIN
MOVE 3 TO STRUCT-POS
END-EVALUATE.
* Open VSAM file and search for a suitable franchise
PERFORM C035-BROWSE-VSAM-FILE.
IF BR-RESP-CODE = 0 THEN
PERFORM C037-READ-VSAM-FILE
ELSE
MOVE 'BROWSE FILE ERROR' TO FILE-RECORD
EXEC CICS SEND FROM(FILE-RECORD)
LENGTH(120)
ERASE
END-EXEC
END-IF.
EXIT.
|
Next, as shown in Listing 30, start browsing the VSAM file for a franchise that can satisfy the customer's requirements:
Listing 30. STARTBR
C035-BROWSE-VSAM-FILE.
* Browse VSAM file
EXEC CICS STARTBR
FILE(FILE-NAME)
RIDFLD(PRIID)
RESP(BR-RESP-CODE)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the READNEXT FILE command shown in Listing 31 to get the next record in the VSAM file. Each record is a whole description of a franchise, including its product types and EPR. Next, compare the record you got with the search condition. If they match, the right franchise has been selected and its EPR returned. If they don't match, the next record in the VSAM file is selected and compared with the search condition. This continues until end of file -- not a particularly efficient search mechanism, but it sufficient for the purposes of this article:
Listing 31. Loop for finding a record
C037-READ-VSAM-FILE.
* Get a new record
EXEC CICS READNEXT FILE(FILE-NAME)
INTO(FILE-RECORD)
RIDFLD(PRIID)
RESP(RE-RESP-CODE)
END-EXEC.
* find the suitable franchise and get its EPR
IF RE-RESP-CODE = 0
THEN
MOVE FRAN-STRUCT-TYPE OF FILE-RECORD TO STRUCT-TEMP
IF FRAN-GEOGRAPHY OF FILE-RECORD = GEOGRAPHY-VALUE(1:2)
AND
STRUCT-TEMP(STRUCT-POS:1) = '1'
THEN
MOVE FRAN-NAME OF FILE-RECORD
TO FRANCHISE OF RESP-FRANCHISE-EPR
MOVE FRAN-EPR OF FILE-RECORD
TO EPR-TEMP
ELSE
GO TO C037-READ-VSAM-FILE
END-IF
ELSE
IF RE-RESP-CODE = DFHRESP(ENDFILE)
PERFORM C038-BROWSE-END-BR
ELSE
MOVE 'READ FILE ERROR' TO FILE-RECORD
EXEC CICS SEND FROM(FILE-RECORD)
LENGTH(120)
ERASE
END-EXEC
END-IF
END-IF
EXIT.
|
When you have finished browsing the file, end the browse using ENDBR:
Listing 32. ENDBR
C038-BROWSE-END-BR.
EXEC CICS ENDBR
FILE(FILE-NAME)
END-EXEC.
|
Use the PUT CONTAINER command shown in Listing 33 to put the located franchise EPR and the name of the franchise into containers.
This code completes the locateEPR action:
Listing 33. PUT RESPONSE IN CONTAINER
C040-PUT-CONTAINER-REPLY-EPR.
* Response franchise and its EPR to requester
MOVE 'FRAN-CONTAINER ' TO EPR-XML-CONT OF LOCATEEPRRESP.
EXEC CICS PUT CONTAINER(EPR-XML-CONT OF LOCATEEPRRESP)
FROM(EPR-TEMP)
CHAR
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
EXEC CICS PUT CONTAINER(PI-DFHWS-DATA)
FROM(RESP-FRANCHISE-EPR)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Creating the AGSTracking service: Overview
AGSTracking is used to record order information and track order status. It accepts requests sent from franchises and from AGSOrder. The franchise can accept an order and transmit the order information to AGSTracking for recording. AGSOrder accepts a tracking order status request from a client and forwards it to AGSTracking. AGSTracking uses the order number to find relevant information relating to the order, and returns that information to AGSOrder. The program flowchart for the service is illustrated in Figure 6:
Figure 6. AGSTracking flowchart

AGSTracking first uses the WS-Addressing API to get the Action parameter, which exists in the request WSACONTEXT. If the Action is processOrderResp, the program gets two input parameters from the container: orderDate and orderStatus. Then AGSTracking uses the WS-Addressing API to get the order number stored in the reference parameter. AGSTracking uses these parameters to construct a record and writes it into the VSAM file that holds the order status.
If the Action is getOrderTrackingReq, the program gets the lone input parameter, OrderNumber, from the container. AGSTracking reads the VSAM file, finds the order tracking records, and returns the order status to AGSOrder.
Creating the AGSTracking service: Detailed steps
Using DFHWS2LS (JCL AGPTRKP and AGPTRKR), process AGSTrackingService.wsdl to create the WSBind files required by CICS to process the requests and responses, along with the COBOL copybooks for the AGSTracking Service. This process generates the copybooks shown in Listings 34 to 36:
Listing 34. AGSTKP01
03 processOrderResp. 06 orderDate PIC X(256). 06 orderStatus PIC X(256). |
Listing 35. AGSTKP02
03 orderTrackingReq. 06 orderNumber PIC X(256). |
Listing 36. AGSTKQ02
03 processOrderResp. 06 orderDate PIC X(256). 06 orderStatus PIC X(256). |
You also need to construct the data structure of the VSAM file that is used to hold order information and status, as shown in Listing 37:
Listing 37. ORDERSTA
03 ORDERNUMBER PIC X(30). 03 ORDERDATE PIC X(30). 03 ORDERSTATUS PIC X(2048). |
After the language structures are produced, the AGSTracking service can be written as the program AGSTRACK. The key elements of the program are illustrated in the next few listings.
Listing 38 contains main line of AGSTracking. AGSTracking can take one of two operations, as determined by the Action in the SOAP header:
processOrderReq and getOrderTrackingReq:
Listing 38. AGSTracking main line
A-MAIN-PROCESSING SECTION.
* Initialise any variables and information
PERFORM B010-INIT-PROC.
* get Action from the WSACONTEXT
PERFORM C010-GET-HEADER-ACTION.
* If the process order request is sent
IF ACTION-OPTION(1:67) = ACTION-PROCESSORDER
THEN
PERFORM C020-GET-REQUEST-ORDER-DATA
PERFORM C030-FILL-NEW-RECORD
PERFORM C040-WRITE-VSAM-FILE
ELSE
* If the get order status request is sent
IF ACTION-OPTION(1:46) = ACTION-GETORDSTATUS
PERFORM C050-GET-ORDER-NUMBER
PERFORM C060-GET-STATUS-FROM-VSAM
PERFORM C070-PUT-RESPONSE-STATUS
ELSE PERFORM X-GENERIC-ABEND
END-IF
END-IF.
A-MAIN-PROCESSING-EXIT.
GOBACK.
|
Initialize variables and information using the ASSIGN CHANNEL API:
Listing 39. ASSIGN CHANNEL
B010-INIT-PROC.
* Initialise any variables and information
EXEC CICS ASSIGN
CHANNEL(CURRENT-CHANNEL)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the WSACONTEXT GET command shown in Listing 40 in a service provider to get the MAPs sent by the service requester:
Listing 40. WSACONTEXT GET
C010-GET-HEADER-ACTION.
* Retrieve the action value from WSACONTEXT with WS-A API
EXEC CICS WSACONTEXT GET REQCONTEXT
ACTION(ACTION-OPTION)
RESP(resp)
RESP2(resp2)
END-EXEC.
*
* ... COBOL code ...
*
|
For the processOrderReq action, use the GET CONTAINER command shown in Listing 41 to retrieve data from the container
PI-DFHWS-DATA. WORKING-ROOT-DATA1 is the high-level language data structure of AGSTKP01:
Listing 41. GET CONTAINER
C020-GET-REQUEST-ORDER-DATA.
* Retrieve the content of root container of the request
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(WORKING-ROOT-DATA1)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Construct the record that will be written to the VSAM file:
Listing 42. Construct record
C030-FILL-NEW-RECORD.
* get the ordernumber in reference parameters
EXEC CICS WSACONTEXT GET REQCONTEXT
TOEPR
REFPARMS
EPRINTO(REFERPARM)
RESP(resp)
RESP2(resp2)
END-EXEC.
IF RESP NOT = DFHRESP(NORMAL)
THEN
PERFORM X-GENERIC-ABEND
ELSE
XML PARSE REFERPARM PROCESSING PROCEDURE PARSE-ORDERNUMBER
END-IF.
* File in the order number
MOVE ORDERNUM TO ORDERNUMBER OF NEW-RECORD.
* File in the order date
MOVE ORDERDATE OF WORKING-ROOT-DATA1 TO TEMP-DATA.
MOVE TEMP-DATA(1:30) TO ORDERDATE OF NEW-RECORD.
MOVE SPACES TO TEMP-DATA.
* Fill in the Order Status
MOVE ORDERSTATUS OF WORKING-ROOT-DATA1
TO ORDERSTATUS OF NEW-RECORD.
|
Use the WRITE FILE command shown in Listing 43 to write the record into the VSAM file. This code completes the processOrderReq action:
Listing 43. WRITE FILE
C040-WRITE-VSAM-FILE
* Read Update record from VSAM file
MOVE ORDERNUMBER OF NEW-RECORD TO PRIID.
EXEC CICS READ
FILE(FILE-NAME)
INTO(TEMP-RECORD)
RIDFLD(PRIID)
UPDATE
RESP(WR-RESP-CODE)
END-EXEC.
* If record exists, then perform update
IF WR-RESP-CODE = 0
EXEC CICS REWRITE
FILE(FILE-NAME)
FROM(NEW-RECORD)
RESP(WR-RESP-CODE)
END-EXEC
* if record does not exist, perform write
ELSE IF WR-RESP-CODE = DFHRESP(NOTFND)
MOVE ORDERNUMBER OF NEW-RECORD TO PRIID
EXEC CICS WRITE
FILE(FILE-NAME)
FROM(NEW-RECORD)
RIDFLD(PRIID)
RESP(WR-RESP-CODE)
END-EXEC
ELSE PERFORM X-GENERIC-ABEND
END-IF
END-IF.
*
* ... COBOL code ...
*
|
For the getOrderTrackingReq action, use the GET CONTAINER command to retrieve data from the container PI-DFHWS-DATA, as shown in Listing 44. WORKING-ROOT-DATA2 is the high-level language data structure of AGSTKP02:
Listing 44. Retrieve data
C050-GET-ORDER-NUMBER.
* Retrieve the content of root container of the request
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(WORKING-ROOT-DATA2)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
MOVE ORDERNUMBER OF WORKING-ROOT-DATA2 TO TARGET-DATA.
MOVE TARGET-DATA(1:18) TO PRIID.
*
* ... COBOL code ...
*
|
Read the KSDS file using the order number that was input by the client as a key to get the detailed content, as shown in Listing 45. Then construct the response data structure and return it to the client:
Listing 45. Read file
C060-GET-STATUS-FROM-VSAM.
* Get order status from VSAM file
EXEC CICS READ FILE(FILE-NAME)
INTO(FILE-RECORD)
RIDFLD(PRIID)
RESP(RE-RESP-CODE)
END-EXEC.
*
* ... COBOL code ...
*
|
Finally, as shown in Listing 46, use the PUT CONTAINER command to pass the order status back to the caller. This code completes the
getOrderTrackingReq action:
Listing 46. Return order status
C070-PUT-RESPONSE-STATUS.
* Construct the response data
MOVE ORDERDATE OF FILE-RECORD TO
orderDate OF RESP-ORDER-STATUS.
MOVE ORDERSTATUS OF FILE-RECORD TO
orderStatus OF RESP-ORDER-STATUS.
* Response order status to AGSOrder
EXEC CICS PUT CONTAINER(PI-DFHWS-DATA)
FROM(RESP-ORDER-STATUS)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Creating the AGSFranchise service: Overview
In this section, you'll create a sample implementation of a franchisee AGSFranchise service. AGSFranchise has two operations: one to accept an order and process it, and the other to send an updated order status to AGSTracking. Here is the program flowchart for the service:
Figure 7. AGSFranchise flowchart
AGSFranchise first uses the WS-Addressing API to get the Action parameter, which is located in the request WSACONTEXT. If the Action is ProcessOrder, AGSFranchise uses the WS-Addressing API to get the EPR of AGSTracking (stored in the ReplyTo EPR) and writes the EPR into the VSAM file in the AGSFranchise system. Then AGSFranchise gets four input parameters from the container: name, structure, color, and geography. AGSFranchise extracts the order number from the reference parameters of the To EPR using the WS-Addressing API. If the order is accepted, the order status is sent to AGSTracking for recording; if not, an error message is sent to the AGSProblemResolution service.
If the Action is updateOrderStatus, the service gets three input parameters from the container: OrderNumber, OrderDate, and OrderStatus. AGSFranchise uses the order number to locate the EPR of AGSTracking from the VSAM file and uses it as the To EPR. AGSFranchise then invokes the AGSTracking service to update the order status.
Creating the AGSFranchise service: Detailed steps
Using DFHWS2LS (JCL AGSFANP and AGSFANR), process AGSFranchiseService.wsdl to create the WSBind files required by CICS to process the requests and responses, along with the COBOL copybooks for the AGSFranchise service. This process generates the copybooks shown in Listings 47 through 49:
Listing 47. AGSFAP01
03 processOrderReq. 06 name PIC X(256). 06 structure PIC X(256). 06 color PIC X(256). 06 geography PIC X(256). |
Listing 48. AGSFAP02
03 updateOrderStatusReq. 06 orderNumber PIC X(256). 06 orderDate PIC X(256). 06 orderStatus PIC X(256). |
Listing 49. AGSFAQ01
03 processOrderResp. 06 orderDate PIC X(256). 06 orderStatus PIC X(256). |
You also need to construct the data structure of the VSAM file that is used to hold the order number and its ReplyTo EPR, as shown in Listing 50:
Listing 50. AGSFRANF
03 ORDERNUMBER PIC X(30). 03 AGSTRACKING-EPR PIC X(2048). |
After the language structures are produced, the AGSFranchise service can be written as the program AGSFAN1. The key elements of the program are illustrated in the next few listings.
Listing 51 contains the main line of AGSFranchise, which can take one of two operations, as determined by the Action in the request WSACONTEXT:
processOrderReq and updateOrderReq:
Listing 51. AGSFranchise main line
A-MAIN-PROCESSING SECTION.
* Initialise any variables and information
PERFORM B010-INIT-PROC.
* get Action from the WSACONTEXT
PERFORM C010-GET-HEADER-ACTION.
* Accept an order
IF ACTION-OPTION(1:39) = ACTION-PROCESS-ORDER
THEN
PERFORM C020-GET-REQUEST-ORDER-DATA
PERFORM C030-PUT-FIRST-ORDER-STATUS
ELSE
* Update order status
IF ACTION-OPTION(1:46) = ACTION-REGISTER-ORDER
PERFORM C040-GET-REQUEST-ORDER-STATUS
PERFORM C050-PUT-UPDATED-ORDER-STATUS
ELSE PERFORM X-GENERIC-ABEND
END-IF
END-IF.
A-MAIN-PROCESSING-EXIT.
GOBACK.
|
Initialize variables and information using the ASSIGN CHANNEL API:
Listing 52. ASSIGN CHANNEL
B010-INIT-PROC.
* Initialise any variables and information
EXEC CICS ASSIGN
CHANNEL(CURRENT-CHANNEL)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the WSACONTEXT GET command shown in Listing 53 in a service provider to get the MAPs sent by the service requester:
Listing 53. WSACONTEXT GET
C010-GET-HEADER-ACTION.
* Retrieve the action value from WSACONTEXT with WS-A API
EXEC CICS WSACONTEXT GET REQCONTEXT
ACTION(ACTION-OPTION)
RESP(resp)
RESP2(resp2)
END-EXEC.
*
* ... COBOL code ...
*
|
For the processOrderReq action, interrogate the WSACONTEXT and retrieve the To EPR reference parameters. Then, using the XML PARSE command, extract the order number. The details of the order are extracted from the PI-DFHWS-DATA container. WORKING-ROOT-DATA1 is
AGSFAP01, which represents the order information. The ReplyTo EPR is also extracted from the WSACONTEXT and is stored for later use as a To EPR to send order update messages to AGSTracking. You should also extract and store the FaultTo EPR so that it can be used to send application fault messages to the AGSProblemResolution service, but for simplicity's sake we have not done that.
At this point, the AGSFranchise service returns to the caller. The service is unaware that the response is sent to another service and not its caller via the ReplyTo EPR. When the pipeline response leg is executed, the WS-Addressing header handler processes the ReplyTo EPR and causes a new one-way request to be sent to the AGSTracking service. All of these actions are handled by the code in Listing 54:
Listing 54. processOrderReq Action
C020-GET-REQUEST-ORDER-DATA.
* get the replytoepr in reference parameters
EXEC CICS WSACONTEXT GET REQCONTEXT
CHANNEL(CURRENT-CHANNEL)
TOEPR
REFPARMS
EPRINTO(REFERPARM)
RESP(resp)
RESP2(resp2)
END-EXEC.
IF RESP NOT = DFHRESP(NORMAL)
THEN
PERFORM X-GENERIC-ABEND
ELSE
XML PARSE REFERPARM PROCESSING PROCEDURE C027-PARSE-ORDERNUMBER
END-IF.
* Retrieve the content of root container of the request
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(WORKING-ROOT-DATA1)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* get the ReplyToEPR and store the EPR into VSAM file
MOVE ORDERNUM TO ORDERNUMBER OF FILE-RECORD.
EXEC CICS WSACONTEXT GET REQCONTEXT
CHANNEL(CURRENT-CHANNEL)
REPLYTOEPR
ALL
EPRINTO(AGSTRACKING-EPR OF FILE-RECORD)
RESP(resp)
RESP2(resp2)
END-EXEC.
IF RESP NOT = DFHRESP(NORMAL)
THEN PERFORM X-GENERIC-ABEND
ELSE
PERFORM C025-WRITE-RECORD-FILE
END-IF.
*
* ... COBOL code ...
*
|
Write the ReplyTo EPR to a VSAM file for later use:
Listing 55. Write ReplyTo EPR
C025-WRITE-RECORD-FILE.
* Record the ReplyToEPR to the File
MOVE ORDERNUM TO PRIID.
EXEC CICS WRITE
FILE(FILE-NAME)
FROM(FILE-RECORD)
RIDFLD(PRIID)
RESP(WR-RESP-CODE)
END-EXEC
*
* ... COBOL code ...
*
|
Then construct the initial status of an order and put it into a container, as shown in Listing 56. WS-Addressing transfers it to the AGSTracking service using the ReplyTo EPR.
This code completes the processOrderReq action:
Listing 56. Put order initial status
C030-PUT-FIRST-ORDER-STATUS.
* Response the initial order status to AGSTrackingService
MOVE FUNCTION CURRENT-DATE(1:14)
TO ORDERDATE OF RESP-ORDER-STATUS.
MOVE ORDER-INITIAL-STATUS
TO ORDERSTATUS OF RESP-ORDER-STATUS.
* put the order status into container
EXEC CICS PUT CONTAINER(PI-DFHWS-DATA)
FROM(RESP-ORDER-STATUS)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
*
* ... COBOL code ...
*
|
The updateOrderReq action is used by the franchisee system to send order status updates to AGSTracking. The initial order's ReplyTo EPR, which was stored in a VSAM file, is retrieved from the file, as shown in Listing 57. This EPR is used as a To EPR to send an order update to the AGSTracking service:
Listing 57. Get ReplyTo EPR
C040-GET-REQUEST-ORDER-STATUS.
* put the order status into container
EXEC CICS GET CONTAINER(PI-DFHWS-DATA)
INTO(WORKING-ROOT-DATA2)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
MOVE orderNumber OF WORKING-ROOT-DATA2 TO PRIID.
EXEC CICS READ
FILE(FILE-NAME)
INTO(TEMP-RECORD)
RIDFLD(PRIID)
RESP(WR-RESP-CODE)
END-EXEC.
*
* ... COBOL code ...
*
|
Use the PUT CONTAINER command to put the updated order status into the container. Use the WSACONTEXT BUILD command to create a To EPR.
Use the INVOKE SERVICE command shown in Listing 58 to call the AGSTracking service using the To EPR:
Listing 58. INVOKE SERVICE
C050-PUT-UPDATED-ORDER-STATUS.
MOVE orderNumber OF WORKING-ROOT-DATA2 TO
ORDER-NUMBER-CHARS.
MOVE orderDate OF WORKING-ROOT-DATA2 TO
orderDate OF RESP-ORDER-STATUS.
MOVE orderStatus OF WORKING-ROOT-DATA2 TO
orderStatus OF RESP-ORDER-STATUS.
* put the order status into container
EXEC CICS PUT CONTAINER(PI-DFHWS-DATA)
CHANNEL(OUTBOUND-CHANNEL)
FROM(RESP-ORDER-STATUS)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* build WSACONTEXT
EXEC CICS WSACONTEXT BUILD
CHANNEL(OUTBOUND-CHANNEL)
TOEPR
ALL
EPRFROM(TEMP-RECORD)
RESP(RESP)
RESP2(RESP2)
END-EXEC.
* invoke tracking service using track operation
EXEC CICS INVOKE
SERVICE(TRACKINGSERVICE)
CHANNEL(OUTBOUND-CHANNEL)
OPERATION(AGSTRACKOPERATION)
RESP(RESP)
RESP2(RESP2)
END-EXEC
*
* ... COBOL code ...
*
|
Deploying Web services on CICS
Now that you have developed the core services for AGS and for a franchise, you can deploy them to CICS:
- Define and install all the programs in the CICS region:
CEDA DEF PROG(AGSOrder) G(WSA1) CEDA DEF PROG(AGSCFG) G(WSA1) CEDA DEF PROG(AGSTrack) G(WSA1) CEDA DEF PROG(AGSFan1) G(WSA1)
- Create three KSDS files. The first file is used by AGSConfigService to store franchisee details. The second is used by AGSTrackingService to store order information using an index. The third is used by AGSFranchise to store the ReplyTo EPR of AGSTracking, using
orderNumberas the key. Update and run the sample JCL CRVSAMS to create these files. - Define and install the files in CICS, ensuring that the Add, Browse, Delete, Read, and Update operations are set to YES:
CEDA DEF FILE(FILEAS) G(WSA1) CEDA DEF FILE(FILEBS) G(WSA1) CEDA DEF FILE(ADDRFL) G(WSA1)
- Define the provider PIPELINE resource. Use the sample providerforWSAddressing.xml for the ConfigFile, and suitable Shelf and WSDir directories:
CEDA DEF PIPELINE(WSAPROPL) G(WSA1)
- Define the TCPIPSERVICE resource:
CEDA DEF TCPIPSERVICE(WSAPORT) G(WSA1)
- Deploy the WebService provider:
CEDA INSTALL G(WSA1)
Check that all the resources for a Web service provider have been installed successfully:
- PIPELINE: A single PIPELINE definition defines an infrastructure that can be used by many applications. The information about the message handlers is supplied indirectly; the PIPELINE resource specifies the name of an HFS file that contains an XML description of the nodes and their configuration.
- WEBSERVICE: Web services are typically created automatically from a Web service binding file when the PIPELINE's pickup directory is scanned. This action happens when the PIPELINE resource is installed, or as a result of a
PERFORM PIPELINE SCANcommand. - URIMAP: For service providers deployed using the CICS Web services assistant, the URIMAP resources are typically created automatically from a Web service binding file when the PIPELINE's pickup directory is scanned. This action happens when the PIPELINE resource is installed, or as a result of a
PERFORM PIPELINE SCAN command. - TCPIPSERVICE: A TCPIPSERVICE definition is required in a service provider that uses the HTTP transport, and contains information about the port on which inbound requests are received.
Use CEMT INQUIRE WEBSERVICE to view the status of the Web service; the results should look like Figure 8. The resource is created with a name matching the WSBIND file name, and that the WEBSERVICE is associated with the PIPELINE resource that scanned it in:
Figure 8. CEMT INQUIRE WEBSERVICE PROVIDER

Use CEMT INQUIRE URIMAP to list the installed URIMAPs; the results should look like Figure 9. Ensure that the path for the URIMAP matches that entered into the JCL for the job that ran the DFHWS2LS utility earlier:
Figure 9. CEMT INQUIRE URIMAP

Deploying the Web service requester on the CICS region
Now that you have deployed the Web service provider on the CICS region, you need to deploy a requester as well:
- Create the PIPELINE resource for the Web service requester:
CEDA DEF PIPELINE(WSAREQPL) G(WSA1)
- Install the requester PIPELINE resource on the CICS region:
CEDA Inquire PIPELINE(WSAREQPL) G(WSA1)
A corresponding Web service CICS resource is created and installed automatically, as you can see in Figure 10:
Figure 10. CEMT INQUIRE WEBSERVICE REQUESTER

Now that you have deployed a service requester on the CICS region, you can start to write the client program and test the business logic.
You have now deployed the AGS application and a sample franchisee AGSFranchise service to CICS. To test the services, you need a simple client program to drive the AGSOrder service. Use the JCICS test client program supplied in the code package AGSClientJCics.java to test the services. Create the PIPELINE resource for the Web service requester:
CEDA DEF PROG(AGSClint) G(WSA1) |
The results should look like Figure 11:
Figure 11. CEDA DEF PROGRAM

Next, define and install a transaction to run the program:
CEDA DEF TRANS(JCLT) PROG(AGSClint) G(WSA1) |
Then run the transaction, and input the necessary parameters to invoke AGSOrderService. The result is displayed in the output file for Java on the USS file system. Input parameters include the AgsOrderService URI and the Action, among others. The parameters for the PutOrder action are Name, Structure,
Color, and Location. For the TrackOrder action, the parameter is OrderNumber.
Examples of the command are shown in Listing 59:
Listing 59. Sample commands
jclt http://ags.example.ibm.com:80/AgsOrder PutOrder LION HOUSE BLUE 01 jclt http://ags.example.ibm.com:80/AgsOrder TrackOrder LION20100101010101 |
The result is shown in Figure 12:
Figure 12. Result

The sample AGSClientJCics program is shown in Listing 60:
Listing 60. AGSClientJCICS
public class AGSClientJCics {
/*
* Get input parameters, construct the WSAContext and invoke AGSOrderService
*/
public void invokeWebService()
{
... Application Code ...
webService.setName("agsord.req");
String result;
//Create channel
if(channel == null)
{
channel = task.createChannel("OUTBOUND-CHANNEL");
container = channel.createContainer("DFHWS-DATA ");
}
//Build ToEPR address
WSAContext wsaContext = new WSAContext();
wsaContext.setChannel(channel.getName());
wsaContext.setEprAddress(WSAContext.TOEPR, URI);
//Different logic
if(Action.equals(putOrder))
{
... Application Code ...
//Put container and invoke AGSOrderService
container.put(orderReq);
webService.invoke(channel, "placeOrder");
... Application Code ...
}
else if(Action.equals(trackOrder))
{
... Application Code ...
//Put container and invoke AGSOrderService
container.put(trackReq);
webService.invoke(channel, "trackOrder");
... Application Code ...
}
... Application Code ...
}
}
|
A Java client is also supplied with the code download. It was developed using IBM Rational Developer for System Z (Rational Application Developer could have also be used). The project uses the com.ibm.jaxws.thinclient_7.0.0.jar. package, which is provided by those two products and must be imported into the workspace. AGSOrderClient.zip contains the client as an exported Eclipse Java project.
This article has shown you how to construct a simple SOA application using WS-Addressing techniques to dynamically locate services and route messages between services using CICS TS V4.1. Using these techniques, you can construct sophisticated SOA applications that enable use of message exchange patterns that do not fit the normal request/response paradigm, along with applications that make use of dynamic location of services. The business uses are many and varied; this article has shown how a franchise business could operate with each franchisee registering their own service to work as part of the overall franchise application.
| Description | Name | Size | Download method |
|---|---|---|---|
| Code sample | WSADEMO.zip | 84 KB | HTTP |
Information about download methods
- CICS supports the following recommendation specifications:
- W3C WS-Addressing 1.0 -- Core
- W3C WS-Addressing 1.0 -- SOAP Binding
- W3C WS-Addressing 1.0 -- Metadata
- W3C WS-Addressing -- Submission
- IBM CICS resources:
- IBM CICS product page
Product descriptions, product news, training information, support information, and more. - IBM CICS Transaction Server (TS) information center
A single Web portal to all WebSphere Adapters documentation, with conceptual, task, and reference information on installing, configuring, and using CICS TS. - IBM CICS services
IBM has a comprehensive range of services to help you assess, plan, design, upgrade, secure, manage, implement, and successfully exploit CICS solutions within your organization. IBM CICS services can help you lower your costs and maintain a competitive advantage. Direct from the Hursley lab, we have the services and expertise to help you maximize your investment in CICS.
- IBM CICS product page
- IBM WebSphere resources:
- developerWorks WebSphere developer resources
Technical information and resources for developers who use WebSphere products. developerWorks WebSphere provides product downloads, how-to information, support resources, and a free technical library of more than 2000 technical articles, tutorials, best practices, IBM Redbooks, and online product manuals. - developerWorks WebSphere application connectivity developer resources
How-to articles, downloads, tutorials, education, product info, and other resources to help you build WebSphere application connectivity and business integration solutions. - developerWorks WebSphere SOA and Web services developer resources
How-to articles, downloads, tutorials, education, product info, and other resources to help you design and build WebSphere SOA and Web services solutions. - Most popular WebSphere trial downloads
No-charge trial downloads for key WebSphere products. - WebSphere forums
Product-specific forums where you can get answers to your technical questions and share your expertise with other WebSphere users. - WebSphere on-demand demos
Download, watch, and learn what WebSphere products and WebSphere-related technologies can do for your company. - developerWorks WebSphere weekly newsletter
The developerWorks newsletter gives you the latest articles and information only on those topics that interest you. In addition to WebSphere, you can select from Java, Linux, Open source, Rational, SOA, Web services, and other topics. Subscribe now and design your custom mailing. - WebSphere-related books from IBM Press
Convenient online ordering through Barnes & Noble. - WebSphere-related events
Conferences, trade shows, Webcasts, and other events around the world of interest to WebSphere developers.
- developerWorks WebSphere developer resources
- IBM developerWorks resources:
- Trial downloads for IBM software products
No-charge trial downloads for selected IBM® DB2®, Lotus®, Rational®, Tivoli®, and WebSphere® products. - developerWorks blogs
Join a conversation with developerWorks users and authors, and IBM editors and developers. - developerWorks Webcasts
Free technical sessions by IBM experts that can accelerate your learning curve and help you succeed in your most difficult software projects. Sessions range from one-hour Webcasts to half-day and full-day live sessions in cities worldwide. - developerWorks podcasts
Listen to interesting and offbeat interviews and discussions with software innovators. - developerWorks on Twitter
Check out recent Twitter messages and URLs. - IBM Education Assistant
A collection of multimedia educational modules that will help you better understand IBM software products and use them more effectively to meet your business requirements.
- Trial downloads for IBM software products

Ian Hodges is an Advisory Software Engineer at the IBM Software Lab in Hursley, United Kingdom, and develops Web technologies for CICS TS. He has developed various products that use Java technologies over the past 10 years, and is a Sun Certified Java Developer. You can contact Ian at ihodges@uk.ibm.com.

Lun Li is an intern on the CICS and Enterprise Networking Solutions team at the IBM China Development Lab. You can contact Lun at lilunbj@cn.ibm.com.

Guan Jun Liu is a Software Engineer on the CICS TS Development Team at the IBM China Development Lab. He tests and develops Java and Web technologies for CICS TS, and has two years experience with Web services and CICS TS. You can contact Guan Jun at liuguanj@cn.ibm.com.




