Using Wazi Analyze APIs

With Wazi Analyze APIs, you can access impact analysis results in the Wazi Analyze server without the web user interface.

Use the following navigation links to quickly locate the information that you want to learn about Wazi Analyze APIs.

Getting started with Wazi Analyze APIs

All Wazi Analyze APIs are implemented in GraphQL and respond to the POST requests according to the GraphQL query protocol. A Wazi Analyze API is an integration layer for the Wazi Analyze server data provider and requires Wazi Analyze services to be running to provide data.

To get started with Wazi Analyze APIs, complete the following steps.
  1. Configure the host container.
    The Wazi Analyze host container should have an additional port mapping that is defined for accessing the APIs. The port by default in the container image is set to 4680. When you start the Wazi Analyze container, run the following commands to add the port mapping parameter.
    -p <hostname>:4680
    Note: Replace <hostname> with your preferred port to map to, for example,
    -p 4680:4680
  2. Start up and configure the servers.

    The Wazi Analyze servers (wa-startup.sh) should be running for the API servers to be able to query the data. The order of running the startup scripts is not important. You can run the API startup script before or after you start the other Wazi Analyze servers. To start the API server, run one of the following commands on the container's bash prompt:

    1. Normal startup
      aznapi-startup.sh --bearerToken=<token>
      Note: <token> is a string of 10 characters or longer. This is a pseudo bearer token that will be needed to call all GraphQL query API. The token will be needed as part of the Authorization header on the HTTP POST request as follows:
      Authorization: bearer <token>

      The token value is not stored by the API component. Each time the component is started, you provide a token. No rules are defined as to what the content of the token can be except that it must be10 characters or longer. It might contain any combination of alphanumeric characters and special symbols except the equal sign =, hyphen -, or blank .

    2. Detached startup
      nohup aznapi-startup.sh --bearerToken=<token>

      This command will launch the API component in a detached mode and all of the console output will be redirected to file nohup.out.

    Shutting down the API server

    You can run the wa-shutdown.sh script to shut down the Wazi Analyze API server, which will shut down all the Wazi Analyze servers.

  3. Achieve authentication and authorization.

    Authentication and authorization is achieved by supplying a pseudo bearer token on each call to the Query API. Note that schema introspection queries (the information about the model) do not require a token.

  4. Access the API endpoint to view impact analysis results.
    Wazi Analyze API endpoint in the container is running on port 4680 as follows.
    https://localhost:4680/azn-graphql/v1
    You can run queries programmatically through either command line tools, such as cURL, or a browser-based REST client, such as Postman.

API Specification

Introspection

GraphQL is introspective. You can query a GraphQL schema for information about what queries it supports. No authentication is required when you query a GraphQL schema.

Listing all types defined in the schema
Use query __schema to list all types that are defined in the schema.
query {
  __schema {
    types {
      name
      kind
      description
      fields {
        name
      }
    }
  }
}
Example with cURL:
curl -X POST -H "Content-Type: application/json" -d '{"query":"query{__schema {types {name kind description fields {name}}}}"}' -k https://localhost:4680/azn-graphql/v1
Note: -k cURL switch allows to bypass strict SSL/TLS certificate validation. If you have a valid SSL/TLS certificate installed on your server, you should omit this switch.
Getting details about any type
Use query _type to get details about any type.
query {
  __type(name: "AznProject") {
    name
    kind
    description
    fields {
      name
    }
  }
}

Available APIs

You can retrieve the following information in the Wazi Analyze server through Wazi Analyze APIs.
Note: All the samples in Project API, Program API, File API, and Graph API section are using GenAppC project, the sample project that is shipped with Wazi Analyze.
Project API
The Project API retrieves information about generic project objects that are supplied by the providers. The following APIs are supported.
projects(queryString:ID): <AznBasicProject>
project(id:ID): AznBasicProject
project(id:ID): AznBasicProject    
    id:ID
    type:String
    label:String
    metadata:JSON
Sample Project API
Sample request message:
//Retrieve a list of all project ids and types
POST`https://localhost:4680/azn-graphql/v1`
Authorization: bearer 0123456789

{"query":"{ projects {id type}}" }
Sample request using cURL:
curl -X POST -H "Authorization: bearer 0123456789" -H "Content-Type: application/json" -d '{"query":"query{projects {id type}}"}' -k https://localhost:4680/azn-graphql/v1
Sample response message:
{
    "data": {
        "projects": [
            {
                "id":"GenAppC",
                "type":"project"
            },
            {
                "id":"GenApp_dev",
                "type":"project"
            },
            {
                "id":"GenApp_wrk",
                "type":"project"
            }
        ]
    }
}
Sample request message:
//Retrieve a list of project ids and metadata for all projects whose Id contains a string `wrk`
POST`https://localhost:4680/azn-graphql/v1`
Authorization: bearer 0123456789

