SOAP Provider for 3270 CICS Applications

By | August 1, 2013

The tooling CICS provides for the building and execution of SOAP Web Services providers makes it a very reasonable way to “modernize” CICS applications that are designed to be invoked via COMMAREA or Channel/Container.  But, for 3270 terminal based applications–not so good out of the box.   There are third-party software solutions, some of which seem pretty useful.  HostBridge comes to mind. Also GT Software’s Ivory and Attachmate’s Verastream Bridge Integrator.

Another CICS application modernization paradigm, although a bit older, is the Link3270 Bridge. This facility allows you to write one program to drive one or more 3270 applications allowing the driving application to address screen fields “by name”, using the BMS Map copybook (ADS or application data structure).  Since the interface is via a CICS LINK API call, the driving program could be a batch program connecting via EXCI, or ECI, another 3270 application, or . . . how about a Web Service provider program?

1 + 1 = ?

The idea here is that the Web Service tooling makes it pretty convenient to build a Web Service provider for a application that has copybooks describing the input and output.  Since the interface with BMS 3270 screens is also via copybooks, it is fairly straightforward to write a Web Service provider program that front-ends a 3270 application via the Link3270 Bridge using the BMS map copybooks to feed the Web Services tooling to generate an initial WSDL  What you end up with is rather like screen automation that has traditionally done using a terminal emulator’s HLLAPI, but this will perform much better (less network activity) and has the advantage that the copybooks are common so that the source management system can detect changes to the BMS map and trigger rebuilding the Web Services application.

Feasibility

Before starting off coding, you should check to ensure the 3270 application that you want to use for your project is going to work OK with the Link3270 Bridge.  First, review the restrictions. Second, install and run the 3270 Bridge Pass-through transaction from the  CA1E Supportpac which allows you to test a 3270 application via the 3270 Bridge from a terminal and gives you some good diagnostic information.

We’ll skip some steps here and use the IBM supplied sample NACT application.  We already know it works with the Link3270 Bridge because, well, IBM uses it in their Link3270 sample.  Plus we can use the code in that sample to check our own coding and won’t have to explain how to do bridge coding since that’s already in the sample.

Flow

Imagine a use case where a customer service user needs to find a customer given their name and from the list returned from a lookup chooses the one of whom they want so see the account details. The Web Service operations we’re going to implement to support this are,

  • Account search by name
  • Account display by account number

These are functions available from the NACT transaction Accounts Menu:

NACT Accounts Menu

NACT Accounts Menu

NACT Account List

NACT Account List

NACT Account Details

NACT Account Details

Click to enlarge

One bit of complexity is on the Account List interaction when there are more to list than fit on the screen and we must PF8 to scroll through the list.

Process

Generally, this is how we plan to proceed:

  1. Build new copybooks, one for each web service operation we are going to build, using as a basis the NACT BMS map copybooks generated when the (DFH0MNA) map was assembled.
  2. Generate WSDL for these copybooks using the CICS Web service assistant (DFHLS2WS).
  3. Combine the two resulting WSDL so we have one that defines s single service with two operations. Edit the WSDL to adjust for specific business requirements; for example, allowing for optional fields (minoccurs=0 or nillable=true).
  4. Build new copybooks from this WSDL using the CICS web service assistant (DFHWS2LS).
  5. Code our program to implement the service.
  6. Test.  Yeah, sure we will.  😉

This is somewhat like what the IBM Redbook Application Development for CICS Web Services refers to a meet-in-the-middle approach.

1. Build New Copybooks

For the first pass at building the copybooks, I eliminated as many of the fields I thought were not necessary and also renamed the fields from their BMS names so something more descriptive since that is what will be present in the WSDL and XML  So for the AccountList operation, the request will only need Surname and Firstname (and first name will be optional–I’ll deal with that later):

*01  ACCTMNUI.
 01  AccountListRequest.
*    02  SNAMEMI  PIC X(18).
     02  Surname  PIC X(18).
*    02  FNAMEMI  PIC X(12).
     02  FirstName PIC X(12).

And the  reply:

*01  ACCTMNUO REDEFINES ACCTMNUI.
 01  AccountListReply.
*    02  DFHMS1 OCCURS 6 TIMES.
*      03  SUMLNMO  PIC X(79).
     02  SummaryLine PIC X(79) OCCURS 6 TIMES.
*    02  MSGINVMO  PIC X(65).
     02  Message   PIC X(65).

The SummaryLine is actually multiple columns on the screen which could be broken up into separate fields (and thus separate WSDL/XML elements).

Similar process for AccountDisplay.

2. Generate WSDL

This is the sort of JCL I used to generate WSDL from these copybooks:

// JCLLIB ORDER=(XXXXXXXX.XDFHINST)
//DFHLS2WS EXEC DFHLS2WS,
// JAVADIR='java/J6.0',
// PATHPREF=,
// REGION.JAVAPRG1=256M
//INPUT.SYSUT1 DD *
PDSLIB=//XXXXXXX.SRC.COB
REQMEM=ALSTREQ
RESPMEM=ALSTREP
LANG=COBOL
PGMNAME=LISTWS
TRANSACTION=NAWS
URI=Account
PGMINT=COMMAREA
WSBIND=/tmp/AccountList.wsbind
WSDL=/tmp/AccountList.wsdl
LOGFILE=/tmp/AccountList.log
MAPPING-LEVEL=2.2
SOAPVER=ALL

