Developing a simple JSON web service client application
This chapter describes how to develop a Customer Information Control System (CICS) application that acts as a client for a JavaScript Object Notation (JSON) web service. To demonstrate this, the chapter walks you through an example application that calls another company’s service to retrieve a credit score for a customer.
The solution is described in the following sections:
11.1 Overview of the solution
This section gives an overview of how the solution is implemented, and presents some background information about the linkable interface used to transform JSON.
11.1.1 The scenario
Fictional Insurance Company (company example) wants to better understand the level of risk associated with new motor insurance policies. They have partnered with Nonexistent Credit Agency (company example) to obtain insurance-related credit scores for their prospective customers to do this.
Obtaining a credit score for their prospective customers will enable them to gauge the potential level of risk and adjust the quoted premium accordingly. Rather than requiring their staff to call Nonexistent Credit Agency when processing a new policy, they want to take advantage of the JSON web service provided by Nonexistent Credit Agency. This service enables partners to send a JSON request to obtain a credit score.
11.1.2 The solution
As described briefly in 4.2.2, “How CICS supports acting as a client for JSON web services” on page 26, you can develop CICS applications that act as a client for JSON web services using WEB application programming interface (API) commands and the linkable interface to transform JSON.
You must create JSONTRANSFRM bundle parts using the JSON assistants to describe the mappings between JSON and application data. The application sends requests to the service using WEB API commands, and uses the linkable interface to transform request and response data. Figure 11-1 gives a conceptual view of how data flows between the application and the target service.
Figure 11-1 Conceptual view of a JSON web service client application
This chapter walks you through creating your JSONTRANSFRM, starting from the interface to Nonexistent Credit Agency’s service credit scoring service. Unfortunately, Nonexistent Credit Agency does not provide a JSON schema describing the interface, so your first task is to create one. You can then generate the JSONTRANSFRM bundle, develop the CICS application, and deploy the artifacts.
To demonstrate how the client application works, there is a complete sample program that calls the credit score service and writes information from the response to the terminal. It contains static input data for a fictional customer. In a complete application, such a program can instead be called from the business logic that creates an insurance quote. The Common Business Oriented Language (COBOL) source for the client program is provided in Appendix B, “Sample COBOL programs” on page 167.
To test the client application, there is an implementation of the credit scoring service that runs in CICS. This is a Request-response style JSON web service that was developed from the JSON schema for the service. It simply returns a random credit score that will vary depending on the customer’s house number and policy type.
The complete source for the provider program is given in Appendix B, “Sample COBOL programs” on page 167. No further details about the implementation of the service are provided in this IBM Redbooks publication. For details about how to set up client and provider applications, see 11.6, “Testing the sample application” on page 148.
11.1.3 The linkable interface for transforming JSON
The CICS Transaction Server (CICS TS) Feature Pack for Mobile Extensions V1.0 provides a transformer program, DFHJSON, which can be called from an application using a LINK PROGRAM command. You can use it to transform application data to JSON, and JSON to application data. Parameters are passed to the transformer using a set of containers that the application must create before calling the transformer, and data is returned to the application in containers.
The transformations between application data and JSON data are described by a JSONTRANSFRM bundle part. The transformation is performed in a Java virtual machine (JVM) server, which must have the JAVA_PIPELINE=YES option in the JVM profile. For more information about configuring the JVM server, see Chapter 5, “Configuring CICS for the example scenarios” on page 31.
The JSONTRANSFRM bundle part and the JSBIND file
A JSONTRANSFRM bundle part is generated by the CICS JSON assistants. It describes a single mapping between a language structure and a JSON schema, which can be used at run time to transform application data to JSON and JSON to application data. The JSON assistants generate a CICS bundle on z/OS file system (zFS) containing a JSONTRANSFRM bundle part and a JSBIND file that describes the mapping.
You create a BUNDLE resource pointing to the zFS location of the bundle, and then install it into CICS. You can generate a JSBIND file starting either from a language structure (using DFHLS2JS), or from a JSON schema (using DFHJS2LS).
Containers used with the linkable interface
Before calling the transformer program, the application must create a set of containers that hold the input data, the name of JSONTRANSFRM, and optionally the name of the JVM server where the transformation will be performed. Before the transformer returns control to the application, the transformed data is placed in a container.
If an error occurs during transformation, the transformer creates containers giving details of the error. Table 11-1 gives details of the containers.
 