{"query":"{ projects(queryString:\"wrk\") {id metadata}}" }
Response:
{
    "data": {
        "projects": [
            {
                "id":"GenApp_wrk",
                "metadata": {
                    "metatype":"logical",
                    "info": [
                        "GenApp_wrk",
                        "2021-05-20T02:03:24",
                        "18",
                        "94",
                        "IMPACT"
                    ]
                }
            }
        ]
    }
}
Program API
The Program API retrieves a list of generic (as defined by providers) program object names for a specified project. The following API is supported.
programs(queryString: String, projectId: ID): <AznProgram>
Sample Program API
Sample request message:
//Retrieve a list of program names (labels) for all programs whose name contains a string `LGTEST` in project `GenAppC`
{
  programs(projectId: "GenAppC", queryString: "LGTEST") {
    label
  }
}
Sample response message:
{
  "data": {
    "programs": [
      {
        "label": "LGTESTC1"
      },
      {
        "label": "LGTESTP1"
      },
      {
        "label": "LGTESTP2"
      },
      {
        "label": "LGTESTP3"
      },
      {
        "label": "LGTESTP4"
      }
    ]
  }
}
File API
The File API retrieves a list of generic (as defined by providers) file object names for a specified project. The following API is supported.
files(queryString:String, projectId:ID): <AznFile>
Sample File API
Sample request message:
//Retrieve a list of file names (labels) for all files whose name contains a string `LGC` in project `GenAppC`
{
  files(projectId: "GenAppC", queryString: "LGC") {
    label
  }
}
Sample response message:
{
  "data": {
    "files": [
      {
        "label": "LGCMAREA.CPY"
      },
      {
        "label": "LGCMARER.CPY"
      }
    ]
  }
}
Graph API

The Graph API retrieves the information about the types and relationships between and among generic (as defined by provider) program objects and/or generic file objects. The Graph response format is based on JSON Graph Format specificaion (V2).

The following API is supported.
graphs (
programName: String
fileName: String
projectId: ID
callDepth: BigInt
): [Graph]

The current provider for Wazi Analyze data is for static source code analysis. Based on the static analysis of code, the relationship between programs is a programCall type, and the relationship between files is a contain type. When you specify the programName query parameter without callDepth, the relationship edges array in the response will contain both the programCall type relationship for the specified program name and the contain type relationships for the files related to the program, such as included source files. Note that if you have duplicate program names in your project, where the duplicate program name is located in a file that has a name different from the program name, the query results will be undetermined. Also note that the File artifacts are called modules in the nodes map metadata. Contain type relationships do not have a depth specification and for programName queries, the entire set of related files will be returned, including files whose references are nested in the relationship chain.

When you specify the programName query parameter with callDepth, the relationship edges will contain only programCall type relationship for the specified program name. Call depth specification is honored in both call directions. That is, both parents and children of the program are returned at the specified depth. Note that the nodes map may still contain File (metadata type module) artifacts that could be ignored for the purpose of programCall type depth relationships.

When you specify the fileName, a contain type list of edges will be returned for the fileName. Only files that are directly referenced by the file containing the fileName are returned. For example, if file A contains references to file B and C, and file B contains references to file D, only relationships to B and C will be returned for file A. The edges might also contain programCalltype relationship, and the nodes map might contain program type nodes, which can be ignored for the purpose of containtype relationships.

When you specify both programName and fileName, two separate independent graph objects will be returned. The callDepth parameter will be applied to the graph that is based on programName.

