Modernization of Mainframe applications by implementing cloud based agile architecture

This article discusses how legacy mainframe applications can be modernized to enable teams to work in Devops/Agile mode for faster
development/deployment without rewriting or porting mainframe code which is very expensive and time consuming.


Below are the list of proposals to uplift mainframe water fall work processes to Agile/Devops methodology. Each point below address shortfalls in a mainframe based environment which need to be addressed before adopting Devops/Agile practices or tools.

  1. Create APIs to access data residing in mainframe using Mainframe Z/OS components like Z/OSMF, DB2 rest interface, IMS SOAP connect etc.
  2. Create APIs for all the existing IMS transactions such that front end applications can use APIs instead of MQ based tight integrations. For
    Example Zosconnect offers capability to generate API for all IMS defined transactions.
  3. Establish API gateways (Ex: Kong gateway) to manage all these APIs and micro services.
  4. Create CD/CI pipelines with automated testing scripts for mainframe micro services and APIs.
  5. Uplift old front end applications to new micro service based architecture which can run in docker containers.
  6. All these docker containers running front end applications should be provisioned and configured using Infrastructure as a service solution
    like Kubernetes.
  7. Mainframe side development should be uplifted from traditional Mainframe based test environments to X86 mainframe emulators(Ex: IBM
    zPDT ) which can scale dynamically.
  8. Mainframe test environments should be provisioned dynamically based on Application images using products like ZD&T on a
    infrastructure as a cloud platform rather than spending millions of dollars building new test environments and creating dedicated teams to
    maintain them.

Here we briefly discuss about creating APIs to access data residing on mainframe using ZOSMF , Db2 REST services available in mainframe.

Instructions for ZOSMF

  1. Make sure ZOSMF is installed and running on the mainframe LPAR your want to extract data from.
  2. Find the ZOSMF port from configuration files in /var/zosmf/configuration/servers OR from STDOUT of IZUSVR* jobs running in spool.
  3. Get access to ZOSMF by getting your mainframe id added into RACF profile linked to USS user group specified in ZOSMF configuration.
    (Check with administrators/Security team if you are not sure where to check)
  4. Install python or prepare Java spring boot environment
    • Refer below links for installing Java spring boot or python:
      • Java Springboot instructions https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started-installing-spring-boot.html
      • Python instructions https://docs.python-guide.org/starting/installation/
  5. Create API endpoints for accessing mainframe data by using python flask module or Java Springboot

Using python flask and requests modules to create API endpoints :

Once python is installed use pip to install flask and requests modules. Flask will be used to create local server with API endpoints on localhost (0.0.0.0). requests module will be used to send GET/POST/PUT/DELETE requests Z/OSMF or DB2 Rest interface.
Below is the sample code to do this

Payload should be formatted in json as per mainframe api schema to which url is pointed to.
Authorization: If mainframe APIs are using basic authentication then create base64 encoded text of string “userid:password”

header = {
'Content-Type': "text/plain",
'X-IBM-Data-Type': "text",
'Authorization': "Basic cDczNzQasdfasdFyMDcxOQ==",
'Host': "hostname:1111",
}
response = requests.request("PUT", url, data=payload, headers=header, verify=False)

Instructions for ZOSMF Db2 rest interface:

If we want to get data from DB2 tables on mainframe using Db2 rest interface then fallow below steps and create a DB2 service to be called by
our Python code or Java spring boot code:

Procedure:

  • To create a service, issue an HTTP or HTTPS POST request through a REST client with the following URI:POST https://:/services/DB2ServiceManager
  • Set the HTTP header Accept and Content-Type fields to application/json for the request.
  • Specify the create service parameters using JSON format key/value pairs in the HTTP body for the request. The requestType , sqlStmt , collection , serviceName , description , and version JSON keys are case sensitive. General service create bind option keys are case insensitive. The requestType , sqlStmt , and serviceName parameters are required. To use the version create service parameter, REST service versioning must be enabled. Specify the create service HTTP body content:
{
"requestType": "createService",
"sqlStmt": "<sqlStatement>",
"collectionID": "<serviceCollectionID>",
"serviceName": "<serviceName>",
"description": "<serviceDescription>",
"version": "<version identifier>",
"<bindOption>": "<bindOptionValue>",
...
"<bindOption>": "<bindOptionValue>"
}

where

  • createService indicates that you request to create a new service.
  • <sqlStatement> is the SQL statement that you include in the new service. For each new service, you can embed a single CALL, DELETE, INSERT, SELECT, TRUNCATE, UPDATE, or WITH SQL statement. When you create the service, Db2 also binds a package that is used to invoke the service.
    • Db2 adds a new row in the user-defined SYSIBM.DSNSERVICE catalog table for the service and saves the bound package in the directory. Db2also sets the HOSTLANG column in the SYSIBM.SYSPACKAGE and SYSIBM.SYSPACKCOPY tables to ‘R’ to mark the package for the REST API.
  • <serviceCollectionID> is the collection identifier of the package that is associated with the new service. The serviceCollectionID property is optional. If you specify , Db2 names the package in the form of collectionID.serviceName . Otherwise, Db2 uses the default form of SYSIBMSERVICE. serviceName .
  • <serviceName> is the name of the new service that you create.
  • <serviceDescription> is a brief description of the new service. The serviceDescription property is optional. If provided, Db2 stores the value in the DESCRIPTION column of the SYSIBM.DSNSERVICE catalog table.
  • <version identifier> is an optional version identifier for the service being created. This is only valid if REST service versioning support is enabled.
  • <bindOption> is the option that you specify for binding the package that is associated with the new service. The bindOption property is optional. All bind options supported by the BIND SERVICE subcommand, except DESCRIPTION, NAME, SQLDDNAME, SQLENCODING, and VERSION, apply to the createService API. The createService API uses the serviceName , description , and version parameters, instead of the NAME, DESCRIPTION, and VERSION bind options of the BIND SERVICE subcommand. See BIND SERVICE (DSN) for supported bind options. See BIND and REBIND options for packages, plans, and services for details about the bind options.

Once the service is created, we can call the service using python requests module or java spring boot code retrieve data from db2 tables using a
predefined SQL query of service.

Containerizing services:

Once the APIs are created for accessing mainframe data using python or java spring boot, We can create containers to deploy them in production. Containerization will enable load balancing, capacity management using container management platforms like Kubernetes or Docker swarm. Docker images for containers can be built by writing docker file similar to below:

FROM alpine:latest #base image to start from apline is recommended for
small size
EXPOSE 5000
# Expose server port, In this case flask default port
RUN apk add python # Install python in container
RUN apk add py-pip # Install python pip
# set working directory
WORKDIR /MF-APP
#install dependencis
RUN pip install flask
RUN pip install requests
# copy files to containerCOPY . /MF-APP
# start app
CMD ["python", "startr_server.py"]

For more information on how to write Dockerfiles, see the Docker user guide and the Dockerfile reference .
Once the above file is created issue command “docker build ./” this will build local image. To manage local images and publishing to a docker registry use a docker GUI like portainer .( https://www.portainer.io/overview/ )

Links and references:

  1. https://developer.ibm.com/mainframe/products/z-systems-development-test-environment/
  2. http://www.redbooks.ibm.com/abstracts/sg248205.html?Open
  3. https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.izua300/IZUHPINFO_OverviewMain.htm
  4. https://www.ibm.com/support/knowledgecenter/en/SSEPEK_11.0.0/restserv/src/tpc/db2z_restservices.html
  5. https://docs.docker.com/get-started/
  6. https://www.portainer.io/installation/
  7. https://kubernetes.io/docs/home/

Leave a Reply

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