Note: The transformer uses the presence of the DFHJSON-DATA or DFHJSON-JSON containers to determine which type of transformation to perform. Therefore, only one of these containers can be present when the transformer is called.
Table 11-1 Containers used with the linkable interface
Container name
Type
Created
Contents
DFHJSON-TRANSFRM
CHAR
By the application
The name of the JSONTRANSFRM bundle part.
DFHJSON-JVMSERVR
CHAR
Optionally by the application
The name of the JVM server that performs the transformation. If this container is not present, the CICS-supplied JVMSERVER DFH$AXIS is used.
DFHJSON-ERROR
BIT
By CICS if an error occurs
A fullword binary value indicating the type of error that occurred.
DFHJSON-ERRORMSG
CHAR
By CICS for some errors
Further details of the error.
When transforming application data to JSON
DFHJSON-DATA
BIT
By the application
Application data to be transformed.
DFHJSON-JSON
CHAR
By CICS
JSON corresponding to the application data provided.
When transforming JSON to application data
DFHJSON-JSON
CHAR
By the application
JSON to be transformed.
DFHJSON-DATA
BIT
By CICS
Application data corresponding to the JSON provided.
11.2 Writing the JSON schema
The first step to create a client application for a JSON web service is to describe the interface made available by that service. This can be done starting with either a JSON schema or a language structure. As the most common scenario is that the service you want to call already exists, this chapter demonstrates starting from a JSON schema. The CICS JSON assistants use information in the JSON schema to map JSON properties to high-level language data types. These mappings are also used at run time to transform between JSON and application data.
Nonexistent Credit Agency does not provide a JSON schema describing the interface to their credit scoring service, but instead provides the following documentation, shown in Example 11-1 on page 131. If a JSON schema is already available that describes the service you want to call, you can skip to 11.3, “Generating the language structures” on page 135.
Example 11-1 Documentation for Nonexistent Credit Agency’s insurance scoring service
To request an insurance credit score for an individual, send an HTTP POST request to the following URI:
 
http://services.nonexistentcreditagency.com/insuranceScore
 
with a JSON body like this:
{
"insuranceScoreRequest": {
"firstName": "Joe",
"lastName": "Bloggs",
"houseNumber": 67,
"postcode": "N00 BDY",
"dob": "01/01/1970",
"policyType": 1
}
}
 
where policyType represents the type of insurance to request a risk score for, and can take the following values:
0 - home insurance policy
1 - motor insurance policy
2 - endowment policy
3 - commercial policy
4 - public liability insurance policy
 
The response body will look like this:
{
"insuranceScoreResponse": {
"timestamp": "2013-05-05T10:46:50.52Z",
"customerId": 55446511,
"score": 341
}
}
 
