Curious about what Deep interaction with zOS in Zowe looks like?

Jakub Balhar
Zowe
Published in
6 min readNov 25, 2020

--

New Foundation by Ed G

{Core} As a software engineer working in the nexus between mainframe and distributed environments, you can imagine the following scenario…

Say your boss/manager, who was previously a mainframe engineer back in the day, asks you to provide a GUI to improve user experience to one of the millions of API specifically used on zOS. Let’s also say there’s already an API to map the public part of a certificate to the SAF user id. But what if the highest level wrapper is in fact a wrapper around a HLASM macro callable from C.

What then?

As an engineer coming from the world of modern distributed systems who’s already aware of the multiple advantages of the virtual desktop provided by the Zowe Open Mainframe Project to leverage your API, you decide you want to build your GUI application using the React framework. Fortunately, you’ve also discovered that all of the key pieces for making this happen are available through Zowe.

The only remaining part to get this GUI into the works is the HLASM mapper. After searching through Zowe repositories, you find a few repos that are written in C which seems to be a good starting point. Later, you realize that the right place is to put the code either directly in the ZSS or create an extension to ZSS such as a ZSS sample plugin.

So what are the prerequisites?

Well, you’’ll need access to zOS for compilation and testing.

To help you get familiar with the roadmap of how to make your GUI into a reality by getting a new service in the ZSS core, this article outlines the step-by-step process and offers examples and pieces of code which your service will likely need.

But before we get started with the process, we recommend you consider if, in fact, you absolutely need the service to be part of every installation. If not, we highly recommend you build a plug-in. Take our word for it, it’s faster and much more straightforward.

If the answer to your question is yes, let’s get to it.

The process

The first step is to persuade members of the Zowe project that your service needs to be part of the ZSS core services. To do this, you’ll need to create an issue that describes the service you have in mind in the ZSS repository. One you’ve created the issue, you’ll then need to present the idea to the Web UI squad which is responsible for ZSS. The Web UI squad meetings are visible in the Open Mainframe Project calendar. Based on how complex the required service is, you’ll either be able to get buy-in from the Web UI squad, or you’ll possibly need to present the idea to the Zowe architecture call which is visible in the same calendar. Once you’ve persuaded Zowe project members, you can get started with the development of your wrapper to the Assembler macros.

The current version of ZSS lives in the https://github.com/zowe/zss repository. The two important branches are master and staging. Master contains the currently released version, while staging represents the branch that is currently in development. With every release, staging is merged to master. To integrate a new branch, you need to fork the core repository and create a new branch based on staging.

At the current time as this article is being written, there is no open-source testing suite for ZSS services. Development of this open-source testing suite for ZSS services is, however, planned for a later date. For now, you’ll need to provide some way of verifying that the provided solution works. The zowe-install-packaging repository contains a test suite that verifies the integration of all Zowe components, which is one of the places where you can put your testing code. Alternatively, you can provide some methods which can be run to prove that your code works.

The Zowe-install-packaging repository is also a place where you’ll need to add any code that is necessary to run as part of the installation in order for the new ZSS service to work. An example of such code may be ESMs permissions to map the certificates to the user id as was the case in our use case.

Once you have the code for the service ready, as well as the updates to the installation in the zowe-install-packaging, you can now create Pull requests to both repositories. Ask the Web UI squad and the Systems squad for review. The Systems squad is responsible for the zowe-install-packaging repository and the regular meetings are in the Open Mainframe Project calendar. The final step is to merge your branch into both the https://github.com/zowe/zss and zowe-install-packaging repositories. Your code will be released in a next monthly refresh.

Code

Code, in this context, is designed with the objective of building a new RESTful service which will be available as part of ZSS. Therefore you need to know, specifically, where to add your code. You also need to know how to enable the new service in the ZSS, how to properly process requests and responses, and how you build and run ZSS. One example that was merged and shows the full implementation of the new service is provided here: https://github.com/zowe/zss/pull/224.

Installation of new service within ZSS

New service installation within ZSS has two parts.

  • The installation procedure within the service itself
  • The call to this procedure within the zss.c

Install the service into the ZSS server using the following format:

void installCertificateService(HttpServer *server)
{
HttpService *httpService = makeGeneratedService("CertificateService", "/certificate/x509/**");
httpService->authType = SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN;
httpService->serviceFunction = serveMappingService;
httpService->runInSubtask = TRUE;
httpService->doImpersonation = TRUE;

registerHttpService(server, httpService);
}

The previous code shows a new REST service on path /certificate/x509/ and all subsequent paths.

where:

  • The authType states what authentication options will be accepted. The SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN accepts the valid JWT token produced by the API Mediation Layer and as such is used to participate in SSO.
  • The runInSubtask option specifies whether the request processing will be run in a new process.
  • The doImpersonation option specifies whether the process will run under the identity of the ZSS or of the authenticated user, where true means the authenticated user.
  • The serviceFunction specifies the procedure available from the code which will be called. The following line is an example of what such a function might look like.

Example:

static int serveMappingService(HttpService *service, HttpResponse *response)

The following line is the code in zss.c which is used to actually install the service:

#include "certificateService.h" // On the topinstallCertificateService(server); // As part of the main method at the end of the file.

Reading the code from JSON

The following code shows how to get access to the request within the service and the key portion of the request.

HttpRequest *request = response->request;
int contentLength = request->contentLength;
char* requestBody = request->contentBody;

Responding with the result

In order to respond with JSON it is necessary to include the following libraries:

#include "httpserver.h"
#include "json.h"
#include "http.h"

Once you’ve included these libraries, create a JSON printer and set the headers and status with convenience methods such as setResponseStatus and setDefaultJSONRESTHeaders. Write them into the response by calling writeHeader.

jsonPrinter *p = respondWithJsonPrinter(response);
setResponseStatus(response, 200, "OK");
setDefaultJSONRESTHeaders(response);
writeHeader(response);

jsonStart(p);
{
jsonAddString(p, "userid", userMapCertificateStructure.useridRacf);
jsonAddInt(p, "returnCode", rc);
jsonAddInt(p, "safReturnCode", userMapCertificateStructure.returnCode);
jsonAddInt(p, "racfReturnCode", userMapCertificateStructure.returnCodeRacf);
jsonAddInt(p, "racfReasonCode", userMapCertificateStructure.reasonCodeRacf);
}
jsonEnd(p);

finishResponse(response);

At this point you start JSON for the response with jsonStart and end it with jsonEnd. Between these methods, you can use convenient methods such as jsonAddInt to add new objects to the JSON. Finally, you close response for further changes by calling finishResponse.

Build and run

From the properly set ZSS repository in a directory on zOS, you can run the following sequence of commands from USS to build, and then run the ZSS service.

./build/build.sh
cd bin
./zssServer config/server.json

The config/server.json needs to be in a directory with 644 permissions and contains key information such as the port on which the ZSS runs.

Conclusion

So there it is, your roadmap to get your service integrated with all Zowe installations by integrating your service into the ZSS core. Bear in mind that this process takes more coordination and verification than extending Zowe through a plug-in. If you do not absolutely need the service to be part of every installation, then we highly recommend you build a plug-in. The time needed to get a plug-in into production is much faster and far more streamline.

If you enjoyed this blog checkout more Zowe blogs here. Or, ask a question and join the conversation on the Open Mainframe Project Slack Channel #Zowe-dev, #Zowe-user or #Zowe-onboarding. If this is your first time using the OMP slack channel register here.

--

--

Jakub Balhar
Zowe

I always try to find answers to the complex questions. Now exploring the world of Mainframes in the Broadcom inc.