In this blog post I'll show you how I put together a sample application which makes use of the programs and data provided by the the GENAPP support pac.

The architecture of the completed solution looks like

image

Setting up CICS TG

Configuring the Gateway daemon for http requests

To allow the Gateway daemon to receive and process http requests I added the following configuration to the SECTION GATEWAY part of the configuration file:

SUBSECTION HTTP
   port=26682
ENDSUBSECTION

This tells the Gateway daemon that I want it to listen for http requests on port 26682. To check this configuration is correct, the following log message is output during the Gateway daemon initialization.

06/11/14 11:42:04:672 [0] CTG6524I TESTA    Successfully started handler for the http: protocol on port 26882

Creating the JSON web services

The application makes use of two web services, one to get a list of all the customers and the other to get all the details for a particular customer.

Create the web service bind files

The critical piece of configuration for each web service is the web services bind (WSBind) file. This file contains the information required to perform the transformation between a JSON object and a CICS application payload that can be passed to the CICS program.

To generate the bind files I made use of the web services assistant shipped with CICS TG which can generate a bind file from either the language structure definition of the data as the CICS program uses it or from a json schema describing the data as the web service client provides it.

The CICS program for retrieving a customer's details already existed so the bind file was generated from the COBOL source describing the COMMAREA structure. The parameters passed to the assistant for this were:

LANG=Cobol 
MAPPING-MODE=LS2JS 
JSON-SCHEMA-REQUEST=/u/smithso/mobile/getcustomerrequest.json
JSON-SCHEMA-RESPONSE=/u/smithso/mobile/getcustomerresponse.json
LS-REQUEST=//'SMITHSO.MOBILE.CUSTREC' 
LS-RESPONSE=//'SMITHSO.MOBILE.CUSTREC' 
WSBIND=/u/smithso/mobile/getcust.wsbind
PGMNAME=GETCUST
PGMINT=COMMAREA

As well as the bind file this operation produces two json schema files which describe the JSON objects passed to and from this web service. This information is then used by the mobile application to ensure the call to the web service is correct.

Unfortunately there was no existing program to retrieve all the customers in the customer database so a new program had to be created. As this would be a brand new program I could start from the mobile application and decide how the information should be passed back and forth. To start I created a JSON schema to describe how the data would be formatted:

{
    "title": "Retrieve all customers schema",
    "type": "object",
    "properties": {
        "customers": {
            "type": "array",
            "minItems": 0,
            "items": {
                "type": "object",
                "properties": {
                    "customerid": {
                        "type": "string",
                        "maxLength": 10
                    },
                    "firstName": {
                        "type": "string",
                        "maxLength": 10
                    },
                    "lastName": {
                        "type": "string",
                        "maxLength": 20
                    }
                },
                "required": ["customerid", "firstName", "lastName"]
            }
        }
    },
    "required": ["customers"]
}

and then used the web services assistant to generate the high level language structures:

LANG=C 
MAPPING-MODE=JS2LS 
JSON-SCHEMA-REQUEST=/u/smithso/mobile/allcust.json
JSON-SCHEMA-RESPONSE=/u/smithso/mobile/allcust.json
LS-REQUEST=//'SMITHSO.MOBILE.ALLCUSTI' 
LS-RESPONSE=//'SMITHSO.MOBILE.ALLCUSTO' 
WSBIND=/u/smithso/mobile/allcust.wsbind
PGMNAME=ALLCUST
PGMINT=CHANNEL

which produced the bind file and the language structure elements. Prefering to code in C rather than COBOL, I chose to produce C header files to describe the data format in the new program.

Configure the CICS Transaction Gateway

Once the WSBind files had been created I needed to configure the Gateway daemon to make the web services available. Each web service requires a new section in the configuration file, so for the demo the configuration file contains the following:

SECTION WEBSERVICE = CUSTINQ 
    uri = customers/inquire
    bindfile = /u/smithso/mobile/allcust.wsbind
    server = IY2GNS51
ENDSECTION

SECTION WEBSERVICE = GETCUST 
    uri = customers
    bindfile = /var/cicstg/getcust.wsbind
    server = IY2GNS51
ENDSECTION

The configuration options have the following affect

  • The name of the section is used to identify this web service in the Gateway Daemon, and is used by the statistics in the creation of the statistics group for this web service
  • uri specifies the configurable part of the URL which client applications can use to invoke the webservice. For the GETCUST webservice it will be available at http://<hostname>:26882/json/customers
  • bindfile specifies the location of the bindfiles we created earlier
  • server specifies the name of the CICS server requests sent to this web service are sent to. This is an optional parameter, and if one isn't set then the default server is used.

When the Gateway daemon is started the following log messages are written which shows that the web services have been successfully created:

06/11/14 11:42:04:683 [0] CTG9920I TESTA    JSON web service CUSTINQ started successfully
06/11/14 11:42:04:683 [0] CTG9920I TESTA    JSON web service GETCUST started successfully

Building the mobile application

In order to easily build a mobile application that could be deployed on a variety of platforms I decided to make use of IBM Mobile Foundation to build the application as this provides an easy way to do this. There are two parts to the application, a Mobile Foundation adapter and the program to run on the mobile device.

Creating the Mobile Foundation Adapter

The Mobile Foundation adapter provides the link between the mobile application and the CICS TG. In it I configured the hostname and port where the CICS TG is, the port number matches the value configured in SECTION HTTP.

I then created two procedures, one for each of the web services that will be called by the application. The general outline of these procedures is to create the request JSON object, call the web service and return the result of the call. To get all the customers the procedure looks like:

function getCustomers(){
   var payload = "{\"customers\":[{}]}";

   var input = {
       method : 'post',
       returnedContentType : 'json',
       path : 'json/customers', 
       body : {
          content: payload,
          contentType : 'application/json'
       }
   };

   return WL.Server.invokeHttp(input);
}

The input object describes how the web service is invoked and the the results of invoking the web service are returned back to the caller of this function. This allows me to abstract away the full payload that needs to be sent to the webservice and send the response back to the mobile application.

Creating the Mobile Foundation Application

The mobile application itself is a hybrid application written in HTML5 and JavaScript as this allows for the same application to be deployed to a variety of mobile devices without the need to write specific applications for each mobile platform.

To call the procedures in the Mobile Foundation Adapter I use the client API provided by Mobile Foundation as in the following code snippet

var invocationData = {
   adapter : 'CTGAdapter',
   procedure : 'getCustomers'
};

WL.Client.invokeProcedure(invocationData, {
   onSuccess : displayCustomers,
   onFailure : errorLog
});

The invocationData object contains the name of the Adapter that contains the procedure to call and the name of that procedure. This object is then passed to the invokeProcedure function along with the callback functions which will be called depending on whether the procedure call succeeds or fails.

To interact with the mobile device I make use of the Cordova plug-ins to access the camera and other applications on the device. In order to get a picture from the camera the following code snippet was used to open the camera, and then add the resulting picture to the page.

function takePhoto(){
   navigator.camera.getPicture(cameraSuccess, 
                               cameraError, 
                               {quality: 50, 
                                destinationType: Camera.DestinationType.DATA_URL});  
}

function cameraSuccess(imageData) {
   $('#images').append('<img style="width:60px;height:60px;" src="data:image/jpeg;base64,' + imageData +'"/>');
}

function cameraError(message) {
   WL.Logger.info(message);
}

Conclusion

Through the creation of some new configuration pieces in the CICS TG and making use of the easy application design functionality provided by IBM Mobile Foundation I produced a professional looking application quickly and easily which leverages information stored in a back-end CICS TS system without any changes to the CICS server.

image

Join The Discussion

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.