where customerId is an 8-digit number integer and score is an integer from 100 to 999.
Based on this information, you create two JSON schemas:
One for the request message
One for the response
When writing JSON schema you might find it helpful to see the JSON schema specification and related tutorials, which are available on the JSON schema website:
The website also contains a list of validation tools and libraries that might be helpful. Consider validating your schema before running DFHJS2LS. One useful tool is the online JSON schema validator available at the following website:
11.2.1 Writing the request schema
Begin with the request message. Example 11-2 shows a first attempt at a schema that gives the basic structure for the message. This schema expresses the structure of the data, and also states that all of the properties are required, because the documentation does not state any of the fields are optional. If you do not mark properties as required, DFHJS2LS will generate existence flags in the language structure that are set at run time if the fields are present in the transformed JSON.
Example 11-2 Basic schema for the insuranceScoreRequest
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"required": [
"insuranceScoreRequest"
],
"properties": {
"insuranceScoreRequest": {
"type": "object",
"properties": {
"dob": {
"type": "string"
},
"firstName": {
"type": "string"
},
"houseNumber": {
"type": "string"
},
"lastName": {
"type": "string"
},
"policyType": {
"type": "string"
},
"postcode": {
"type": "string"
}
},
"required": [
"dob",
"firstName",
"houseNumber",
"lastName",
"policyType",
"postcode"
]
}
}
}
The next step is to add some constraints on the sizes of the fields, because otherwise DFHJS2LS assumes the default values, resulting in much padding in the language structure.
For the string fields, use the minLength and maxLength properties, and for integer fields use maximum and minimum. You also make some inferences about the lengths of some of these fields.
The resulting schema is shown in Example 11-3. Notice that the policyType field has a maximum value of 999 specified, despite the documentation stating the highest acceptable value is 4. This is because a field with a maximum value less than 256 is mapped to a COBOL PIC X DISPLAY declaration (because no suitably small binary type is provided in COBOL). The value of 999 maps to a PIC 999 declaration which is more suitable for your application.
Example 11-3 Improved schema for insuranceScoreRequest
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"required": [
"insuranceScoreRequest"
],
"properties": {
"insuranceScoreRequest": {
"type": "object",
"properties": {
"dob": {
"type": "string",
"minLength": 10,
"maxLength": 10
},
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 50
},
"houseNumber": {
"type": "string",
"minLength": 1,
"maxLength": 4
},
"lastName": {
"type": "string",
"minLength": 1,
"maxLength": 50
},
"policyType": {
"type": "integer",
"minimum": 0,
"maximum": 999
},
"postcode": {
"type": "string",
"minLength": 6,
"maxLength": 8
}
},
"required": [
"dob",
"firstName",
"houseNumber",
"lastName",
"policyType",
"postcode"
]
}
}
}
11.2.2 Writing the response schema
Next, you create a schema for the JSON response message, in a similar way as you did for the request message. Example 11-4 shows the schema. Note the use of the date-time value of the format property. This indicates that the value is a time stamp in RFC3339 format, which at run time is converted to CICS ABSTIME format.
Example 11-4 JSON schema for insuranceScoreResponse
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"properties": {
"insuranceScoreResponse": {
"type": "object",
"properties": {
"customerId": {
"type": "integer",
"minimum": 0,
"maximum": 99999999
},
"score": {
"type": "integer",
"minimum": 100,
"maximum": 999
},
"timestamp": {
"type": "string",
"format": "date-time"
}
},
"required": [
"customerId",
"score",
"timestamp"
]
}
},
"required": [
"insuranceScoreResponse"
]
}
11.3 Generating the language structures
Now, you have a description of the interface to the service in the form of a JSON schema. Next, generate a language structure to be used by the client application and the necessary artifacts for CICS to transform between JSON and application data.
You do this by running DFHJS2LS, which is the JSON assistant used when starting from a JSON schema. This process is similar to using DFHJS2LS when developing a JSON web service provider, as described in 10.4.2, “Mapping the JSON schema to language structures” on page 117, but you use some different parameters.
Run DFHJS2LS twice, once with the JSON schema for the request, and once with the JSON schema for the response. Each time, a language structure and a CICS bundle containing a JSONTRANSFRM bundle part are generated.
The bundle is generated on zFS, and is later installed into CICS. The CICS TS Feature Pack for Mobile Extensions V1.0 supplies a JCL procedure to start DFHJS2LS in the SDFHMOBI library. The JCL to start it with the request schema is shown in Example 11-5.
Example 11-5 JCL to run DFHJS2LS for the request language structure
//JS2LS JOB (MYSYS,AUSER),MSGCLASS=H,
// CLASS=A,NOTIFY=&SYSUID,REGION=0M
// JCLLIB ORDER='CICS510.SDFHMOBI'
//*
//JS2LS EXEC DFHJS2LS,USSDIR='cics680',
// PATHPREF='',JAVADIR='java6_64/J6.0_64'
//INPUT.SYSUT1 DD *
LOGFILE=/u/cicsuser/genapp/json/logs/insuranceScoreRequest.log
PDSLIB=//USER.JS2LS.COPYLIB
PDSMEM=SCREQ
LANG=COBOL
MAPPING-LEVEL=3.0
JSONTRANSFRM=SCOREREQ
BUNDLE=/u/cicsuser/genapp/json/client/insuranceScoreRequest
CHAR-VARYING=NO
JSON-SCHEMA=/u/cicsuser/genapp/json/insuranceScoreRequest.json
*/
You must supply the following parameters when starting DFHJS2LS:
LOGFILE The zFS file where a log of the DFHJS2LS processing is created.
PDSLIB The partitioned data set where the language structure is created.
PDSMEM The name of the member in the partitioned data set that is created.
LANG The high-level language in which the language structure is created.
MAPPING-LEVEL The level of mapping applied by the JSON assistant. 3.0 or greater can be used, but earlier mapping levels are supported only for compatibility with the SOAP web services assistants.
JSONTRANSFRM The name of the JSONTRANFRM bundle part that will be created by CICS when the bundle is installed.
BUNDLE The zFS location of the bundle that is created.
CHAR-VARYING=NO Suppresses the generation of length fields for variable-length string values.
JSON-SCHEMA The zFS location of the JSON schema used as input.
Full details of all the parameters for DFHJS2LS is found in the “DFHJS2LS: JSON schema to high-level language conversion for linkable interface” topic of the CICS TS Feature Pack for Mobile Extensions Information Center. The following website is for CICS TS 5.1:
Example 11-6 shows the JCL for the response structure. This is similar to the JCL for the request schema, except for the values of the LOGFILE, PDSMEM, JSONTRANSFRM, and BUNDLE parameters.
Example 11-6 JCL to run DFHJS2LS for the response language structure
//JS2LS JOB (MYSYS,AUSER),MSGCLASS=H,
// CLASS=A,NOTIFY=&SYSUID,REGION=0M
// JCLLIB ORDER='CTS.CICS510.SDFHMOBI'//*
//* The following line is changed by APAR PK04055 @BA04055
//JS2LS EXEC DFHJS2LS,USSDIR='cics680',
// PATHPREF='',JAVADIR='java6_64/J6.0_64'
//INPUT.SYSUT1 DD *
LOGFILE=/u/cicsuser/genapp/json/logs/insuranceScoreResponse.log
PDSLIB=//USER.JS2LS.COPYLIB
PDSMEM=SCRESP
LANG=COBOL
MAPPING-LEVEL=3.0
JSONTRANSFRM=SCORERESP
BUNDLE=/u/cicsuser/genapp/json/client/insuranceScoreResponse
CHAR-VARYING=NO
JSON-SCHEMA=/u/cicsuser/genapp/json/insuranceScoreResponse.json
*/
When running DFHJS2LS, the following error message can occur:
DFHPI9523E An unexpected error occurred whilst processing file "//USER.JS2LS.COPYLIB(CRREQ01)". The problem is: "//USER.JS2LS.COPYLIB(CRREQ01)".
This normally indicates that the partitioned data set (PDS) cannot be opened for output because a user had a member of the PDS open for editing in Interactive System Productivity Facility (ISPF) or IBM Rational Developer for IBM System z.
Also, if you run DFHJS2LS more than one time, with the same value of BUNDLE parameter, the following message can occur:
DFHPI9683W Bundle directory "/u/cicsuser/genapp/client/insuranceScoreRequest" already exists and may contain files that are inconsistent with the new Bundle manifest file.
This message can be safely ignored if you have maintained the same value of the JSONTRANFRM parameter and are rerunning the assistant due to a change in the input schema or mapping parameters. However, if a different bundle already exists at this location, you must choose a different one or delete the existing directory first.
11.4 Defining the CICS resources
The next step is to define the resources used by CICS. These resources are named in the application, and are required to test it, so they must be defined before the program can be developed. You define BUNDLE resources for each JSONTRANSFRM and a URIMAP resource using the CICS Explorer.
11.4.1 Defining the BUNDLE resources
When you run DFHJS2LS to create the language structures (see 11.3, “Generating the language structures” on page 135), it also creates a bundle directory on zFS. This contains a JSBIND file and a JSONTRANFRM bundle part, which CICS uses to perform the transformation between application data and JSON. You must create and install a CICS BUNDLE resource for both the request and response bundles.
Follow these steps to create and install the BUNDLE resources in CICS Explorer:
1. Click File → New → Other.
2. In the New window, expand CICS Definitions and select Bundle Definition, as shown in Figure 11-2. Click Next.
Figure 11-2 Creating a new bundle definition
3. On the Create Bundle Definition page, complete these steps:
a. Enter the name of a CICSplex where the definition will be created in the CICSplex field.
b. If you want to create the resource in a CICS system definition data set (CSD), for example if you are connected to a stand-alone CICS region, select the Region (CSD) check box and enter the name of the region in the adjacent field.
c. Enter the name of the CSD or resource group where the bundle definition will be created in the Resource/CSD Group field.
d. Enter the name of the bundle for the request transform in the Name field.
e. Click Browse and choose the bundle directory on zFS that was created by DFHJS2LS when processing the request schema.
The completed page is shown in Figure 11-3.
Figure 11-3 Specifying the attributes of a new bundle definition
4. Click Finish.
5. Repeat steps 1-4, entering details for the response transform.
6. Select Definitions → Bundles Definitions to show the Bundle Definitions view.
7. In the CICSplex Repositories view, select the group that you specified in step 3c.
8. Select both of the bundle definitions listed in the Bundle Definitions view, as shown in Figure 11-4.
Figure 11-4 Locating the bundle resources to install
9. Right-click the selected definitions and click Install.
10. In the Perform Operation window, select the region or system group into which you want to install the definitions, and then click OK.
You can now view the BUNDLEs and BUNDLEPARTs to verify they installed correctly. To view the BUNDLEs in CICS Explorer, click Operations → Bundles. To view the corresponding BUNDLEPARTs, right-click a BUNDLE and select Show Bundle Parts. You can see a single JSONTRANSFRM BUNDLEPART for each BUNDLE, as shown in Figure 11-5.
Figure 11-5 Viewing the Bundle Parts for the credreq bundle
11.4.2 Defining the URIMAP resource
You can define a URIMAP resource that specifies the URI of the JSON service that you are writing a client application for. This is not required (you can specify all the parameters on the WEB OPEN and WEB CONVERSE commands instead). However, creating a URIMAP resource has the following advantages:
You can use an SSL client certificate to authenticate with the server.
You can avoid coding the URI in your application, so that it can be updated by simply modifying the URIMAP definition.
You can enable connection pooling, so that all of the connections to the same host share a single HTTP connection.
To define and install a URIMAP resource in CICS Explorer, follow these steps:
1. Click File → New → Other.
2. In the New window, expand CICS Definitions, and URI Map Definition. Click Next.
3. On the Create URI Map Definition page, complete these steps:
a. Enter the name of a CICSplex where the definition will be created in the CICSplex field.
b. If you want to create the resource in a CSD (for example if you are connected to a stand-alone CICS region), select the Region (CSD) check box and enter the name of the region in the adjacent field.
c. Enter the name of the CSD or resource group where the URIMAP definition will be created in the Resource/CSD Group field.
d. Enter the name of the URIMAP in the Name field.
e. Enter the host where the JSON web services is located in the Host field.
f. Enter the path to the service in the Path field.
g. Click Client, and enter the TCP/IP port for the service in the Port field.
The completed page is shown in Figure 11-6 on page 141.
Figure 11-6 Specifying the attributes of the URIMAP
4. Click Finish.
5. In the URI Map Definition editor, follow these steps:
a. If you want connections that were opened using this URIMAP resource to be pooled for reuse, specify the SOCKETCLOSE attribute as the length of time for which CICS keeps the connection in the pool after the application program has finished using it. See the “Connection pooling for HTTP client performance” topic in the CICS Information Center for information about how CICS manages pooled connections, and how connection pooling improves application performance.
For CICS TS 5.1, this is found at the following website:
b. To configure security for the connection to the server, see Chapter 7, “Security and workload management” on page 69.
c. Press Ctrl + S to save your changes.
d. From the resource drop-down menu, select Install.
e. In the Perform Operation window, select the region or system group that you want to install the definitions into, and then click OK.
Figure 11-7 illustrates the URI Map Definition editor.
Figure 11-7 Editing the attributes of the URIMAP
11.5 Developing the application program
The final task is to write the application program that will call the remote service. A complete sample COBOL program is provided, and this section provides information about each part of it.
11.5.1 Transforming the request data
The first task that your application program might need to perform is to generate the JSON request message. Whether you need to do this depends on the service you are calling. Some JSON web services can take input from the URI, either from the path or the query string, rather than the request body.
If the service is called using the HTTP GET method, a request body cannot be provided. In the scenario presented in this chapter, the service uses a request-response pattern using the POST method, so both the request and response are contained in the HTTP body. If you do not need to generate a JSON request, you can skip to 11.5.2, “Sending the request” on page 145. You can use the linkable interface to transform application data to JSON for the request message. You must first set up the containers as noted in the following steps:
1. Put the name of the JSONTRANSFRM bundle part for the request (as specified by the JSONTRANSFRM parameter on DFHJS2LS) in the DFHJSON-TRANSFRM container.
2. If you want to use a JVM server other than DFH$AXIS, put the name of the JVMSERVER resource in the DFHJSON-JVMSERVR container.
3. Put the application data that you want to transform in the DFHJSON-DATA container.
4. Then perform a LINK PROGRAM to DFHJSON, passing the channel where you have put the containers.
Example 11-7 is an excerpt from the sample COBOL program that performs these tasks.
Example 11-7 Sample COBOL to transform the request message
MOVE 'JOE' TO FIRSTNAME
MOVE 'BLOGGS' TO LASTNAME
MOVE 67 TO HOUSENUMBER
MOVE '10/10/1984' TO DOB
MOVE 'N00 BDY' TO POSTCODE
MOVE 3 TO POLICYTYPE
 
