Node.js - Group home

Calling rexx from Node.js as a global web application component on z/OS

By Chandni Dinani posted Wed July 14, 2021 11:47 AM


At Phoenix Software, the advent of the world wide web presented new opportunities in online customer support with automation being a prominent goal. In particular, the manual system of issuing product licenses to customers gave way to an automated system where customers could request a software license online.

Ideally, the license would be delivered instantaneously, and while that was possible, even then, architecting and building a secure, event-driven system that bridged the Intel-based web server with what was then the precursor to z/OS—where the license is generated—was a significant task requiring substantial resources. Instead, off-the-shelf components such as email, ftp, and rexx were assembled into a solution that used polling to discover a license request and then eventually delivers the license via email.

As technology advanced the existing solution began looking more and more archaic and I advocated for the ideal, secure, event-driven system that modern technology could easily provide. The key pieces of technology enabling that solution were Unix System Services (USS) and Node.js on z/OS. At last! the power of Node.js availed itself on every platform in the enterprise!

"The modern solution should, of course, involve minimal changes to shorten both development and implementation time, as well as reduce the potential for introducing unforeseen behavior."

The problem:

The first step was to build a secure SSL/TLS (HTTPS) communication channel between the web server and z/OS. This was trivial using Node.js, requiring very little code as demonstrated in the Node.js documentation. Since the webserver provides the events (license requests) but is not able to connect to z/OS sitting behind the firewall, the z/OS component initiates and maintains a long-lasting, indefinite connection to handle requests and communicate responses as they occur.

The next step, on the z/OS side, was to call the REXX driver that oversees the creation of the license. Again, this was trivial in Node.js using the child_process.spawn function. Since the REXX exec addresses the TSO environment and calls external programs, we spawn REXX via the USS command “tsocmd” to set up the environment. This creates a process that then establishes a TSO environment to run the REXX program. However, I found empirically that the startup time on our MSU-limited LPAR—which occurred on every transaction—was delaying the response; and that impacted the customer experience.

The solution:

The solution was to write a small REXX “stub” that runs perpetually, and processes requests over an HTTP channel (port) on the local interface that is protected via SAF security. Rather than firing up a TSO REXX address space on every transaction, each transaction from the webserver is forwarded over HTTP to the perpetual REXX stub, which then calls the existing REXX license driver.
Figure 1 Calling REXX from Node.js

const options = {
detached: true,
stdio: ['ignore','pipe', ‘inherit'],
env: {
STEPLIB: `${my.steplib}`,
SYSEXEC: `${my.sysexec}`,
TSOPROFILE: `${my.tsoprofile}`
} }
const cmd = `/bin/tsocmd "%${my.rexxstub}" 2>&1`
const cp = child_process.spawn('/bin/sh',['-c',cmd], options)

While HTTP protocol is not strictly necessary, the HTTP headers can be used as a convenient side-channel that is used for keeping track of the transaction identifier and other meta-data. HTTP was chosen over HTTPS for this local channel because HTTP is more easily accomplished in REXX and privacy can be provided via SAF security.

"The prototype for this modern, event-driven solution using Node.js was completed in a single weekend. I can’t think of another language that can achieve so much, across such varied platforms, with so little effort."

About the author: 

Paul Scott — Chief Architect / Web Enablement Technologies

Paul has over 35 years of cross-industry IT experience writing software for IBM mainframes and various other platforms in Assembly language, C, C++, Java, and most scripting languages native to those environments. He worked in the banking, communications, health care, and software industries on projects as diverse as language and OS conversions, automated teller machines, RDS/TMC broadcasting, graphical applications, remote printing, and system software. Currently, Paul is leading a modernization project bringing web technologies to existing products and bridging internal systems to the worldwide web.