Introduction

There are a large number of REST based applications, which are not OpenAPI complaint. On the other hand, the Serverless Workflows specification define the constructs to interact with ONLY OpenAPI compliant end-point. To bridge this gap, Workflow Hub allows users to define OpenAPI schemas for non-OpenAPI Rest Endpoints and store them in Workflow Hub. With the schema defined, the workflow can invoke the function using the schema available inside Workflow-Hub. The Workflow-Hub treats the End-point as a OpenAPI end-point and the workflow execution proceeds as if the end-point was OpenAPI compliant.

This document explains how non-OpenAPI REST Endpoints can be supported in Workflow Hub.

Prerequisites

  • The end-point should be REST-API complaint.
  • The Content-Type is either application/json or application/x-www-form-urlencoded.

Approach

  • User will develop a OpenAPI schema that's aligned with the request/response of the REST API.
  • Using the Schema APIs (or the UI), the user will upload the OpenAPI schema to the DB.
  • In the workflow, the user will define the functions to fetch the OpenAPI schema from the db, using the keyword "db://" instead of traditional "https://" or "http://".
  • The workflow executions happens as before.

Uploading Openapi Schema to Workflow Hub

Click on Schemas

Click on Add Schema

Enter Path, Description and the Schema

  • Path
  • Schema
  • Description
  • Type
Parameter Comment
Path Indicates a reference to fetch the schema during workflow-execution. It must be unique across schemas that are inserted by the same tenant.
Schema The Openapi Schema that corresponds to the Request/Response of the REST API server. This needs to be OpenAPI 3 compliant
Description Description of the Schema
Type Type of the schema. Can be one of Open API, Swagger, AsyncAPI, JSON
Note: Server Info

OpenAPI compliant specification requires a server section. The server section must describe the server that's actually responsible for responding to the requests. The server can be templated.

Server Definition in Openapi
servers:
- url: https://{gitlabWebServer}:{gitlabPort}
  variables:
    gitlabWebServer:
      default: localhost
      description: Host where Gitlab Web is running
    gitlabPort:
      default: '443'
      description: The port on which Gitlab server is listening to

Using the Schema in the Workflow

The schema is used in the workflow, by invoking function calls on the resources exposed by the schema. All function calls that refer to the DB schema, start with "db://", indicating to the Workflow Hub that the schema for this request is available locally on the Workflow Hub. Subsequently, the workflow execution engine parses the schema obtained from the DB and constructs header/body/query accordingly.

As a example, consider the following function call:

Sample Function Code
functions:
  - name: TriggerGitlabPipeline
    operation: db://gitlabserver/apis/api-gitlab/swagger/1.0/gitlabAPI.json#triggerPipeline
    metadata:
      tlsVerify: false

In this function call, the function is referring to the "path" of the schema db://gitlabserver/apis/api-gitlab/swagger/1.0/gitlabAPI.json . This indicates to WorkflowHub that the schema is available in Workflow Hub. The #triggerPipeline indicates the operationId of the operation that is needed to be invoked.

The schema description for the operation is described below:

Trigger Gitlab Pipeline OpenAPI
---
"/api/v4/projects/{project_id}/trigger/pipeline":
  post:
    summary: Trigger the Pipeline
    operationId: triggerPipeline
    parameters:
    - name: project_id
      in: path
      description: The name of the project for which CI/CD pipeline is getting triggered
      required: true
      schema:
        type: string
        default: None
      example: testing_project
    - name: Content-Type
      in: header
      description: application/json
      required: true
      schema:
        type: string
      example: application/json
    requestBody:
      content:
        application/json:
          schema:
            type: object
            properties:
              ref:
                type: string
                description: The name of the branch on which the pipeline is triggered
                example: main, private_branch, etc.
              token:
                type: string
                description: Value of Trigger Token
                example: 6d056f63e50fe6f8c5f8f4aa10edb7
              variables:
                type: object
                additionalProperties:
                  type: string
                description: The variables to be overridden
                example: '{ "WC": "wc-1", "NODEPOOL": "np1", "CNFID": "12345678",
                  "KUBECONFIG": "cluster kubeconfig", "MC": "mgmt-cluster-20" }'
      required: true
    responses:
      '200':
        description: Status 200
        content:
          application/json:
            example:
              id: 46
              iid: 11
              project_id: 1
              status: success
              ref: main
              sha: a91957a858320c0e17f3a0eca7cfacbff50ea29a
              before_sha: a91957a858320c0e17f3a0eca7cfacbff50ea29a
              tag: false
              user:
                name: Administrator
                username: root
                id: 1
                state: active
                avatar_url: http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon
                web_url: http://localhost:3000/root
              created_at: '2016-08-11T11:28:34.085Z'
              updated_at: '2016-08-11T11:32:35.169Z'
              finished_at: '2016-08-11T11:32:35.145Z'
              duration: 123.65
              queued_duration: 0.01
              coverage: '30.0'
              web_url: https://example.com/foo/bar/pipelines/46
    x-codegen-request-body-name: body

In accordance with the function definition, the input to the REST API requires the following parameters:

  • gitlabWebServer (Server is templated)
  • gitlabPort (server is templated)
  • ref (branch on which pipeline needs to be triggered
  • token (for auth/authz)
  • variables ( the variables used in the pipeline)

The user would invoke this function, like any other Workflow function as follows:

Sample Function Code
- name: Trigger_Gitlab_Pipeline
  type: operation
  actions:
    - functionRef:
        refName: TriggerGitlabPipeline
        arguments:
          gitlabWebServer: "${ .ci_url }"
          project_id: "${ .project_id }"
          token: "${ .trigger_token }"
          ref: "${ .branch }"
          variables: '${ { "JENKINS_INFO": .jenkins_info }}'
          Content-Type: application/json
      actionDataFilter:
        results: '${  { "pipelineId": ."id" | tostring,  "pcounters": { "wait": 0, "run": 0 } }}'
  transition: Get_Pipeline_Status

In the above example, the user invokes TriggerGitlabPipeline function and passes the arguments required by the function. These arguments (and their locations in the request would be defined in the OpenAPI Schema).