EXEC CICS PUT CONTAINER('DFHJSON-TRANSFRM')
CHANNEL('CHAN')
FROM('SCOREREQ')
CHAR
RESP(CICS-RESP)
END-EXEC
PERFORM CHECK-RESP
 
EXEC CICS PUT CONTAINER('DFHJSON-DATA')
CHANNEL('CHAN')
FROM(REQUEST-DATA)
RESP(CICS-RESP)
END-EXEC
PERFORM CHECK-RESP
 
* Link to the transfomer
EXEC CICS LINK PROGRAM('DFHJSON')
CHANNEL('CHAN')
RESP(CICS-RESP)
END-EXEC
PERFORM CHECK-RESP
Handling Errors
If an error occurs during transformation, CICS puts an error code in the DFHJSON-ERROR container and returns to the application. Under some circumstances, CICS also puts further information about the error in the DFHJSON-ERRORMSG container. After linking to DFHJSON, you can check for the presence of the DFHJSON-ERROR container and take action accordingly.
Some types of errors indicate a configuration error, such as the JSONTRANSFRM resource not being defined or enabled. Other types of errors indicate a problem with the data transformation, such as invalid JSON or a mismatch between the type of data provided and the data that was expected. In these situations, it can be helpful to capture the contents of the DFHJSON-ERRORMSG container.
Example 11-8 shows a COBOL procedure that can be started after linking to DFHJSON. It checks for the DFHJSON-ERROR container, and (if the error container is present) displays the error code on the terminal. If the DFHJSON-ERRORMSG container is present, the first 256 byes of its contents are sent to the transient data queue (TDQ) CESE using a COBOL DISPLAY statement.
Example 11-8 Sample COBOL routine for handling errors return by the linkable interface
HANDLE-ERROR.
EXEC CICS GET CONTAINER('DFHJSON-ERROR') CHANNEL('CHAN')
INTO(TRANS-RESP)
RESP(CICS-RESP)
END-EXEC
IF CICS-RESP EQUAL DFHRESP(NORMAL)
* Error container is present, output value
MOVE TRANS-RESP TO ERROR-DISPLAY
EXEC CICS SEND TEXT FROM(BAD-RESP-MSG)
ERASE END-EXEC
 
