Previous Topic: Deploy and Configure CA OPS/MVS Web ServicesNext Topic: Making Web Service Requests to Generate an API Event


Configure Tomcat for HTTPS (HTTP Secure)

You can optionally configure your Tomcat server to use HTTPS instead of HTTP for user access. Because HTTPS includes SSL encryption, this option alleviates concerns about exposing the data in clear text on the network.

Apache Tomcat is an Open-source third-party product. Apache provides documentation to help you configure SSL for Tomcat with the Apache Tomcat SSL Configuration HOW-TO. You can use the Apache Tomcat HTTP Connector Reference to look up the definitions of the configuration properties that the HOW-TO document utilizes. You can also find other web tutorials that describe the configuration. Locate and follow the steps that are appropriate for the version of Apache Tomcat that your CA OPS/MVS release installed. There are three methods that you can use for your keystore file.

Method 1: Use an existing trusted certificate

Follow this step:

  1. Use the keytool program to create the keystores, truststores, and certificates to achieve your desired security configuration.

    Note: For more information about trusted certificates, see the Apache Tomcat 7.0 on the Web (Apache Tomcat 7.0 SSL Configuration HOW-TO).

Method 2: Create and use your own self-signed certificate
Follow these steps:
  1. Select the appropriate method to create a keystore that contains a self-signed certificate:
  2. Execute the sample scripts that are provided in the {CCS_installation_dir}/OPS/distrib directory.

    For example:

  3. Copy file .keystore file from {CCS_installation_dir}/OPS/distrib to your {CCS_installation_dir}/OPS/tomcat/conf.
  4. Save the full path to the .keystore file under {CCS_installation_dir}/OPS/tomcat/conf. You have to specify this path later on the keystoreFile keyword that server.xml specifies.

    Note: The JCL job [hlq].OPS.CCLXCNTL(OPWBSVMK) lets you execute the makeks and listks scripts in a batch environment. You must customize this JCL before it is submitted at your site.

Method 3: Complete the following steps to generate a keystore containing a self-signed certificate manually
Follow these steps:
  1. Enter the following command from the USS command line (OMVS):
    cd {CCS_installation_dir}/OPS/distrib
    $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA -keystore .keystore
    

    A series of prompts appears:

  2. Specify a password, press Enter, and answer the following questions:

After you use one of the three methods, continue with the following steps and complete the Tomcat configuration:

  1. (Optional) Enter the following command from the USS command line (OMVS) and verify the contents of your keystore:
    cd {CCS_installation_dir}/OPS/distrib
    
    $JAVA_HOME/bin/keytool -list -keystore .keystore
    

    The results appear like the following example:

    Enter keystore password:
    Keystore type: jks
    Keystore provider: IBMJCE
    Your keystore contains 1 entry
    
    Alias name: tomcat
    Creation date: Feb 3, 2014
    Entry type: keyEntry
    Certificate chain length: 1
    Certificate[1]:
    Owner: CN=tomcat, OU=CA, O=CA, L=Pittsburgh, ST=PA, C=US
    Issuer: CN=tomcat, OU=CA, O=CA, L=Pittsburgh, ST=PA, C=US
    Serial number: 114822b8
    Valid from: 2/3/14 8:15 AM until: 5/4/14 9:15 AM
    ...
    
  2. Within the Tomcat server.xml configuration file, modify the Connector element which has port="8443".

    This port is the TLS connector. Specify a keystore file and a keystore password.

    1. Update the Apache Tomcat configuration parameters in the server.xml file as follows:
      • If you use the Tomcat that CA Common Services distributed, you can locate the server.xml configuration file under {CCS_installation_dir}/OPS/tomcat/conf.
      • If you use your own Tomcat server, you can locate the server.xml configuration file under {tomcat_home}/conf.
      • Understand that server.xml is an ASCII file. As such, you must use ISPF 3.17 to edit server.xml.

      A typical connector element for an SSL port appears like the following example:

      <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
      	maxThreads="150" scheme="https" secure="true"
      	clientAuth="false" sslProtocol="TLS" />
      

      Important! You must uncomment this connector element if it is commented. Comment blocks are defined in this file by a starting token of “<!--“ and an ending token of “-->

    2. Add the keystoreFile and keystorePassword keywords as follows:

      Figure 1

      <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
          maxThreads="150" scheme="https" secure="true"
          clientAuth="false" sslProtocol="TLS"
          sslEnabledProtocols=”TLSv1.2,TLSv1.1,TLSv1″
          keystorePass="tomcat"
          keystoreFile="{CCS_installation_dir)/OPS/distrib/.keystore"
      />
      

      We also recommend that you disable SSLv3 in your Internet browser and on your web clients before connecting to CA OPS/MVS web services. Disabling SSLv3 on either client side or server side will mitigate the vulnerability to cyber-attack due to recent compromises with the SSLv3 protocol.

      Note: To avoid the potential for cyber-attack, we recommend that you disable SSLv3 in your Apache Tomcat web server. Specify the sslEnabledProtocols attribute (see Figure 1) with only the TLS protocols listed. This step avoids usage of the older SSL protocols. You can find documentation about the sslEnabledProtocols attribute in the JVM documentation under method SSLSocket.setEnabledProtocols(). See the Oracle JDK documentation for Java 7 or Java 8.

      If you want to use client certificate authentication, follow these basic steps:

      • Generate a self-signed server-certificate on the server (Tomcat host).
      • Download the server-certificate to the client.
      • Import the server-certificate to the Java-keystore of the client.
      • Generate a self-signed client-certificate on the client.
      • Upload it to the server.
      • Import the client-certificate to the Java-keystore of the Tomcat server.
      • Configure Tomcat to use this keystore.
      • If you want to ensure that the client connections are also authorized by certificate, set clientAuth="true" in server.xml.

      Note: For specific details about accomplishing these tasks, see the Apache Tomcat 7.0 SSL Configuration HOW-TO Java™ Secure Socket Extension (JSSE) Reference Guide.

  3. Add the following lines before </web-app> at the end of the web.xml file that is located in {tomcat_dir}/conf:
    <security-constraint>
    
    <web-resource-collection>
    	<web-resource-name>Tomcat</web-resource-name>
    	<url-pattern>*.html</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
    	<transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
    
    </security-constraint>
    
  4. After you restart Tomcat, you now have access to your URIs over both a Secured connection and with an unencrypted connection.

    This test assumes that you retained the default TLS port number of 8443.

  5. (Optional) After you tested your secured connection successfully, you can disable (comment out) the unencrypted Connector element, which has port 8080. This procedure prevents Tomcat from serving any requests over the unencrypted connection.

