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. 

  1. 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();
        }
    }
  2. Open the file in your preferred editor and set the required variables according to your environment.
    The following table describes the variables:

    Variable

    Description

    PROTOCOL

    CRA server protocol type for the API request    

    HOST 

    Name of the mainframe host where the CRA server is running

    PORT 

    Port number of the CRA server

    SERVICE 

    Name of the service (for MVE host server) that you want to use    

    PRODUCT 

    Name of the product you want to retrieve data from

    VIEW 

    Name of the views that you want to retrieve data for that product

    USERNAME 

    Your mainframe user credentials

    Make sure that required SAF permissions for the user are properly defined.



    PASSWORD 
    NEW_SERVICE_HOST

    Name of the new service host if a service is not registered on a CRA server

    NEW_SERVICE_PORT

    Name of the new service port if a service is not registered on a CRA server

    RESPONSE_FILE_PATH

    Path (including a file name) from where a return data from the CRA API calls is written

  3. Open the command prompt and go to the directory where your Sample.java file is located. 
  4. Compile the class using the following command:
    javac Sample.java
  5. 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.

  1. 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)

  2. Open the file in your preferred editor and set the required variables according to your environment.
    The following table describes the variables:

    Variable

    Description

    PROTOCOL

    CRA server protocol type for the API request    

    HOST 

    Name of the mainframe host where the CRA server is running

    PORT 

    Port number of the CRA server

    SERVICE 

    Name of the service (for MVE host server) that you want to use    

    USERNAME 

    Your mainframe user credentials

    Make sure that required SAF permissions for the user are properly defined.


    PASSWORD 
    PRODUCT 

    Name of the product you want to retrieve data from

    VIEW 

    Name of the views that you want to retrieve data for that product

    NEW_SERVICE_HOST

    Name of the new service host if a service is not registered on a CRA server

    NEW_SERVICE_PORT

    Name of the new service port if a service is not registered on a CRA server

  3. Open the command prompt and go to the directory where the PythonSample.py file is located.
  4. 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.

  1. 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!"
  2. Open the file in your preferred editor and set the required variables according to your environment.
    The following table describes the variables:

    Variable

    Description

    PROTOCOL

    CRA server protocol type for the API request    

    HOST 

    Name of the mainframe host where the CRA server is running

    PORT 

    Port number of the CRA server

    USERNAME 

    Your mainframe user credentials

    Make sure that required SAF permissions for the user are properly defined.


    PASSWORD 
    SERVICE

    Name of the service (for MVE host server) that you want to use 

    PRODUCT 

    Name of the product you want to retrieve data from

    VIEW 

    Name of the views that you want to retrieve data for that product

  3. Enter the following command to run your sample code:
    ./file_name.sh
  4. 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.

  1. Log on to the mainframe using your valid user credentials. 
  2. Create a new member in your PDS data set.
  3. 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 */
  4. Set the required variables according to your environment.
    The following table describes the variables:

    Variable

    Description

    PROTOCOL

    CRA server protocol type for the API request    

    HOST 

    Name of the mainframe host where the CRA server is running

    PORT 

    Port number of the CRA server

    SERVICE

    Name of the service (for MVE host server) that you want to use 

    USERNAME 

    Your mainframe user credentials

    Make sure that required SAF permissions for the user are properly defined.


    PASSWORD 
    PRODUCT 

    Name of the product you want to retrieve data from

    VIEW 

    Name of the views that you want to retrieve data for that product

    SSLVERSION

    Use 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 types

    Set 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   
       keystore

      Important

      If using the KEYDBFILE and KEYSTASHFILE values, make sure that:

      1. A keystore is exported first and then imported using 
        the GSKKYMAN utility.
      2. Convert it into a .kdb database format.
      3. Create a stash password file.
  5. 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 End                                                                                                                         

    Log 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 End                                                                                                                         

    Get 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                                                                                                                         
    ***                                                                                                                                                            

 

Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*