MOVE 256 TO ERROR-LENGTH
 
EXEC CICS GET CONTAINER('DFHJSON-ERRORMSG')
CHANNEL('CHAN')
INTO(ERROR-MSG)
RESP(CICS-RESP)
FLENGTH(ERROR-LENGTH)
END-EXEC
 
IF CICS-RESP EQUAL DFHRESP(NORMAL)
DISPLAY ERROR-MSG
END-IF
EXEC CICS RETURN END-EXEC
END-IF
EXIT.
 
Full details of the possible errors can be found in the “DFHJSON-ERROR container” topic in the CICS TS Feature Pack for Mobile Extensions Information Center. For CICS TS 5.1 this information can be found at the following website:
11.5.2 Sending the request
The next step is to send the request to the JSON web service over HTTP. This is accomplished using WEB commands.
Opening the connection
First, open a connection using a WEB OPEN command. This opens an HTTP connection, or reuses an existing one (if connection pooling is enabled). If you use a URIMAP resource as described in 11.4.2, “Defining the URIMAP resource” on page 140, you can name the resource on the WEB OPEN command. Otherwise, you must code the HOST and PORTNUMBER parameters to specify the server to connect to.
A WEB OPEN command using a URIMAP is shown in Example 11-9. The SESSTOKEN specifies a data area into which CICS will put a session token. This must be specified on all subsequent WEB commands to identify the connection.
Example 11-9 Opening the connection to the remote service using a URIMAP
EXEC CICS WEB OPEN
URIMAP('CREDSERV')
RESP(CICS-RESP)
RESP2(CICS-RESP2)
SESSTOKEN(TOKEN) END-EXEC
Sending the data and receiving the response
Now you are ready to make the request to the JSON web service. You will use a WEB CONVERSE command to send the request and receive the response together. You can also use separate WEB SEND and WEB RECEIVE commands.
The parameters that you specify on the command depend on the interface to the service that you are calling. For example, if your service takes input from the query string, you must specify the QUERYSTRING parameter, but if your service expects a JSON body, you must specify the FROM or CONTAINER parameters.
Specifying the path to the service
Example 11-10 on page 146 uses the URIMAP parameter. CICS then uses the PATH attribute of the corresponding URIMAP to obtain the path to the JSON web service. Alternatively, you can use the PATH and optionally PATHLENGTH parameters to specify the path directly. If your service requires a query string, specify the QUERYSTRING parameter and optionally the QUERYSTRINGLEN parameter.
Specifying the HTTP method and media type
You must specify the HTTP method used to call the JSON web service. You can either specify it directly on the command (as shown in Example 11-10 on page 146), or use the METHOD parameter. You must also specify the MEDIATYPE parameter to indicate the type of data that you are sending. For JSON, the usual value is application/json, but other values can be supported, so you can check with the operator of the JSON web service as to what they expect.
 