Sample Graph API
Sample request message:
//Retrieve graph for program with name `LGACUS01` and file `LGACUS01.CBL` in project `GenAppC`
{
  graphs(projectId: "GenAppC", programName: "LGACUS01", fileName: "LGACUS01.CBL") {
    id
    nodes
    edges {
      source
      target
      relation
    }
  }
}
Sample response message:
{
  "data": {
    "graphs": [
      {
        "id": "GenAppC",
        "nodes": {
          "program:LGACUS01": {
            "label": "LGACUS01",
            "metadata": {
              "type": "program",
              "srctype": "COBOL",
              "loc": "580",
              "locmt": "164",
              "rloc": "382"
            }
          },
          "module:DEFVAR.CPY": {
            "label": "DEFVAR.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITP%/Include/MACLIB/DEFVAR.CPY"
            }
          },
          "module:LGACUS01.CBL": {
            "label": "LGACUS01.CBL",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITPDATA%/GenAppC/source/nazare-demo-genapp/base/src/cobol/LGACUS01.CBL"
            }
          },
          "module:LGPOLICY.CPY": {
            "label": "LGPOLICY.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITPDATA%/GenAppC/source/nazare-demo-genapp/base/src/copy/LGPOLICY.CPY"
            }
          },
          "module:LGCMAREA.CPY": {
            "label": "LGCMAREA.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITPDATA%/GenAppC/source/nazare-demo-genapp/base/src/copy/LGCMAREA.CPY"
            }
          },
          "module:DFHEIBLK.CPY": {
            "label": "DFHEIBLK.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITP%/Include/MACLIB/DFHEIBLK.CPY"
            }
          },
          "module:DFHEIVAR.CPY": {
            "label": "DFHEIVAR.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITP%/Include/MACLIB/DFHEIVAR.CPY"
            }
          },
          "module:DIBSTAT.CPY": {
            "label": "DIBSTAT.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITP%/Include/MACLIB/DIBSTAT.CPY"
            }
          }
        },
        "edges": [
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:DEFVAR.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:LGPOLICY.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:LGCMAREA.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:DFHEIBLK.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:DFHEIVAR.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:DIBSTAT.CPY",
            "relation": "Contain"
          },
          {
            "source": "program:LGACUS01",
            "target": "program:LGACDB01",
            "relation": "ProgramCall"
          },
          {
            "source": "program:LGACUS01",
            "target": "program:LGSTSQ",
            "relation": "ProgramCall"
          }
        ]
      },
      {
        "id": "GenAppC",
        "nodes": {
          "program:LGACUS01": {
            "label": "LGACUS01",
            "metadata": {
              "type": "program",
              "srctype": "COBOL",
              "loc": "580",
              "locmt": "164",
              "rloc": "382"
            }
          },
          "module:LGACUS01.CBL": {
            "label": "LGACUS01.CBL",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITPDATA%/GenAppC/source/nazare-demo-genapp/base/src/cobol/LGACUS01.CBL"
            }
          },
          "module:DEFVAR.CPY": {
            "label": "DEFVAR.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITP%/Include/MACLIB/DEFVAR.CPY"
            }
          },
          "module:LGPOLICY.CPY": {
            "label": "LGPOLICY.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITPDATA%/GenAppC/source/nazare-demo-genapp/base/src/copy/LGPOLICY.CPY"
            }
          },
          "module:LGCMAREA.CPY": {
            "label": "LGCMAREA.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITPDATA%/GenAppC/source/nazare-demo-genapp/base/src/copy/LGCMAREA.CPY"
            }
          },
          "module:DFHEIBLK.CPY": {
            "label": "DFHEIBLK.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITP%/Include/MACLIB/DFHEIBLK.CPY"
            }
          },
          "module:DFHEIVAR.CPY": {
            "label": "DFHEIVAR.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITP%/Include/MACLIB/DFHEIVAR.CPY"
            }
          },
          "module:DIBSTAT.CPY": {
            "label": "DIBSTAT.CPY",
            "metadata": {
              "type": "module",
              "srctype": "COBOL",
              "sourcefile": "%ITP%/Include/MACLIB/DIBSTAT.CPY"
            }
          }
        },
        "edges": [
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:DEFVAR.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:LGPOLICY.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:LGCMAREA.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:DFHEIBLK.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:DFHEIVAR.CPY",
            "relation": "Contain"
          },
          {
            "source": "module:LGACUS01.CBL",
            "target": "module:DIBSTAT.CPY",
            "relation": "Contain"
          },
          {
            "source": "program:LGACUS01",
            "target": "program:LGACDB01",
            "relation": "ProgramCall"
          },
          {
            "source": "program:LGACUS01",
            "target": "program:LGSTSQ",
            "relation": "ProgramCall"
          }
        ]
      }
    ]
  }
}

Error handling

GraphQL queries report data errors and data authorization errors through a response body in an HTTP code 200 response. This behavior is different from many REST-based systems where the data and authorization errors might cause HTTP error response codes. GraphQL systems will produce HTTP error responses in cases of network server, endpoint access errors, and query syntax errors. Queries that result in empty responses or other recoverable back end errors, the GraphQL-based API will return HTTP 200 and either empty responses or a body with a standard GraphQL errors array content that contains the error message.

For individual query authorization errors, API will return an HTTP 200 with an errors array in the message body, for example:

{
 "errors":[
   {
    "message": "Authorization failed. Token is not authorized.",
     "locations":[
       {"line": 1, "column": 2}
     ],
     "path":[
     "graph"
     ]
   }
 ],
 "data":{
   graph": null
 }
}