Using sample codes in different programming languages to access the API services for CRA
Some content is unavailable due to permissions.
We provide various sample codes in different programming languages (for example, Python) to access the API services for CRA.
You can use these samples to:
- Obtain a list of services that are registered to work with the API.
- Log in to a service from which you want to retrieve data.
- Extract data from a service.
Important
The sample codes provided in this topic do not cover all the connection types (for example, https) and capabilities to access the API services for CRA.
Running the sample code
This section explains how to run the sample code and generate output.
Tip
Click the required tab to see more details.
Use the following steps to run a sample code in Java and see its output.
Important
Make sure that you have Oracle Java 8 or later installed.
Copy the following sample code and save it to your local machine. Make sure that you rename the file as Sample.java. The file name must match with the name of the class.
Click here to expand...
// In this sample, we demonstrate the use of several CRA APIs. Starting with retrieving a list of registered services,
// then logging in to a service, extracting data from it with and without a session ID, and also writing the output into a file.
import java.io.*;
import java.net.*;
import java.nio.charset.MalformedInputException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
public class Sample {
//---------------------------------------------------------------
// Please change the below variables according to your environment
//---------------------------------------------------------------
// The CRA server protocol type for the API request
public static final String PROTOCOL = "http";
// The name of the mainframe host where the CRA server is running
public static final String HOST = "host_name";
// The port number of the CRA server
public static final String PORT = "8080";
// The name of the service (for MVE host server) you want to use
public static final String SERVICE = "service_name";
// The product name of which you want to retrieve data
public static final String PRODUCT = "product_name";
// The view name within the product you want to retrieve data
public static final String VIEW = "view_name";
// The Username and Password of your mainframe user credentials where your services located. This user must have the required SAF permission defined
public static final String USERNAME = "user_name";
public static final String PASSWORD = "password";
// In case that the service is not register on CRA, the below code will add it using the host and port variables.
// The name of the mainframe host where the service you want to register resides
public static final String NEW_SERVICE_HOST = "service_host";
// The port number of the service you want to register
public static final String NEW_SERVICE_PORT = "service_port";
// The path with the file name where the return data from the CRA API calls to be written
public static final String RESPONSE_FILE_PATH = "path+file.txt";
//---------------------------------------------------------------
// End of variable need to be change
//---------------------------------------------------------------
public static final String GET_SERVICES_URL = PROTOCOL + "://" + HOST + ":" + PORT + "/cra/serviceGateway/services";
public static final String LOGIN_URL = PROTOCOL + "://" + HOST + ":" + PORT + "/cra/serviceGateway/services/" + SERVICE + "/login";
public static final String GET_DATA_URL = PROTOCOL + "://" + HOST + ":" + PORT + "/cra/serviceGateway/services/" + SERVICE + "/products/" + PRODUCT + "/views/" + VIEW + "/data?rows=1";
public static final String GET_LIST_OF_PRODUCT_URL = PROTOCOL + "://" + HOST + ":" + PORT + "/cra/serviceGateway/services/" + SERVICE + "/products";
public static final String UPDATE_SERVICE_URL = PROTOCOL + "://" + HOST + ":" + PORT + "/cra/serviceGateway/services/" + SERVICE + "/update?host=" + NEW_SERVICE_HOST + "&port=" + NEW_SERVICE_PORT;
public static void main(String[] args) {
Sample sample = new Sample();
sample.runCRAAPIExample();
}
public void runCRAAPIExample() {
File file = createFile(RESPONSE_FILE_PATH);
//-------------------- SERVICES -------------------------------------------
// Get list of services call.
String getServicesUrlResponse = apiCall(GET_SERVICES_URL, "GET", null);
System.out.println(getServicesUrlResponse);
// Checking if a service is found, and if it isn't add a service using update service call.
if (!getServicesUrlResponse.contains("\"" + SERVICE + "\"")) {
System.out.println("Service isn't found, " + SERVICE + " service will be added to CRA server.");
String updateServiceResponse = apiCall(UPDATE_SERVICE_URL, "POST", null);
}
//------------------- LOGIN ----------------------------------------------
// Login to a service.
String token = null;
try {
// Login call which retrieves a token
token = apiLogin(LOGIN_URL, USERNAME, PASSWORD).substring(14, 50);
System.out.println(token);
} catch (Exception e) {
System.out.println("Login failed - " + e.getMessage());
System.exit(0);
}
//------------------- GET DATA --------------------------------------------
String getDataUrlResponse = null;
String sessionID = null;
try {
// get data by parameters call with close=false which retrieves a session id.
getDataUrlResponse = apiCall(GET_DATA_URL + "&close=false", "GET", token);
System.out.println(getDataUrlResponse);
sessionID = getDataUrlResponse.substring(getDataUrlResponse.lastIndexOf("\"session\":") + 11, 114);
} catch (Exception e) {
System.out.println("Running get data failed - " + e.getMessage());
}
try {
// get data by parameters call with a session id.
getDataUrlResponse = apiCall(GET_DATA_URL + "&close=true&session=" + sessionID, "GET", token);
System.out.println("Get data using session \n" + sessionID);
} catch (Exception e) {
System.out.println("Failed running get data by parameters with sessionID - " + e.getMessage());
}
String getListOfProductsResponse = null;
try {
// get list of products call.
getListOfProductsResponse = apiCall(GET_LIST_OF_PRODUCT_URL, "GET", token);
System.out.println(getListOfProductsResponse);
} catch (Exception e) {
System.out.println("Running get list of products failed - " + e.getMessage());
}
//----------------- WRITE TO FILE ----------------------------------------------
writeToFile(file, Arrays.asList(getServicesUrlResponse, getDataUrlResponse, getListOfProductsResponse));
}
// apiCall performs the REST call.
public String apiCall(String apiURL, String method, String token) {
HttpURLConnection conn = null;
InputStreamReader reader = null;
StringBuilder responseContent = new StringBuilder();
int status = 0;
boolean eof = false;
try {
URL url = new URL(apiURL);
conn = (HttpURLConnection) url.openConnection();
if (token != null) {
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Authorization", "Bearer " + token);
}
conn.setRequestMethod(method);
status = conn.getResponseCode();
System.out.println(status);
if (status > 299) {
reader = new InputStreamReader(conn.getErrorStream());
} else {
reader = new InputStreamReader(conn.getInputStream());
}
int temp;
while (!eof) {
temp = reader.read();
if (temp == -1) {
eof = true;
}
responseContent.append((char) temp);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
}
if (status > 299) {
throw new RuntimeException("Failed running URL message=" + responseContent);
}
return responseContent.toString();
}
public static File createFile(String path) {
File myFile = new File(path);
try {
if (myFile.createNewFile()) {
System.out.println("File created: " + myFile.getName());
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
e.printStackTrace();
}
return myFile;
}
public static void writeToFile(File fileName, List<String> input) {
try {
FileWriter myWriter = new FileWriter(fileName);
for (String inputLine : input) {
myWriter.write(inputLine + "\n");
}
myWriter.close();
System.out.println("Successfully wrote to the file.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
public String apiLogin(String apiURL, String username, String password) {
String data = "{\n \"username\": \""+ username+ "\",\n \"password\": \"" +password+"\" \n}";
HttpURLConnection conn = null;
InputStreamReader reader = null;
StringBuilder responseContent = new StringBuilder();
byte[] postData = data.getBytes(StandardCharsets.UTF_8);
boolean eof = false;
int status = 0;
try {
URL url = new URL(apiURL);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Content-Type", "application/json");
conn.setUseCaches(false);
OutputStream stream = conn.getOutputStream();
stream.write(postData);
status = conn.getResponseCode();
if (status > 299) {
reader = new InputStreamReader(conn.getErrorStream());
} else {
reader = new InputStreamReader(conn.getInputStream());
}
int temp;
while (!eof) {
temp = reader.read();
if (temp == -1) {
eof = true;
}
responseContent.append((char)temp);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
}
if (status > 299) {
throw new RuntimeException("Failed running URL message=" + responseContent);
}
return responseContent.toString();
}
}Open the file in your preferred editor and set the required variables according to your environment.
The following table describes the variables:Variable
Description
PROTOCOLCRA server protocol type for the API request
HOSTName of the mainframe host where the CRA server is running
PORTPort number of the CRA server
SERVICEName of the service (for MVE host server) that you want to use
PRODUCTName of the product you want to retrieve data from
VIEWName of the views that you want to retrieve data for that product
USERNAMEYour mainframe user credentials
Make sure that required SAF permissions for the user are properly defined.
PASSWORDNEW_SERVICE_HOSTName of the new service host if a service is not registered on a CRA server
NEW_SERVICE_PORTName of the new service port if a service is not registered on a CRA server
RESPONSE_FILE_PATHPath (including a file name) from where a return data from the CRA API calls is written
- Open the command prompt and go to the directory where your Sample.java file is located.
- Compile the class using the following command:
javac Sample.java Run the sample code using the following command:
java -classpath.Sample
You should get a similar output as shown in the following sample:Click here to expand...
File created: testAPIs.txt
200
[
{"HOSTCN":"172.24.49.150","HOSTIP":"172.24.49.150","PORT":3931,"TLS":"N","WEBSERVICEName":"MVERESTAPI_SYSO","STATUS":"ACTIVE"},
{"HOSTCN":"ESSK.BMC.COM","HOSTIP":"172.24.49.150","PORT":7893,"TLS":"N","WEBSERVICEName":"MVERESTAPI_SYSK","STATUS":"ACTIVE"},
{"HOSTCN":"sjsa","HOSTIP":"","PORT":7121,"TLS":"N","WEBSERVICEName":"Mvb","STATUS":"ACTIVE","DESCRIPTION":"Primary Test Target - Update at 1651569796802"},
]
ee416a17-24d7-47e7-88a6-93221f123e71
200
{
"rc": 0,
"system": "SJSA",
"viewName": "JCPU",
"startRow": 1,
"numRows": 1,
"context": "SJSA",
"Columns": {
"ASGRNMC": "C(8)",
"ASRESCPN": "N(4.0)",
"JACT$INT": "D(10),T(5)",
"SYSNAME": "C(8)",
},
"totalRows": 1,
"version": "2.1.00",
"productName": "MVMVS",
"Rows": [
{
"ASGRNMC": "",
"ASRESCPN": "2",
"JACT$INT": [
{
"0": "2022/08/30 02:00:12.23"
},
{
"1": "2022/08/30 02:00:12.23"
}
],
}
]
}
200
Get data using session
b5754de6-87e4-439c-9f2e-ee5864b7cb9d
200
[
{"server":"XTS32PAS","name":"CMF","description":"CMF MONITOR Online (6.2.00)","version":"6.2.0"},
{"server":"M32C","name":"MVALERT","description":"MAINVIEW Alert Manager (6.3.00)","version":"6.3.0"},
{"server":"X32D","name":"MVAO","description":"SJSD-MVI63-AO82##-X32D","version":"8.2.0"},
{"server":"X32D","name":"MVCICS","description":"MVCICS Administrative Services","version":"6.9.0"},
{"server":"*","name":"MVIP","description":"Test Def.","version":"0.0.0"},
{"server":"XTS32PAS","name":"MVMVS","description":"MainView for z/OS (6.2.00)","version":"6.2.0"}
]Successfully wrote to the file.
Process finished with exit code 0
Use the following steps to run a sample code in Python and see its output.
Important
Make sure that you have Python version 3.7 or later.
Copy the following sample code and save it to your local machine (with extension .py)
Click here to expand...
# In this sample, we demonstrate the use of several CRA APIs. Starting with retrieving a list of registered services,
# then logging in to a service, extracting data from it, and then log off.
import requests
import json
# Variables
# ---------------------------------------------------------------
# Please change the below variables according to your environment
# ---------------------------------------------------------------
# The CRA server protocol type for the API request
PROTOCOL = 'http'
# The name of the mainframe host where the CRA server is running
HOST = 'host_name'
# The port number of the CRA server
PORT = '8080'
# The name of the service (for MVE host server) you want to use
SERVICE = 'service_name'
# The Username and Password of your mainframe user credentials where your services located. This user must have the
# required SAF permission defined
USERNAME = 'user_name'
PASSWORD = 'password'
# The product name of which you want to retrieve data
PRODUCT = 'product_name'
# The view name within the product you want to retrieve data
VIEW = 'view_name'
# In case that the service is not register on CRA, the below code will add it using the host and port variables.
# The name of the mainframe host where the service you want to register resides
NEW_SERVICE_HOST = 'service_host'
# The port number of the service you want to register
NEW_SERVICE_PORT = 'service_port'
# ---------------------------------------------------------------
# End of variable need to be change
# ---------------------------------------------------------------
# -------------------- SERVICES -------------------------------------------
# The get list of services API retrieves a list of registered services.
# {{http://}}{{host}}:{{port}}/cra/serviceGateway/services
getServicesResponse = requests.get(PROTOCOL + '://' + HOST + ':' + PORT + '/cra/serviceGateway/services')
print('GetListOfServices ' + str(getServicesResponse))
if getServicesResponse.status_code > 299:
exit(0)
print(getServicesResponse.json())
services = getServicesResponse.json()
# Search for a service name
SERVICE_IS_FOUND = 0
for item in services:
if SERVICE == item['WEBSERVICEName']:
print('Service ' + item['WEBSERVICEName'] + ' is found')
SERVICE_IS_FOUND = 1
# If service is not found, use update service API to add it
# {{http://}}{{host}}:{{port}}/cra/serviceGateway/services/{{ServiceName}}/update
if SERVICE_IS_FOUND == 0:
print('Service is not found, ' + SERVICE + ' service will be added to CRA server')
updateServiceResponse = requests.post(PROTOCOL + '://' + HOST + ':' + PORT + '/cra/serviceGateway/services/'
+ SERVICE + '/update', data={'host': NEW_SERVICE_HOST,
'port': NEW_SERVICE_PORT})
print('UpdateService ' + str(updateServiceResponse))
if updateServiceResponse.status_code > 299:
exit(0)
# ------------------- LOGIN --------------------------------------------
# Login API is used to log in to a service from which you want to retrieve data. After successfully logging in, a 32
# character user token is returned, which will be used in all subsequent requests until you log off or the token
# expires.
# {{http://}}{{host}}:{{port}}/cra/serviceGateway/services/{{ServiceName}}/login
headers = {'content-type': 'application/json'}
data = {"username": USERNAME, "password": PASSWORD}
loginResponse = requests.post(PROTOCOL + '://' + HOST + ':' + PORT + '/cra/serviceGateway/services/' + SERVICE +
'/login', data=json.dumps(data), headers=headers)
print('Logon ' + str(loginResponse))
print(loginResponse.json())
if loginResponse.status_code > 299:
exit(0)
# Form the Bearer token header given by Logon API
loginToken = loginResponse.json()
userToken = "Bearer" + " " + loginToken['userToken']
# ------------------- GET DATA --------------------------------------------
# The get data by parameters API retrieves data for a view within a product. In this call, we ask for 5 rows.
# {{http://}}{{host}}:{{port}}/cra/serviceGateway/services/{{ServiceName}}/products/{{ProductName}}/views/{{ViewName}}/data?rows=5
# Syntax for the authorization = {'Authorization': 'Bearer {access_token}}
my_headers = {'Authorization': userToken}
query = {'rows': '1'}
getDataResponse = requests.get(PROTOCOL + '://' + HOST + ':' + PORT + '/cra/serviceGateway/services/' + SERVICE +
'/products/' + PRODUCT + '/views/' + VIEW + '/data', headers=my_headers,
params=query)
print('GetDataByParameters ' + str(getDataResponse))
if getDataResponse.status_code > 299:
exit(0)
print(getDataResponse.json())
# ------------------- VIEWS LIST --------------------------------------------
# The get list of views API retrieves a list of product views.
# {{http://}}{{host}}:{{port}}/cra/serviceGateway/services/{{ServiceName}}/products/{{ProductName}}/views
getViewsResponse = requests.get(PROTOCOL + '://' + HOST + ':' + PORT + '/cra/serviceGateway/services/' + SERVICE +
'/products/' + PRODUCT + '/views', headers=my_headers)
print('GetListOfViews ' + str(getViewsResponse))
if getViewsResponse.status_code > 299:
exit(0)
print(getViewsResponse.json())
# ------------------- LOGOFF --------------------------------------------
# Logoff API
# {{http://}}{{host}}:{{port}}/cra/serviceGateway/services/logoff
logOffResponse = requests.post(PROTOCOL + '://' + HOST + ':' + PORT + '/cra/serviceGateway/services/logoff',
headers=my_headers)
print('LogOff ' + str(logOffResponse))
if logOffResponse.status_code > 299:
exit(0)Open the file in your preferred editor and set the required variables according to your environment.
The following table describes the variables:Variable
Description
PROTOCOLCRA server protocol type for the API request
HOSTName of the mainframe host where the CRA server is running
PORTPort number of the CRA server
SERVICEName of the service (for MVE host server) that you want to use
USERNAMEYour mainframe user credentials
Make sure that required SAF permissions for the user are properly defined.
PASSWORDPRODUCTName of the product you want to retrieve data from
VIEWName of the views that you want to retrieve data for that product
NEW_SERVICE_HOSTName of the new service host if a service is not registered on a CRA server
NEW_SERVICE_PORTName of the new service port if a service is not registered on a CRA server
- Open the command prompt and go to the directory where the PythonSample.py file is located.
Run the sample code using the following command:
Python PythonSample.py
You should get a similar output as shown in the following sample:Click here to expand...
GetListOfServices <Response [200]>
[
{'HOSTCN': '172.24.49.101', 'HOSTIP': '172.24.49.101', 'PORT': 3941, 'TLS': 'N', 'WEBSERVICEName': 'MVERESTAPI_SYSL', 'STATUS': 'ACTIVE'},
{'HOSTCN': 'ESBC.BMC.COM', 'HOSTIP': '172.24.49.101', 'PORT': 7898, 'TLS': 'N', 'WEBSERVICEName': 'MVERESTAPI_SYSL', 'STATUS': 'ACTIVE'},
{'HOSTCN': 'sjss', 'HOSTIP': '', 'PORT': 7171, 'TLS': 'N', 'WEBSERVICEName': 'Mvb', 'STATUS': 'ACTIVE', 'DESCRIPTION': 'Primary Test Target - Update at 1651569796802'},
{'HOSTCN': 'sjss', 'PORT': 7178, 'TLS': 'N', 'WEBSERVICEName': 'gpmOnlyUse', 'STATUS': 'ACTIVE'},
{'HOSTCN': 'sjss', 'PORT': 7178, 'TLS': 'N', 'WEBSERVICEName': 'Mvb', 'STATUS': 'ACTIVE'},
]
Service Mvb is found
Login <Response [200]>
{
'userToken': '3c5792dc-d58b-4a8f-b638-c3b8e1ff7454'
}
GetDataByParameters <Response [200]>
{
'rc': 0,
'system': 'SJSS',
'viewName': 'JCPU',
'startRow': 1,
'numRows': 1,
'context': 'SJSS',
'Columns': {
'ASGRNMC': 'C(8)',
'ASRESCPN': 'N(4.0)',
'JACT$INT': 'D(10),T(5)',
'SYSNAME': 'C(8)',
},
'totalRows': 1,
'version': '2.1.00',
'productName': 'MVMVS',
'Rows': [
{
'ASGRNMC': '',
'ASRESCPN': '2',
'JACT$INT': [
{
'0': '2022/08/30 02:00:12.23'
},
{
'1': "2022/08/30 02:00:12.23'
}
],
}
]
}GetListOfViews <Response [200]>
[
{'name': 'ADMIN', 'description': 'Administrative views'},
{'name': 'ALRMDIST', 'description': 'Alarm Distribution List'},
{'name': 'ARD', 'description': 'Address space resource data'},
{'name': 'ARDZ', 'description': 'Summary addr space resource data'},
{'name': 'ASD', 'description': 'Address space state data'},
{'name': 'ASDZ', 'description': 'Summary addr space state data'}
]
LogOff <Response [202]>
Use the following steps to run a sample code in Shell script and see its output.
Copy the following sample code and save it to your local machine (with extension .sh).
Click here to expand...
#!/bin/bash
# Sample of using curl tool to call CRA APIs
clear
# variables
##---------------------------------------------------------------
# Please change the below variables according to your environment
##---------------------------------------------------------------
# The CRA server protocol type for the API request
PROTOCOL="http"
# The name of the mainframe host where the CRA server is running
HOST="host_name"
# The port number of the CRA server
PORT="8080"
# The Username and Password of your mainframe user credentials where your services located. This user must have the required SAF permission defined
USERNAME="username"
PASSWORD="password"
# The name of the service (for MVE host server) you want to use
SERVICE="service_name"
# The product name of which you want to retrieve data
PRODUCT="product_name"
# The view name within the product you want to retrieve data
VIEW="view_name"
##---------------------------------------------------------------
# End of variable need to be change
##---------------------------------------------------------------
# API URL
GetListOfServices=""$PROTOCOL"://"$HOST":"$PORT"/cra/serviceGateway/services"
Login=""$PROTOCOL"://"$HOST":"$PORT"/cra/serviceGateway/services/"$SERVICE"/login"
GetData=""$PROTOCOL"://"$HOST":"$PORT"/cra/serviceGateway/services/"$SERVICE"/products/"$PRODUCT"/views/"$VIEW"/data"
GetListOfViews=""$PROTOCOL"://"$HOST":"$PORT"/cra/serviceGateway/services/"$SERVICE"/products/"$PRODUCT"/views"
##-------------------- SERVICES -------------------------------------------------
# Get a list of services API - retrieves a list of services that are registered.
echo "Get a list of services API"
curl $GetListOfServices
echo
##------------------- LOGIN --------------------------------------------
# Login - log in to a service from which you want to retrieve data.
# When login is successful a user token is returned.
echo "Login API"
Json='{"username":"'"$USERNAME"'","password":"'"$PASSWORD"'"}'
# Check for HTTP status code, and if it is greater than 299 exit
HTTPStatusCode=$(curl -s -o tempfile.text -w "%{http_code}" -X POST -H "Content-Type: application/json" -d $Json $Login)
if [ $HTTPStatusCode -gt "299" ]
then
echo "Login API call failed with "$HTTPStatusCode" status code"
exit
else
LogonResponse=$(cat tempfile.text)
echo $LogonResponse
fi
# Form the authorization bearer token
BearerToken=$(cat tempfile.text | cut -c15-50)
Authorization="Authorization: Bearer "$BearerToken
echo
##------------------- GET DATA --------------------------------------------
# Get data by parameters - retrieves data for a view within a product (in the following example we ask for five rows)
echo "Get data by parameters API"
# Check for HTTP status code, if it is greater than 299 exit
HTTPStatusCode=$(curl -s -o tempfile.text -w "%{http_code}" -X GET -H "$Authorization" $GetData"?rows=5")
if [ $HTTPStatusCode -gt "299" ]
then
echo "Get data by parameters API call failed with "$HTTPStatusCode" status code"
exit
else
GetDataResponse=$(cat tempfile.text)
echo $GetDataResponse
fi
##------------------- VIEWS LIST --------------------------------------------
# Get a list of views - retrieves a list of product views
echo "Get a list of views"
# Check for HTTP status code, if it is greater than 299 exit
HTTPStatusCode=$(curl -s -o tempfile.text -w "%{http_code}" -X GET -H "$Authorization" $GetListOfViews)
if [ $HTTPStatusCode -gt "299" ]
then
echo "Get a list of views API call failed with "$HTTPStatusCode" status code"
exit
else
GetListOfViewsResponse=$(cat tempfile.text)
echo $GetListOfViewsResponse
fi
echo
rm tempfile.text
echo "End Of Sample!"Open the file in your preferred editor and set the required variables according to your environment.
The following table describes the variables:Variable
Description
PROTOCOLCRA server protocol type for the API request
HOSTName of the mainframe host where the CRA server is running
PORTPort number of the CRA server
USERNAMEYour mainframe user credentials
Make sure that required SAF permissions for the user are properly defined.
PASSWORDSERVICEName of the service (for MVE host server) that you want to use
PRODUCTName of the product you want to retrieve data from
VIEWName of the views that you want to retrieve data for that product
- Enter the following command to run your sample code:
./file_name.sh You should get a similar output as shown in the following sample:
Click here to expand...
Get list of services API
[
{"HOSTCN":"SJSC","HOSTIP":"","PORT":7171,"TLS":"N","WEBSERVICEName":"Mvc","STATUS":"ACTIVE","DESCRIPTION":""},
{"HOSTCN":"172.54.28.142","HOSTIP":"172.54.28.142","PORT":3983,"TLS":"N","WEBSERVICEName":"MVERESTAPI_IMSB_3981","STATUS":"ACTIVE"},
{"HOSTCN":"172.54.28.142","HOSTIP":"172.54.28.142","PORT":5453,"TLS":"N","WEBSERVICEName":"MVERESTAPI_IMSB_3981","STATUS":"ACTIVE"},
{"HOSTCN":"172.54.28.142","HOSTIP":"172.54.28.142","PORT":3342,"TLS":"N","WEBSERVICEName":"MVERESTAPI_IMSB_3981","STATUS":"ACTIVE"}
]Login API
{
"userToken":"55ee53b4-8355-45ae-9283-45d11e0fd219"
}Get data by parameters API
{
"rc": 0,
"system": "SJSK",
"viewName": "JCPU",
"startRow": 1,
"numRows": 1,
"context": "SJSK",
"Columns": {
"ASGRNMC": "C(8)",
"ASRESCPN": "N(4.0)",
"JACT$INT": "D(10),T(5)",
"SYSNAME": "C(8)",
"M390IND": "C(1)",
"ASGJSFLY": "C(4)",
"ASGJELT": "T(8)"
},
"totalRows": 1,
"version": "2.1.00",
"productName": "MVMVS",
"Rows": [
{
"ASGRNMC": "",
"ASRESCPN": "2",
"JACT$INT": [
{
"0": "2022/08/30 02:00:12.23"
},
{
"1": "2022/08/30 02:00:12.23"
}
],
}
]
}Get list of views
[
{"name":"ADMIN","description":"Administrative views"},
{"name":"ALRMDIST","description":"Alarm Distribution List"},
{"name":"ARD","description":"Address space resource data"},
{"name":"ARDZ","description":"Summary addr space resource data"},
{"name":"ASD","description":"Address space state data"}
]End Of Sample!
Use the following steps to run a sample code in REXX and see its output.
- Log on to the mainframe using your valid user credentials.
- Create a new member in your PDS data set.
Copy the following sample code to your member:
Click here to expand...
/* REXX
This REXX sample was copied from SYS1.SAMPLIB(HWTHXRX1) to
use HTTP services in the z/OS Client Web Enablement Toolkit
The sample was modified to preform CRA API calls
*/
/* START OF SPECIFICATIONS *********************************************/
/* */
/*---------------------------------------------------------------------*/
/* */
/* SCRIPT NAME= */
/* */
/* DESCRIPTIVE NAME=Sample Rexx code to use HTTP services */
/* in the z/OS Client Web Enablement Toolkit */
/* */
/* FUNCTION: */
/* This particular sample shows a sample invocation of several CRA */
/* APIs such as, get a list of registered services, logging in to */
/* a service, and get data from a service. */
/* */
/* This script provides sample calls to these HTTP Enabler */
/* services: */
/* HWTHINIT - Initialize a connection or request instance. */
/* HWTHSET - Set various connection or request options. */
/* HWTHCONN - Connect to a web server. */
/* HWTHRQST - Make an HTTP request over an existing connection. */
/* HWTHDISC - Disconnect from a web server. */
/* HWTHTERM - Terminate a connection or request instance. */
/* */
/* OPERATION: */
/* */
/* CODE FLOW in this sample: */
/* Call HTTP_init to create a connection instance. */
/* Call HTTP_setupConnection to set all the necessary connection */
/* options prior to connecting to the web server. */
/* Call HTTP_connect to connect to the web server. */
/* Call HTTP_init to create a request instance. */
/* Call HTTP_setupRequest to set the necessary request options. */
/* Call HTTP_request to send the request over the established */
/* connection. */
/* * Stem variable ResponseHeaders. accumulates each response */
/* header received from the HTTP server */
/* * Variable ResponseBody holds any response body content */
/* received from the HTTP server. */
/* * Variables ResponseStatusCode and ResponseReasonCode hold */
/* the status code and reason received from the HTTP server. */
/* Call HTTP_terminate to terminate the request instance. */
/* Call HTTP_disconnect to disconnect the connection (socket) */
/* from the web server. */
/* Call HTTP_terminate to terminate the connection instance. */
/* */
/* INVOCATION: */
/* This can run in any non-reentrant REXX environment (e.g., TSO, */
/* ISPF, zOS UNIX, SYSTEM REXX) where the HWTHTTP */
/* commands are available. */
/* */
/* END OF SPECIFICATIONS * * * * * * * * * * * * * * * * * * * * * * **/
/***************************************************************************/
/* Please change the below variables according to your environment */
/* */
/* PROTOCOL - The CRA server protocol type for the API request */
/* */
/* HOST - The CRA server protocol type for the API request */
/* */
/* PORT - The name of the mainframe host where the CRA srever is running */
/* */
/* SERVICE - The name of the service (for MVE host server) you want to use */
/* */
/* USERNAME and PASSWORD - The Username and Password of your mainframe */
/* user credentials where your services located. This user must have the */
/* required SAF permission defined */
/* */
/* PRODUCT - The product name of which you want to retrieve data */
/* */
/* VIEW - The view name within the product you want to retrieve data */
/* */
/* SSLVERSION - One of the following: */
/* */
/* - HWTH_SSLVERSION_TLSv13 - Support TLS version 1.3. */
/* */
/* - HWTH_SSLVERSION_TLSv12 - Support TLS version 1.2. */
/* */
/* - HWTH_SSLVERSION_TLSv11 - Support TLS version 1.1. */
/* */
/* SSL Key types are SafKeyring and KeyDBfile (set only one): */
/* */
/* SAFKEYRING - A SAF key ring name, in the form userid/keyring */
/* */
/* KEYDBFILE and KEYSTASHFILE - Set when CRA is configured with a local */
/* keystore. The keystore needs to be exported first, then imported using */
/* GSKKYMAN utility, then converted it into a .kdb database format, also */
/* a stash password file need to created. */
/* */
/***************************************************************************/
PROTOCOL = 'http'
HOST = ''
PORT = 8080
USERNAME = ''
PASSWORD = ''
SERVICE = ''
PRODUCT = ''
VIEW = ''
SAFKEYRING = ''
SSLVERSION = ''
KEYDBFILE = ''
KEYSTASHFILE = ''
Json = ,
'{',
'"username": "'USERNAME'",',
'"password": "'PASSWORD'"',
'}'
if SAFKEYRING /= '' then
do
sslKey = SAFKEYRING
end
else
do
sslKey = KEYDBFILE
end
/***********/
/* API url */
/***********/
GetListOfServices = '/cra/serviceGateway/services'
Login = '/cra/serviceGateway/services/'SERVICE'/login'
GetDataByParameters = '/cra/serviceGateway/services/'SERVICE'/products/'PRODUCT'
/views/'VIEW'/data?rows=1'
/*------------------------------- SERVICES --------------------------------*/
say 'Get list of services API call'
call APICall GetListOfServices 'GET'
/*------------------------------- LOGON -----------------------------------*/
say 'Log in API call'
call APICall Login 'POST'
if ResponseStatusCode > 299 then
do
say 'Logon failed'
exit 0
end
/*------------------------------- GET DATA --------------------------------*/
say 'Get data by parameters API call'
call APICall GetDataByParameters 'GET' Token
if ResponseStatusCode > 299 then
do
say 'Get data by parameters failed'
exit 0
end
exit 0
APICall:
parse arg p1 p2 p3 .
CONNECTION_URI = PROTOCOL'://'HOST
REQUEST_URI = p1
CONNECTION_PORT = PORT
CONTENT_LEN_HEADER = 'Content-Length'
/*********************************************/
/* Get Web Enablement Toolkit REXX constants */
/*********************************************/
call HTTP_getToolkitConstants
if RESULT <> 0 then
exit fatalError( '** Environment error **' )
say 'HTTP Web Enablement Toolkit Sample Begin'
/*****************************************/
/* Initialize request-related variables */
/*****************************************/
ConnectionHandle = ''
RequestHandle = ''
/******************************************/
/* Initialize response-related variables */
/******************************************/
ResponseStatusCode = ''
ResponseReason = ''
ResponseHeaders. = ''
ResponseBody = ''
ContentLen = 0
/*******************************/
/* Obtain a connection handle */
/*******************************/
call HTTP_init HWTH_HANDLETYPE_CONNECTION
if RESULT == 0 then
do
/**************************************************************/
/* Set the necessary options before connecting to the server */
/**************************************************************/
call HTTP_setupConnection
if RESULT == 0 then
do
/*******************************/
/* Connect to the HTTP server */
/*******************************/
call HTTP_connect
if RESULT == 0 then
do
/****************************/
/* Obtain a request handle */
/****************************/
call HTTP_init HWTH_HANDLETYPE_HTTPREQUEST
if RESULT == 0 then
do
/************************************************************/
/* Set necessary request options before making the request */
/************************************************************/
call HTTP_setupRequest
if RESULT == 0 then
do
/**********************/
/* Make the request */
/**********************/
call HTTP_request
if RESULT == 0 then
do
/************************************************/
/* If the response code was ok, write out the */
/* response data */
/************************************************/
if ResponseHeaders.0 > 0 then
do i = 1 to ResponseHeaders.0
if ResponseHeaders.i = CONTENT_LEN_HEADER then
ContentLen = ResponseHeaders.i.1
end
Say 'HTTP status:' ResponseStatusCode
Say 'HTTP reason:' ResponseReasonCode
Say 'Response body contains:' ContentLen 'bytes.'
/* To display the response body content
uncomment the following line:
*/
Say ResponseBody
/* extract Token */
Token = SUBSTR(ResponseBody,15,36)
end /* endif request made */
/***************************************/
/* Release underlying request resource */
/***************************************/
call HTTP_terminate RequestHandle, HWTH_NOFORCE
end /* endif request setup */
end /* endif request handle obtained */
/******************************/
/* Disconnect the connection */
/******************************/
call HTTP_disconnect
end /* endif connected */
/******************************************/
/* Release underlying connection resource */
/******************************************/
call HTTP_terminate ConnectionHandle, HWTH_NOFORCE
end /* endif connection setup */
end /* endif connection handle obtained */
say 'HTTP Web Enablement Toolkit Sample End'
return 0 /* end APICall */
/*******************************************************/
/* Function: HTTP_getToolkitConstants */
/* */
/* Access constants used by the toolkit (for return */
/* codes, etc), via the HWTCONST toolkit api. */
/* */
/* Returns: 0 if toolkit constants accessed, -1 if not */
/*******************************************************/
HTTP_getToolkitConstants:
/***********************************************/
/* Ensure that the toolkit host command is */
/* available in your REXX environment (no harm */
/* done if already present). Do this before */
/* your first toolkit api invocation. Also, */
/* ensure no conflicting signal-handling in */
/* cases of running in USS environments. */
/***********************************************/
call hwtcalls 'on'
call syscalls 'SIGOFF'
/************************************************/
/* Call the HWTCONST toolkit api. This should */
/* make all toolkit-related constants available */
/* to procedures via (expose of) HWT_CONSTANTS */
/************************************************/
address hwthttp "hwtconst ",
"ReturnCode ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwtconst', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwtconst (hwthttp) failure **' )
end /* endif hwtconst failure */
return 0 /* end function */
/*************************************************/
/* Function: HTTP_init */
/* */
/* Create a handle of the designated type, via */
/* the HWTHINIT toolkit api. Populate the */
/* corresponding global variable with the result */
/* */
/* Returns: 0 if successful, -1 if not */
/*************************************************/
HTTP_init:
HandleType = arg(1)
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthinit ",
"ReturnCode ",
"HandleType ",
"HandleOut ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthinit', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthinit failure **' )
end
if HandleType == HWTH_HANDLETYPE_CONNECTION then
ConnectionHandle = HandleOut
else
RequestHandle = HandleOut
return 0 /* end Function */
/****************************************************/
/* Function: HTTP_setupConnection */
/* */
/* Sets the necessary connection options, via the */
/* HWTHSET toolkit api. The global variable */
/* ConnectionHandle orients the api as to the scope */
/* of the option(s). */
/* */
/* Returns: 0 if successful, -1 if not */
/****************************************************/
HTTP_setupConnection:
Port = CONNECTION_PORT
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"ConnectionHandle ",
"HWTH_OPT_PORT ",
"Port ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate ConnectionHandle, HWTH_NOFORCE
return fatalError( '** hwthset (HWTH_OPT_PORT) failure Port**' )
end /* endif hwthset failure */
/*******************************************************************/
/* Set URI for connection, aka your host location */
/*******************************************************************/
ConnectionUri = CONNECTION_URI
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"ConnectionHandle ",
"HWTH_OPT_URI ",
"ConnectionUri ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate ConnectionHandle, HWTH_NOFORCE
return fatalError( '** hwthset (HWTH_OPT_URI) failure ConnURI**' )
end /* endif hwthset failure */
/*********************************************************************/
/* Set the HWTH_OPT_USE_SSL option to use a SSL connection */
/*********************************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"ConnectionHandle ",
"HWTH_OPT_USE_SSL ",
"HWTH_SSL_USE ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthset (HWTH_OPT_USE_SSL) failure **' )
end /* endif hwthset failure */
/*********************************************************************/
/* Set the HWTH_OPT_SSLKEYTYPE option for a SAF Keyring */
/*********************************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"ConnectionHandle ",
"HWTH_OPT_SSLKEYTYPE ",
"sslKeyType ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthset (HWTH_OPT_SSLKEYTYPE) failure **' )
end /* endif hwthset failure */
/*********************************************************************/
/* Set the HWTH_OPT_SSLKEY option to the SAF Keyring name */
/*********************************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"ConnectionHandle ",
"HWTH_OPT_SSLKEY ",
"sslKey ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthset (HWTH_OPT_SSLKEY) failure **' )
end /* endif hwthset failure */
/*********************************************************************/
/* Set the HWTH_HWTH_OPT_SSLKEYSTASHFILE */
/*********************************************************************/
if sslKeyType == 'HWTH_SSLKEYTYPE_KEYDBFILE' then
do
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"ConnectionHandle ",
"HWTH_OPT_SSLKEYSTASHFILE ",
"KEYSTASHFILE ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthset (HWTH_OPT_SSLKEY) failure **' )
end /* endif hwthset failure */
end
/*********************************************************************/
/* Set the HWTH_OPT_SSLVERSION */
/*********************************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"ConnectionHandle ",
"HWTH_OPT_SSLVERSION ",
"SSLVERSION ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthset (HWTH_OPT_SSLVERSION) failure **' )
end /* endif hwthset failure */
/********************************************************************/
/* Set HWTH_OPT_COOKIETYPE */
/* Enable the cookie engine for this connection. Any "eligible" */
/* stored cookies will be resent to the host on subsequent */
/* interactions automatically. */
/********************************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"ConnectionHandle ",
"HWTH_OPT_COOKIETYPE ",
"HWTH_COOKIETYPE_SESSION ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate ConnectionHandle, HWTH_NOFORCE
return fatalError( '** hwthset (HWTH_OPT_COOKIETYPE) failure **' )
end /* endif hwthset failure */
return 0 /* end function */
/*************************************************************/
/* Function: HTTP_connect */
/* */
/* Connect to the configured domain (host) via the HWTHCONN */
/* toolkit api. */
/* */
/* Returns: 0 if successful, -1 if not */
/*************************************************************/
HTTP_connect:
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthconn ",
"ReturnCode ",
"ConnectionHandle ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthconn', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthconn failure **' )
end
return 0 /* end function */
/************************************************************/
/* Function: HTTP_setupRequest */
/* */
/* Sets the necessary request options. The global variable */
/* RequestHandle orients the api as to the scope of the */
/* option(s). */
/* */
/* Returns: 0 if successful, -1 if not */
/************************************************************/
HTTP_setupRequest:
if p3 /= '' then
do
acceptAutoHeader = 'Authorization: Bearer 'Token''
Say 'Bearer token is: ' acceptAutoHeader
/*********************************************************************/
/* Create a brand new SList and specify the first header to be an * */
/* "Accept" header that requests that the server return any response */
/* body text in JSON format. * */
/*********************************************************************/
address hwthttp "hwthslst ",
"ReturnCode ",
"RequestHandle ",
"HWTH_SLST_NEW ",
"SList ",
"acceptAutoHeader ",
"DiagArea."
/*******************************************************/
/* Set the request headers with the just-produced list */
/*******************************************************/
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_HTTPHEADERS ",
"SList ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate ConnectionHandle, HWTH_NOFORCE
return fatalError( '** hwthset (HWTH_OPT_HEADER) failure HEADER**' )
end /* endif hwthset failure */
end /* endif p3=' ' */
/**************************************************************/
/* Set HTTP Request method. */
/* A GET request method is used to get data from the server. */
/**************************************************************/
Request_Method = 'HWTH_HTTP_REQUEST_'p2''
/* say 'built Request method: ' Request_Method */
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_REQUESTMETHOD ",
"Request_Method ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate RequestHandle, HWTH_NOFORCE
return fatalError('** hwthset (HWTH_OPT_REQUESTMETHOD) failure **')
end /* endif hwthset failure */
/*if p2 == 'POST' then do */
/* say 'maxim maimon is POST' */
/**************************************************************/
/* Set the request body */
/**************************************************************/
RequestBody = Json
returnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_REQUESTBODY ",
"RequestBody ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
return fatalError ('hwthset (HWTH_OPT_REQUESTBODY) failure **')
end /* endif hwthset failure */
/******************************************************************/
/* Have the toolkit convert the request body from ASCII to EBCDIC */
/******************************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_TRANSLATE_REQBODY ",
"HWTH_XLATE_REQBODY_E2A ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthset (HWTH_OPT_TRANSLATE_RESPBODY) ',
'failure **' )
end /* endif hwthset failure */
/* end *//* if p2=get */
/*****************************************************************/
/* Set the request URI */
/* Set the URN URI that identifies a resource by name that is */
/* the target of our request. */
/*****************************************************************/
requestPath = REQUEST_URI
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_URI ",
"requestPath ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate RequestHandle, HWTH_NOFORCE
return fatalError( '** hwthset (HWTH_OPT_URI) failure **' )
end /* endif hwthset failure */
/*********************************************************/
/* Set the stem variable for receiving response headers */
/*********************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_RESPONSEHDR_USERDATA ",
"ResponseHeaders. ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate RequestHandle, HWTH_NOFORCE
return fatalError( '** hwthset (HWTH_OPT_RESPONSEHDR_USERDATA) failed **')
end /* endif hwthset failure */
/*******************************************************************/
/* Have the toolkit convert the response body from ASCII to EBCDIC */
/* (so that we may pass it to our parser in a form that the latter */
/* will understand) */
/*******************************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_TRANSLATE_RESPBODY ",
"HWTH_XLATE_RESPBODY_A2E ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate RequestHandle, HWTH_NOFORCE
return fatalError( '** hwthset (HWTH_OPT_TRANSLATE_RESPBODY) failed **' )
end /* endif hwthset failure */
/*************************************************/
/* Set the variable for receiving response body */
/**************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_RESPONSEBODY_USERDATA ",
"ResponseBody ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
call HTTP_terminate RequestHandle, HWTH_NOFORCE
return fatalError( '** hwthset (HWTH_OPT_RESPONSEBODY_USERDATA) failed **')
end /* endif hwthset failure */
/*************************************************************/
/* Set any request header(s) we may have. This depends upon */
/* the Http request (often we might not have any). */
/*************************************************************/
if p3 == '' then
do
call HTTP_setRequestHeaders
if RESULT <> 0 then
return fatalError( '** Unable to set Request Headers **' )
end
return 0 /* end function */
/****************************************************************/
/* Function: HTTP_disconnect */
/* */
/* Disconnect from the configured domain (host) via the */
/* HWTHDISC toolkit api. */
/* */
/* Returns: 0 if successful, -1 if not */
/****************************************************************/
HTTP_disconnect:
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthdisc ",
"ReturnCode ",
"ConnectionHandle ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthdisc', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthdisc failure **' )
end /* endif hwthdisc failure */
return 0 /* end function */
/****************************************************************/
/* Function: HTTP_terminate */
/* */
/* Release the designated Connection or Request handle via the */
/* HWTHTERM toolkit api. */
/* */
/* Returns: */
/* 0 if successful, -1 if not */
/****************************************************************/
HTTP_terminate:
handleIn = arg(1)
forceOption = arg(2)
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthterm ",
"ReturnCode ",
"handleIn ",
"forceOption ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthterm', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthterm failure **' )
end /* endif hwthterm failure */
return 0 /* end function */
/****************************************************************/
/* Function: HTTP_request */
/* */
/* Make the configured Http request via the HWTHRQST toolkit */
/* api. */
/* */
/* Returns: 0 if successful, -1 if not */
/****************************************************************/
HTTP_request:
say 'Issuing GET request to' CONNECTION_URI||REQUEST_URI
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthrqst ",
"ReturnCode ",
"ConnectionHandle ",
"RequestHandle ",
"HttpStatusCode ",
"HttpReasonCode ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then
do
call HTTP_surfaceDiag 'hwthrqst', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthrqst failure **' )
end /* endif hwthrqst failure */
/****************************************************************/
/* The ReturnCode indicates merely whether the request was made */
/* (and response received) without error. The origin server's */
/* response, of course, is another matter. The HttpStatusCode */
/* and HttpReasonCode record how the server responded. Any */
/* header(s) and/or body included in that response are to be */
/* found in the variables which we established earlier. */
/****************************************************************/
ResponseStatusCode = strip(HttpStatusCode,'L',0)
ResponseReasonCode = strip(HttpReasonCode)
return 0 /* end function */
/*************************************************************/
/* Function: HTTP_isError */
/* */
/* Check the input processing codes. Note that if the input */
/* RexxRC is nonzero, then the toolkit return code is moot */
/* (the toolkit function was likely not even invoked). If */
/* the toolkit return code is relevant, check it against the */
/* set of { HWTH_xx } return codes for evidence of error. */
/* This set is ordered: HWTH_OK < HWTH_WARNING < ... */
/* with remaining codes indicating error, so we may check */
/* via single inequality. */
/* */
/* Returns: 1 if any toolkit error is indicated, 0 */
/* otherwise. */
/*************************************************************/
HTTP_isError:
RexxRC = arg(1)
if RexxRC <> 0 then
return 1
ToolkitRC = strip(arg(2),'L',0)
if ToolkitRC == '' then
return 0
if ToolkitRC <= HWTH_WARNING then
return 0
return 1 /* end function */
/*************************************************************/
/* Function: HTTP_isWarning */
/* */
/* Check the input processing codes. Note that if the input */
/* RexxRC is nonzero, then the toolkit return code is moot */
/* (the toolkit function was likely not even invoked). If */
/* the toolkit return code is relevant, check it against the */
/* specific HWTH_WARNING return code. */
/* */
/* Returns: 1 if toolkit rc HWTH_WARNING is indicated, 0 */
/* otherwise. */
/*************************************************************/
HTTP_isWarning:
RexxRC = arg(1)
if RexxRC <> 0 then
return 0
ToolkitRC = strip(arg(2),'L',0)
if ToolkitRC == '' then
return 0
if ToolkitRC <> HWTH_WARNING then
return 0
return 1 /* end function */
/***********************************************/
/* Procedure: HTTP_surfaceDiag() */
/* */
/* Surface the input error information. */
/***********************************************/
HTTP_surfaceDiag: procedure expose DiagArea.
say
say '*ERROR* ('||arg(1)||') at time: '||Time()
say 'Rexx RC: '||arg(2)', Toolkit ReturnCode: '||arg(3)
say 'DiagArea.Service: '||DiagArea.HWTH_service
say 'DiagArea.ReasonCode: '||DiagArea.HWTH_reasonCode
say 'DiagArea.ReasonDesc: '||DiagArea.HWTH_reasonDesc
say
return /* end procedure */
/***********************************************/
/* Function: fatalError */
/* */
/* Surfaces the input message, and returns */
/* a canonical failure code. */
/* */
/* Returns: -1 to indicate fatal script error. */
/***********************************************/
fatalError:
errorMsg = arg(1)
say errorMsg
return -1 /* end function */
/*************************************************************/
/* Function: HTTP_setRequestHeaders */
/* */
/* Add appropriate Request Headers, by first building an */
/* "SList", and then setting the HWTH_OPT_HTTPHEADERS */
/* option of the Request with that list. */
/* */
/* Returns: 0 if successful, -1 if not */
/*************************************************************/
HTTP_setRequestHeaders:
SList = ''
acceptJsonHeader = 'Accept:application/json'
acceptLanguageHeader = 'Accept-Language: en-US'
contentTypeHeader = 'Content-Type: application/json'
/*********************************************************************/
/* Create a brand new SList and specify the first header to be an */
/* "Accept" header that requests that the server return any response */
/* body text in JSON format. */
/*********************************************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthslst ",
"ReturnCode ",
"RequestHandle ",
"HWTH_SLST_NEW ",
"SList ",
"acceptJsonHeader ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthslst', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthslst (HWTH_SLST_NEW) failure **' )
end /* endif hwthslst failure */
/***********************************************************/
/* Append the Accept-Language request header to the SList */
/* to infer to the server the regional settings which are */
/* preferred by this application. */
/***********************************************************/
address hwthttp "hwthslst ",
"ReturnCode ",
"RequestHandle ",
"HWTH_SLST_APPEND ",
"SList ",
"acceptLanguageHeader ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthslst', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthslst (HWTH_SLST_APPEND) failure **' )
end /* endif hwthslst failure */
/*************************************************************/
/* Append the Content-Type request header to the SList */
/* which is used when data is sent using a HTTP POST or PUT. */
/* preferred by this application. */
/*************************************************************/
address hwthttp "hwthslst ",
"ReturnCode ",
"RequestHandle ",
"HWTH_SLST_APPEND ",
"SList ",
"contentTypeHeader ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthslst', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthslst (HWTH_SLST_APPEND) failure **' )
end /* endif hwthslst failure */
/************************************/
/* Set the request headers with the */
/* just-produced list */
/************************************/
ReturnCode = -1
DiagArea. = ''
address hwthttp "hwthset ",
"ReturnCode ",
"RequestHandle ",
"HWTH_OPT_HTTPHEADERS ",
"SList ",
"DiagArea."
RexxRC = RC
if HTTP_isError(RexxRC,ReturnCode) then do
call HTTP_surfaceDiag 'hwthset', RexxRC, ReturnCode, DiagArea.
return fatalError( '** hwthset (HWTH_OPT_HTTPHEADERS) failure **' )
end /* endif hwthset failure */
return 0 /* end function */Set the required variables according to your environment.
The following table describes the variables:Variable
Description
PROTOCOLCRA server protocol type for the API request
HOSTName of the mainframe host where the CRA server is running
PORTPort number of the CRA server
SERVICEName of the service (for MVE host server) that you want to use
USERNAMEYour mainframe user credentials
Make sure that required SAF permissions for the user are properly defined.
PASSWORDPRODUCTName of the product you want to retrieve data from
VIEWName of the views that you want to retrieve data for that product
SSLVERSIONUse one of the following supported versions:
- HWTH_SSLVERSION_TLSv13—supports TLS version 1.3
- HWTH_SSLVERSION_TLSv12— supports TLS version 1.2
- HWTH_SSLVERSION_TLSv11— supports TLS version 1.1
SSL Key typesSet to one of the following values:
- SAFKEYRING—a SAF key ring name in the form of userid and keyring
KEYDBFILE and KEYSTASHFILE—set when CRA is configured with a local
keystoreImportant
If using the KEYDBFILE and KEYSTASHFILE values, make sure that:
- A keystore is exported first and then imported using
the GSKKYMAN utility. - Convert it into a .kdb database format.
- Create a stash password file.
- A keystore is exported first and then imported using
Go to the ISPF TSO command panel and run the following command:
EX 'dataSet(member)'
You should get a similar output as shown in the following sample:Click here to expand...
Get list of services API call
Sample Begin
Issuing GET request to http://sysp/cra/serviceGateway/services
HTTP status: 200
HTTP reason: (empty)
Response body contains: 3280 bytes.
[{"HOSTCN":"172.22.45.120","HOSTIP":"172.22.45.120","PORT":3331,"TLS":"N","WEBSERVICEName":"MVERESTAPI_SYSB","STATUS":"ACTIVE"},
{"HOSTCN":"ESAK.BMC.COM","HOSTIP":"172.22.45.120","PORT":7822,"TLS":"N","WEBSERVICEName":"MVERESTAPI_SYSC","STATUS":"ACTIVE"},
{"HOSTCN":"sjsc","HOSTIP":"","PORT":7182,"TLS":"N","WEBSERVICEName":"Mvb","STATUS":"ACTIVE","DESCRIPTION":"Primary Test Target - Update at 1651569796802"},
]
Sample EndLog in API call
Sample Begin
Issuing GET request to http://sysp/cra/serviceGateway/services/Mva/login
HTTP status: 200
HTTP reason: (empty)
Response body contains: 52 bytes.
{
"userToken":"a0092d96-d2c3-46a0-8a2c-5fc0736f7840"
}
Sample EndGet data by parameters API call
Sample Begin
Bearer token is: Authorization: Bearer a0092d96-d2c3-46a0-8a2c-5fc0736f7840
Issuing GET request to http://sysp/cra/serviceGateway/services/Mva/products/MVMVS/views/JCPU/data?rows=1
HTTP status: 200
HTTP reason: (empty)
Response body contains: 2900 bytes.
{
"rc": 0,
"system": "BAOI",
"viewName": "JCPU",
"startRow": 1,
"numRows": 1,
"context": "BAOI",
"Columns": {
"ASGRNMC": "C(8)",
"ASRESCPN": "N(4.0)",
"JACT$INT": "D(10),T(5)",
"SYSNAME": "C(8)",
"M390IND": "C(1)",
"ASGJSFLY": "C(4)",
"ASGJELT": "T(8)"
},
"totalRows": 1,
"version": "2.1.00",
"productName": "MVMVS",
"Rows": [
{
"ASGRNMC": "",
"ASRESCPN": "2",
"JACT$INT": [
{
"0": "2022/08/30 02:00:12.23"
},
{
"1": "2022/08/30 02:00:12.23"
}
],
}
]
}
Sample End
***