Note: The data area specified on the MEDIATYPE parameter must be 56 bytes in length, so you must add trailing spaces to the value.
Specifying the request and response data
If your service expects JSON in the request body, you must code either the CONTAINER or FROM parameters. If you use the CONTAINER parameter, you can pass the DFHJSON-JSON container returned by the linkable interface, as shown in Example 11-10.
If your service will provide JSON data in the response that you want to transform, you can also specify DFHJSON-JSON on the TOCONTAINER parameter so that the response data can be passed directly to the linkable interface. If using the CONTAINER or TOCONTAINER parameters, you can specify the channel using the corresponding CHANNEL or TOCHANNEL parameters, or CICS uses the current channel.
Additionally, you can specify the STATUSCODE parameter. This is a data area in which CICS places the HTTP response code. Your application can check this value to determine if the operation was completed successfully, or if an error occurred.
Example 11-10 shows the complete WEB CONVERSE command.
Example 11-10 WEB CONVERSE command to communicate with the insurance score web service
EXEC CICS WEB CONVERSE
URIMAP('CREDSERV') POST
CONTAINER('DFHJSON-JSON')
CHANNEL('CHAN')
MEDIATYPE(CONTENT-TYPE)
TOCONTAINER('DFHJSON-JSON')
TOCHANNEL('CHAN')
STATUSCODE(HTTP-RESP)
STATUSTEXT(HTTPSTATUS)
RESP(CICS-RESP)
RESP2(CICS-RESP2)
SESSTOKEN(TOKEN) END-EXEC
Tidying up
After the WEB CONVERSE, or the final WEB SEND or WEB RECEIVE command, you can issue a WEB CLOSE command. This signals to CICS that the application has finished using the HTTP connection. If you use connection pooling, the HTTP connection might not be closed, but instead returned to the pool for reuse. Example 11-11 shows the WEB CLOSE command.
Example 11-11 WEB CLOSE command to indicate the end of the session
EXEC CICS WEB CLOSE SESSTOKEN(TOKEN) END-EXEC
11.5.3 Transforming the response body
If the JSON web service that you have called provides JSON in the response body, you can transform this to application data for further processing. This can be accomplished by using the linkable interface in a similar way to that described in 11.5.1, “Transforming the request data” on page 143.
Some services indicate the success or failure of the operation simply using the HTTP response code, in which case this step is not required. This section explains how the example program transforms the response from the insurance score service into application data.
The steps to use the linkable interface to transform JSON to application data are similar to those used to transform application to JSON, except that some of the containers differ. Before calling the transformer, set up the containers using the following points:
Put the name of the JSONTRANSFRM for the response (as specified by the JSONTRANSFRM parameter on DFHJS2LS) in the DFHJSON-TRANSFRM container.
If you want to use a JVM server other than DFH$AXIS, put the name of the JVMSERVER resource in the DFHJSON-JVMSERVR container.
Put the JSON that you want to transform in the DFHJSON-JSON container.
 