Here’s the WDSL that was generated:  AccountList.wsdl
And here is the one for AccountDetail: AccountDetail.wsdl

3. Combine the WSDL

This is a bit complicated but the indentation helps.  Also, I used a different program name for each DFHLS2WS run so it would be easier to keep things straight.  There programs are phony anyway since we will never use the WSBIND files from these two assistant runs.  First I copied the AccountList.wsdl to AccountService.wsdl then used ISPF PDF Edit CUT and PASTE to copy sections of AccountDetails.wsdl into it.

  • The schemas between <types> & </types>
  • The messages
  • The operation under portType
  • The operations in the binding sections.
  • Change all the “targetNamespace” values to be the same.
    CHANGE ALL "DETAILWS.ADET" "LISTWS.ALST", for example.
  • Also removed an extraneous field that is a literal on the map for Charge Limit.
  • I left a bunch of names as LISTWSxxxxx even when the WSDL now includes the detail operation as well, but I think that is pretty irrelevant to the final outcome.  It you are doing this for real, you should probably use a real WSDL editor and rationalize the names for better documentation.

In the AccountListRequest schema, I edited the FirstName element to have nillable=”true” since the element is optional.  In the AccountListReply schema, I changed minOccurs for SummaryLine from

The result:  AccountService.wsdl

4. Build new Copybooks

Now we feed the WSDL though the CICS Web service assistant DFHWS2LS to generate a WSBIND CICS can use and new copybooks that reflect the changes we’ve made.

Some notes:

  • A WSDL with multiple bindings (SOAP and SOAP12, for example) and you have to specify which one to the utility with the BINDING= parameter.
  • A WSDL with multiple operations requires PGMINT=CHANNEL instead of COMMAREA.
  • INLINE-MAX-OCCURS=6 so that all of the SummaryLines will fit without an extra container.

The JCL:

// JCLLIB ORDER=(DFH320.XDFHINST)
//DFHWS2LS EXEC DFHWS2LS,
// JAVADIR='java/J6.0',
// PATHPREF=,
// REGION.JAVAPRG1=256M
//INPUT.SYSUT1 DD *
PDSLIB=//USER.SRC.COB
REQMEM=NACTRQ
RESPMEM=NACTRP
LANG=COBOL
INLINE-MAXOCCURS-LIMIT=6
PGMNAME=NACTWS
TRANSACTION=NAWS
URI=Account
PGMINT=CHANNEL
WSBIND=/tmp/AccountService.wsbind
WSDL=/tmp/AccountService.wsdl
BINDING=LISTWSHTTPSoapBinding
LOGFILE=/tmp/AccountService.log
MAPPING-LEVEL=2.2

And the new copybooks:
NACTRQ01.COB NACTRP01.COB NACTRQ02.COB NACTRP02.COB

5. Time to Code.

We’ll start out coding of NACTWS with a copy of  SDFHSAMP(DFH0CBRL) which already has the Link3270 Bridge logic in it and we’ll  add the Web Services support to it.  DFH0CBRL takes it’s input from a COMMAREA, copybook SDFHSAMP(DFH0CBRA); the new program will use containers mapped by the copybooks we created above.  Hmm, all the of the fields names are different.

  • Include the request copybooks int he Linkage section:
     Linkage Section.
     01 srch-request.
       copy NACTRQ01.
     01 list-request.
       copy NACTRQ02.

    and the reply copybooks in working-storage:

    01 srch-reply.  
      copy NACTRP01.
    01 list-reply.  
      copy NACTRP02.
  • Determine the type of request from the Operation name:
    77 ws-operation    pic x(32) value spaces.
       88 srch-req               value 'LISTWSOperation'.
       88 disp-req               value 'DETAILWSOperation'.
    and
          EXEC CICS GET CONTAINER('DFHWS-OPERATION')
                        INTO(ws-operation)
          END-EXEC
    
          if srch-req
             perform search-request
          else
             perform display-request
          end-if.
  • Get the request parameters from the predefined container, for example for the AccountList request:
    EXEC CICS GET CONTAINER('DFHWS-DATA')                 
              SET(ADDRESS OF srch-request)                
              FLENGTH(container-len)                      
    END-EXEC                                              
    
    move Surname             of srch-request   to snamemi 
    move length of Surname   of srch-request   to snameml 
    move Firstname           of srch-request   to fnamemi.
    move length of Firstname of srch-request   to fnameml.
  • Etc.

The result: NACTWS.COB

6. Testing

Here are some test results via SoupUI.

NACTAccountList NACTAccountDetail

 OK, then

I didn’t get around to putting the in PF8 support, but otherwise the web service seems functional.. Perhaps in the future I’ll make this into a RESTful service using the CICS provided Atom service.

Leave a Reply

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