Making Web Service Requests for RDF Table Data

You can retrieve a resource by issuing a GET request with its URI. You can specify the URI directly into an internet browser or can write a web-capable program to make the request.

Example Web Services Calls

The following RESTful Requests table shows these URIs:

URI

Description

GET /opsmvs/web/tables

Retrieves the list of RDF tables from the OPS subsystem

GET /opsmvs/web/tables/tablename

Retrieves the list of columns associated with table tablename

GET /opsmvs/web/tables/table1…table2

Retrieves the list of columns associated with tables named table1 … table2

This list is delimited by a space between table names.

GET /opsmvs/web/tables/tablename/column1

Retrieves data from table tablename and single column column1

GET /opsmvs/web/tables/tablename/column1 … columnN

Retrieves data from table tablename and multiple columns column1 … columnN (space separated)

This list is delimited by a space between column names.

GET /opsmvs/web/tables/tablename/*

Retrieves data from all columns of table tablename

Qualifying RDF Table URI Requests

You can refine the request further with query strings. A query string is an optional component of the URI that you can use to send further qualifying information about the request to the server. The query string is composed of a series of field-value pairs. If you specify more than one query string field-value pair on the same URI request, you must separate them using an ampersand “&” character.

For example: ?sub=OPST&system=OPSMSF1

Subsystem Query String

Generally, query strings consist of keyword/value pairs as is the case in the following table:

Query String

Meaning

?sub=OPSx

Use OPS subsystem OPSx to request table data.

You must specify a subsystem name that runs currently on the same host as the OPS web services server.

Note: All requests are relative to the host to which the request is directed.

If the subsystem that you specified does not exist on the server host, you receive the following error:

OPx7800I SQL COMMAND REJECTED - SUBSYSTEM OPSx IS NOT ACTIVE

sqlcode = -7800

The following Qualifying URI Requests table shows these query strings attached to the URI:

URI

Description

GET /opsmvs/web/tables?sub=OPST

Retrieves the list of RDF tables from the OPS subsystem identified by subsystem name OPST

GET /opsmvs/web/tables/tablename?sub=OPST

Retrieves the list of columns associated with table tablename from OPS subsystem OPST

MSF SystemId Query String

The following table shows the MSFid SystemId query string:

Query String

Meaning

?system=MSFid

Direct the URI request to an MSF-connected system id. The MSFid must be active on the z/OS system where web services is hosted.

Note: All requests are relative to the host to which the request is directed.

If the MSF system that you specified does not exist or is not active on the server host, you receive one of the following errors:

OPx7588E SYSTEM ID ( sysid ) IS NOT AN ACTIVE MSF SYSTEM

RC=8

AppCode = -7588

OPx7589E SYSTEM ID ( sysid ) NOT DEFINED TO MSF

RC=8

AppCode=-7589

Query String

Meaning

GET /opsmvs/web/tables?system=OPS55T

Retrieves the list of RDF tables from the MSF system-id OPS55T.

GET /opsmvs/web/tables/STCTBL?system=OPS55T

Retrieves the list of columns associated with table STCTBL from MSF system-id OPS55T.

GET /opsmvs/web/tables

?sub=OPST&system=OPS55T

Retrieves the list of RDF tables OPS subsystem identified by subsystem name OPST and from the OPS MSF sysid identified by MSF id OPS55T.

Where Query String

The following table shows the where query string:

Query String

Meaning

?where="where_clause"

Filter the request with the given where clause.

You must enclose the where clause in double quotes, and the contents within the double quotes must follow the syntax as defined for WHERE on the OPSQL command.

Note: You must percent-encode the where_clause's on the client side to replace spaces and other special characters with HTTP safe values.

Note: The where query string is only accepted on URIs that request table data, for example, URIs that specify at least one column name. The where query string is not accepted on a table list request (/opsmvs/web/tables) or a column list request (/opsmvs/web/tables/tablename). The where query string cannot contain semi-colons “;” due to its use as a command separator.

Query String

Meaning

GET /opsmvs/web/tables/STCTBL/NAME

MODE?where=”MODE='ACTIVE'”

Retrieves the data from column NAME but only returns those rows where the MODE column is ACTIVE.

GET /opsmvs/web/tables/STCTBL/

NAME CURRENT_STATE

?where=”NAME LIKE 'ACTIVE'”

Retrieves the data from columns NAME and CURRENT_STATE but only returns those rows where the NAME is ACTIVE.

GET /opsmvs/web/tables/COLUMN/*

?where=”COL>=7 AND NAME LIKE 'A%'“

--- Percent-Encoded ---

/opsmvs/web/tables/COLUMN/*

?where=”COL%3E=7%20AND

NAME%20LIKE%20%27A%25%27”

Retrieve data from all columns where the value of COL is greater than or equal to 7 and value of NAME starts with “A”.

Making Web Service Request to Execute REXX in OSF Server

The osfrexx web service is asynchronous in nature. The first part, a POST, is the mechanism to queue your OPS/REXX program to an OSF server. The POST executes the OPS/MVS ‘address OSF OI’ function and in return gets a unique response id. The second part, if you want to use it, is a GET web service call, to retrieve any output from the OPS/REXX program you have previously initiated. If all you need to do is initiate a REXX program, you merely need to do the POST. If the target program never calls OPWSOUT, there is no output generated and no additional overhead is incurred.

You can execute an OPSREXX application that already resides on the target Z/OS system using an HTTP POST request. The POST requires the request to include XML data which allows the requester to specify the target REXX’s name, arguments and what type of OSF server to run the REXX on. This XML is defined with the following schema:

<?xml version="1.0" encoding="utf-8"?>
<OSFRexx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.ca.com/automation/opsmvs/websvc/msgData OSFRexx.xsd"
    xmlns="http://www.ca.com/automation/opsmvs/websvc/msgData">
<Program>
<ProgramName>program name</ProgramName> 
<Args>arguments</Args>
<!-- Server accepts one of: OSFTSO, OSFTSL, OSFTSP -->
<Server>OSFTSO</Server>
<Program>
</OSFrexx>

The Program tag specifies the name of the target OPSREXX application.

Note: The target REXX must be on the same system and must exist in one of the datasets in the SYSEXEC DD concatenation.

Security Requirements: In the case where OSFSECURITY is set to CHECKUSERID, in order for the underlying OI (OPSIMEX) to execute, the z/OS credentials you specify with this web request must have READ access to each of the datasets in the SYSEXEC concatenation of the OSF servers. If OSFSECURITY is set to NOSECURITY, the z/OS credentials from your web request are not propagated to the OSF server; instead the z/OS credentials associated with the OSF PROC are used.

The Args tag specifies arguments. Arguments are passed to the target REXX exactly as they appear between the Args tags. If the target REXX application does not have arguments, leave the content between the Args tag blank.

Note: All tags including the Args tag must be present in all osfrexx POST requests.

The Server tag specifies the type of OSF server to execute the target REXX in. Server can be one of three possible values:

OSF REXX Web Services Calls

The following shows the RESTful Request URI and sample POST xml:

URI: POST opsmvs/web/osfrexx

XML

Meaning

<?xml version="1.0" encoding="utf-8"?>

<OSFRexx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.ca.com/automation/opsmvs/websvc/msgData OSFRexx.xsd"

xmlns="http://www.ca.com/automation/opsmvs/websvc/msgData">

<Program>

<ProgramName>OPWSDEMO</ProgramName>

<Args></Args>

<Server>OSFTSO</Server>

</Program>

</OSFRexx>

Execute the REXX program OPWSDEMO on an OSF server.

<?xml version="1.0" encoding="utf-8"?>

</Program>

<OSFRexx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.ca.com/automation/opsmvs/websvc/msgData OSFRexx.xsd"

xmlns="http://www.ca.com/automation/opsmvs/websvc/msgData">

<Program>

<ProgramName>OPWSDEMO</ProgramName>

<Args>SAMPLE SECWSGV</Args>

<Server>OSFTSL</Server>

</Program>

</OSFRexx>

Execute the REXX program OPWSDEMO on a long running OSF server (OSFTSL) with the arguments “SAMPLE SECWSGV”.

The POST web request returns one of the following XML documents.

In the case of an error, an XML document containing relevant error information is returned in the HTTP body that conforms to the WSResult schema.

In the case of a successful OSF REXX start requests, an XML document containing a unique response identifier is returned in the HTTP body that conforms to the OSFRexx schema. This schema contains a AppCode element and value. This value is a unique key (response-ID) that can be used on subsequent GET osfrexx requests to track the progress of the request and retrieve any results explicitly saved by the target OSF REXX application. Also, the Program element has an attached href attribute that contains a full URI link. You can use this href internally by your managing web application to provide a clickable link directly to the responses of the OSF/REXX program.

The following example shows the OSFRexx schema returned from a POST osfrexx request:

<?xml version="1.0" standalone="yes"?>
<OSFRexx schemaVersion="1.0" xsi:schemaLocation="http://www.mydomain.com/automation/opsmvs/websvc/msgData"
   xmlns="http://www.mydomain.com/automation/opsmvs/websvc/msgData"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Program href="https://myserver:38443/opsmvs/web/osfrexx/OPWSDEMO/1000022">
      <ProgramName>OPWSDEMO</ProgramName>
   </Program>
   <AppInfo>
      <AppCmd>OI OPWSDEMO TEST1 GLVSEC</AppCmd>
      <AppCode>1000022</AppCode>
      <AppRC>0</AppRC>
      <Reason>Successfully sent to the OSFTSO execute queue.</Reason>
   </AppInfo>
</OSFRexx>

In this example, the response-ID for the request is 1000022.

What is expected of the OPS/REXX program?

Retrieving Responses from OSF REXX Programs

The POST OSF REXX web request described above only initiates the request to the run the specified OSF REXX program on an OSF server. Depending on OSF parameters, the initiated REXX program can run immediately or can be queued. Therefore, any results from the REXX program are not returned directly to the web client.

You must complete these steps to retrieve results:

  1. Your web client program must retrieve the unique response-ID code (see OSFRexx schema above) from the AppCode element or the href attribute attached to the Program element.
  2. Your web client program must explicitly issue another web request (GET osfrexx/programName/response-ID) to collect the results and determine whether the program completed.
  3. You must determine exactly what results from your OSF REXX program are to be returned to the web client by adding calls to OPWSOUT to the target program.

A utility program named OPWSOUT is provided to be called from within OSF-executed REXX programs to save the results you wish to be saved for later retrieval. Sample program OPWSDEMO is provided to demonstrate how this can be easily accomplished.

Notes:

CA OPS/MVS provides a template REXX program named OPWSDEMO which demonstrates how OPWSOUT is intended to be utilized to send back responses to a web client. The OPWSDEMO program is distributed in the CA OPS/MVS CCLXSAMP dataset.

Retrieving OPWSOUT Responses

You can retrieve the responses saved by OPWSOUT by issuing a GET request with its URI. You can specify the URI directly into an internet browser or write a web-capable program to make the request. OPWSOUT utilizes temporary global variables to save the responses.

Note: Using Temporary Global Variables provides additional information concerning global variable usage by this service.

The following shows the RESTful request URI:

GET opsmvs/web/osfrexx/program/response-ID

Example Web Services Calls

The following RESTful Requests table shows these URIs:

URI

Description

GET /opsmvs/web/osfrexx/OPWSDEMO/1000001

Retrieves the list of responses from a previously initiated OSF REXX program named OPWSDEMO. In this example, 1000001 is a unique token which was passed back to the web client by POST osfrexx.

Example: OSFRexx GET XML Response

The following example shows an excerpt from an XML response document from this URI request:

GET /opsmvs/web/osfrexx/OPWSDEMO/1000022
<?xml version="1.0" standalone="yes"?>
<OSFRexx schemaVersion="1.0" xsi:schemaLocation="http://www.mydomain.com/automation/opsmvs/websvc/msgData"
   xmlns="http://www.mydomain.com/automation/opsmvs/websvc/msgData"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Program>
      <ProgramName>OPWSDEMO</ProgramName>
   </Program>
   <Output count="6">
      <Response>Listing names of rulesets</Response>
      <Response>BASE</Response>
      <Response>SAMPLE</Response>
      <Response>STATEMAN</Response>
      <Response>TEST</Response>
      <Response>>>>>RC:0</Response>
   </Output>
</OSFRexx>

Using Temporary Global Variables

The GET osfrexx requests utilize global variables for maintaining OSF REXX program responses. Since this is the case, you should ensure that the maximum limits that are associated with global variables are not reached. Specifying OPWSOUT with huge numbers of responses or with too many large responses could use up your global variable blocks and cause problems with existing automation.

A REXX program OPWSGC (Garbage Collection) has been provided to automatically run whenever POST osfrexx requests are issued to ensure these global temporary variables are deleted in a timely manner. See parameter GLOBALTEMPWSGCIV for details.

Note: Many CA OPS/MVS parameters can influence the size and number of temporary global variables. These parameters include OSFOUTLIM, OSFTSPOUTLIM, OSFTSLOUTLIM, GLOBALMAX, and GLOBALTEMPMAX. When you decide how much output you will generate by calling OPWSOUT, we recommend that you ensure that the usage of temporary global variables does not exceed the limits which can cause problems for other automation. If you decide to make extensive use of OPWSOUT, you may also need to consider increasing the number of OSF servers by increasing the values of OSFMAX, OSFTSLMAX or OSFTSPMAX.

The global variable name begins with the prefix GLVTEMP0.#OPWEBSVC#. Since there are temporary variables, they are not preserved across restarts. Thus, responses from OSF REXX programs that are issued through web services are not available across OPS subsystem restarts.

To provide security for global variable access using CA OPS/MVS security rules, define security rules for global variable prefixes GLOBAL0.#OPWEBSVC and GLVTEMP0.#OPWEBSVC#. The following example shows an event definition for the rule:

)SEC OPSGLOBALGLOBAL0.#OPWEBSVC#*

)SEC OPSGLOBALGLVTEMP0.#OPWEBSVC#*

To provide security for global variable access with CA OPS/MVS external security, create security definitions for the following resources:

Resource: OP$MVS.OPSGLOBAL.GLOBAL0.#OPWEBSVC#

Resource: OP$MVS.OPSGLOBAL.GLVTEMP0.#OPWEBSVC#

A sample security rule for global variable access is available in the distributed CCLXRULS library. The sample rule name is SECWSGV.

Additionally, a sample rule SECWSRQ has been provided to enable usage of the OPSREQ function when the web service “osfrexx” function is invoked. This rule uses the same user list initialized by SECWSGV as therefore should be enabled concurrently with SECWSGV. The purpose of the SECWSRQ rule is to allow web service “osfrexx” callers to initiate the Garbage Collection program (OPWSGC) which cleans up global temporary variables which were saved by the OPWSOUT program.

Subsystem Query String

Generally, query strings consist of keyword/value pairs as is the case in the following table:

Query String

Meaning

?sub=OPSx

Use OPS subsystem OPSx to make the web service request.

You must specify a subsystem name that runs currently on the same host as the OPS web services server.

Note: All requests are relative to the host to which the request is directed.

If the subsystem that you specified does not exist on the server host, you receive the following error:

OPx4300I AOF command rejected - subsystem OPSx is not active

AppCode = 20

The following Qualifying URI Requests table shows these query strings attached to the URI:

Query String

Meaning

GET /opsmvs/web/osfrexx?sub=OPST

Retrieves responses from a previously executed OPS/REXX program from the OPS subsystem identified by subsystem name OPST.

POST /opsmvs/web/osfrexx?sub=OPST

Schedules execution of an OPS/REXX program on an OSF server on the subsystem identified by subsystem name OPST.