Note: If you have previously used the linkable interface to transform application data to JSON, you must either use a DELETE CONTAINER command to delete the DFHJSON-DATA container before calling DFHJSON, or use a different channel. Otherwise, both containers will be present on the channel and you will receive error code 14.
Then, use a LINK PROGRAM command to call DFHJSON. If the transformation occurs successfully, CICS puts the application data corresponding to the JSON that you provided in the DFHJSON-DATA container. If an error occurs, CICS puts an error code in the DFHJSON-ERROR container, see “Handling Errors” on page 144 for more information. Example 11-12 demonstrates how to set up the containers and call the linkable interface to transform JSON.
Example 11-12 Calling linkable interface to transform the JSON response from insurance score service
EXEC CICS DELETE CONTAINER('DFHJSON-DATA')
CHANNEL('CHAN')
END-EXEC
 
EXEC CICS PUT CONTAINER('DFHJSON-TRANSFRM')
CHANNEL('CHAN')
FROM('SCORERESP')
RESP(CICS-RESP)
CHAR
END-EXEC
PERFORM CHECK-RESP
 
* Link to the transfomer
EXEC CICS LINK PROGRAM('DFHJSON')
CHANNEL('CHAN')
RESP(CICS-RESP)
END-EXEC
PERFORM CHECK-RESP
 
PERFORM HANDLE-ERROR
 
EXEC CICS GET CONTAINER('DFHJSON-DATA') CHANNEL('CHAN')
INTO(RESPONSE-DATA)
RESP(CICS-RESP)
END-EXEC.
PERFORM CHECK-RESP
11.6 Testing the sample application
If you want to test the sample application, you will need to set up the client application and the provider service. You can follow the steps in the preceding sections to create the client application, or you can use the materials supplied with this book. For information about how to obtain these, see Appendix C, “Additional material” on page 175. In either case, you must perform the following tasks sequentially:
1. Follow the steps in 5.2.2, “How to configure CICS as a service provider” on page 34 to configure your system for JSON web services.
2. Copy the credit.wsbind file provided with this book to the pickup directory of the PIPELINE you created in “Defining and installing a PIPELINE” on page 40, and perform a PIPELINE scan.
3. Create the resource definitions for the requester application as described in 11.4, “Defining the CICS resources” on page 137 if you have not done so already. You can use the bundles supplied with the book if you do not want to create them yourself.
4. Compile the sample programs CREDIT and REQUEST and put them in a load library that is part of the DFHRPL concatenation. Alternatively, create and install a LIBRARY definition that references the load library.
5. If you do not use program autoinstall, create and install PROGRAM definitions for CREDIT and REQUEST.
6. Create and install a TRANSACTION definition that calls REQUEST.
You can then start the transaction from a terminal. If it completes successfully, you can see a message on the terminal indicating the insurance score returned from the service.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset