kyuubi/dev
Fu Chen a5ef94accc
[KYUUBI #1354] Expose OpenAPI Specifications
<!--
Thanks for sending a pull request!

Here are some tips for you:
  1. If this is your first time, please read our contributor guidelines: https://kyuubi.readthedocs.io/en/latest/community/contributions.html
  2. If the PR is related to an issue in https://github.com/apache/incubator-kyuubi/issues, add '[KYUUBI #XXXX]' in your PR title, e.g., '[KYUUBI #XXXX] Your PR title ...'.
  3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., '[WIP][KYUUBI #XXXX] Your PR title ...'.
-->

### _Why are the changes needed?_
<!--
Please clarify why the changes are needed. For instance,
  1. If you add a feature, you can talk about the use case of it.
  2. If you fix a bug, you can clarify why it is a bug.
-->

1. add a new endpoint `/openapi.json` which describes the entire restful API of Kyuubi.
2. add a static web page `/api/v1/swagger-ui`. see [swagger-ui](https://github.com/swagger-api/swagger-ui)

```
curl http://localhost:10099/openapi.json | jq .
```

```json
{
  "openapi": "3.0.1",
  "info": {
    "title": "Apache Kyuubi RESTful Api Documentation",
    "description": "Apache Kyuubi RESTful Api Documentation",
    "contact": {
      "name": "Apache Kyuubi Community",
      "url": "https://kyuubi.apache.org/issue_tracking.html",
      "email": "devkyuubi.apache.org"
    },
    "license": {
      "name": "Apache 2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
    },
    "version": "1.4.0"
  },
  "tags": [
    {
      "name": "Session"
    }
  ],
  "paths": {
    "/api/v1/ping": {
      "get": {
        "operationId": "ping",
        "responses": {
          "default": {
            "description": "default response",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sessions/{sessionHandle}": {
      "get": {
        "tags": [
          "Session"
        ],
        "operationId": "sessionInfo",
        "parameters": [
          {
            "name": "sessionHandle",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "get a session via session handle identifier",
            "content": {
              "application/json": {}
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Session"
        ],
        "operationId": "closeSession",
        "parameters": [
          {
            "name": "sessionHandle",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "close a Session",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api/v1/sessions/execPool/statistic": {
      "get": {
        "tags": [
          "Session"
        ],
        "operationId": "execPoolStatistic",
        "responses": {
          "200": {
            "description": "get some statistic info of sessions",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api/v1/sessions/{sessionHandle}/info/{infoType}": {
      "get": {
        "tags": [
          "Session"
        ],
        "operationId": "getInfo",
        "parameters": [
          {
            "name": "sessionHandle",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "infoType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "get a information detail via session handle identifier and a specific information type",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api/v1/sessions": {
      "get": {
        "tags": [
          "Session"
        ],
        "operationId": "sessionInfoList",
        "responses": {
          "200": {
            "description": "get all the session list hosted in SessionManager",
            "content": {
              "application/json": {}
            }
          }
        }
      },
      "post": {
        "tags": [
          "Session"
        ],
        "operationId": "openSession",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionOpenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Open(create) a Session",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api/v1/sessions/count": {
      "get": {
        "tags": [
          "Session"
        ],
        "operationId": "sessionCount",
        "responses": {
          "200": {
            "description": "get open session count",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api/v1/exception": {
      "get": {
        "operationId": "test",
        "responses": {
          "default": {
            "description": "default response",
            "content": {
              "text/plain": {}
            }
          }
        }
      }
    },
    "/application.wadl/{path}": {
      "get": {
        "operationId": "getExternalGrammar",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "default": {
            "description": "default response",
            "content": {
              "application/xml": {}
            }
          }
        }
      }
    },
    "/application.wadl": {
      "get": {
        "operationId": "getWadl",
        "responses": {
          "default": {
            "description": "default response",
            "content": {
              "application/vnd.sun.wadl+xml": {},
              "application/xml": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ExecPoolStatistic": {
        "required": [
          "execPoolSize"
        ],
        "type": "object",
        "properties": {
          "execPoolSize": {
            "type": "integer",
            "format": "int32"
          },
          "execPoolActiveCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "InfoDetail": {
        "required": [
          "infoType"
        ],
        "type": "object",
        "properties": {
          "infoType": {
            "type": "string"
          },
          "infoValue": {
            "type": "string"
          }
        }
      },
      "HandleIdentifier": {
        "required": [
          "publicId"
        ],
        "type": "object",
        "properties": {
          "publicId": {
            "type": "string",
            "format": "uuid"
          },
          "secretId": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "SessionHandle": {
        "required": [
          "identifier",
          "protocol"
        ],
        "type": "object",
        "properties": {
          "identifier": {
            "$ref": "#/components/schemas/HandleIdentifier"
          },
          "protocol": {
            "type": "string",
            "enum": [
              "HIVE_CLI_SERVICE_PROTOCOL_V1",
              "HIVE_CLI_SERVICE_PROTOCOL_V2",
              "HIVE_CLI_SERVICE_PROTOCOL_V3",
              "HIVE_CLI_SERVICE_PROTOCOL_V4",
              "HIVE_CLI_SERVICE_PROTOCOL_V5",
              "HIVE_CLI_SERVICE_PROTOCOL_V6",
              "HIVE_CLI_SERVICE_PROTOCOL_V7",
              "HIVE_CLI_SERVICE_PROTOCOL_V8",
              "HIVE_CLI_SERVICE_PROTOCOL_V9",
              "HIVE_CLI_SERVICE_PROTOCOL_V10"
            ]
          }
        }
      },
      "MapStringString": {
        "type": "object",
        "additionalProperties": {
          "type": "string"
        }
      },
      "SessionOpenRequest": {
        "required": [
          "configs",
          "protocolVersion",
          "user"
        ],
        "type": "object",
        "properties": {
          "protocolVersion": {
            "type": "integer",
            "format": "int32"
          },
          "user": {
            "type": "string"
          },
          "password": {
            "type": "string"
          },
          "ipAddr": {
            "type": "string"
          },
          "configs": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      },
      "SessionOpenCount": {
        "required": [
          "openSessionCount"
        ],
        "type": "object",
        "properties": {
          "openSessionCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "SessionDetail": {
        "required": [
          "configs",
          "createTime",
          "user"
        ],
        "type": "object",
        "properties": {
          "user": {
            "type": "string"
          },
          "ipAddr": {
            "type": "string"
          },
          "createTime": {
            "type": "integer",
            "format": "int64"
          },
          "sessionHandle": {
            "$ref": "#/components/schemas/SessionHandle"
          },
          "lastAccessTime": {
            "type": "integer",
            "format": "int64"
          },
          "lastIdleTime": {
            "type": "integer",
            "format": "int64"
          },
          "noOperationTime": {
            "type": "integer",
            "format": "int64"
          },
          "configs": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      },
      "SeqSessionOverview": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/SessionOverview"
        }
      },
      "SessionList": {
        "required": [
          "sessionList"
        ],
        "type": "object",
        "properties": {
          "sessionList": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionOverview"
            }
          }
        }
      },
      "SessionOverview": {
        "required": [
          "createTime",
          "user"
        ],
        "type": "object",
        "properties": {
          "user": {
            "type": "string"
          },
          "ipAddr": {
            "type": "string"
          },
          "createTime": {
            "type": "integer",
            "format": "int64"
          },
          "sessionHandle": {
            "$ref": "#/components/schemas/SessionHandle"
          }
        }
      }
    }
  }
}
```
http://localhost:10099/api/v1/swagger-ui

> Note that this request will redirect to http://localhost:10099/swagger-ui-redirected/index.html?url=http://localhost:10099/openapi.json

![截屏2021-11-09 上午10 43 49](https://user-images.githubusercontent.com/8537877/141281596-e47f5552-75b9-47d1-8a36-67337cb6eb3a.png)

### _How was this patch tested?_
- [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible

- [ ] Add screenshots for manual tests if appropriate

- [ ] [Run test](https://kyuubi.readthedocs.io/en/latest/develop_tools/testing.html#running-tests) locally before make a pull request

Closes #1363 from cfmcgrady/kyuubi-1354.

Closes #1354

8895d7fc [Fu Chen] typo
8f5dea9a [Fu Chen] addressed comment
4d325a45 [Fu Chen] constant MediaType.APPLICATION_JSON
0d96951e [Fu Chen] RESTful Api -> REST API
be7d02dc [Fu Chen] add LIABILITY-edl.txt
4ff1053e [Fu Chen] update dev/dependencyList
b126f7e6 [Fu Chen] swagger-ui 4.1.0
a35c2f29 [Fu Chen] addressed comment
7bde0534 [Fu Chen] update LICENSE-binary
38397dc2 [Fu Chen] align jackson version
923f3e7e [Fu Chen] update dev/dependencyList
7d5338c8 [Fu Chen] remove kyuubi-server static files
5cb66b33 [Fu Chen] update dev/dependencyList
e8a8c421 [Fu Chen] fix style
5b13f69c [Fu Chen] add license and remove .map files
c04d7a75 [Fu Chen] rebase master
2388dae8 [Fu Chen] fix style
8dcbd3db [Fu Chen] add static resource
4b0d6d0a [Fu Chen] expose OpenAPI

Authored-by: Fu Chen <cfmcgrady@gmail.com>
Signed-off-by: ulysses-you <ulyssesyou@apache.org>
2021-11-17 12:17:58 +08:00
..
kyuubi-codecov [KYUUBI #1257] [BUILD] Reduce unnecessary maven profile 2021-10-22 14:51:42 +08:00
kyuubi-extension-spark-3-1 [KYUUBI #1257] [BUILD] Reduce unnecessary maven profile 2021-10-22 14:51:42 +08:00
kyuubi-extension-spark-3-2 [KYUUBI #1257] [BUILD] Reduce unnecessary maven profile 2021-10-22 14:51:42 +08:00
kyuubi-extension-spark-common [KYUUBI #1366] Add a todo in zorder that we can do rebalance partitions before local sort of zorder 2021-11-12 17:36:36 +08:00
kyuubi-tpcds [KYUUBI #1238] [BUILD] Add back Scala stuff to root POM 2021-10-15 17:49:48 +08:00
checkout_pr.sh [KYUUBI #1233] Add checkout_pr.sh script 2021-10-14 13:53:09 +08:00
dependencyList [KYUUBI #1354] Expose OpenAPI Specifications 2021-11-17 12:17:58 +08:00
merge_kyuubi_pr.py [KYUUBI #809] [INFRA] Support reopened PR in pr merge tool 2021-07-15 18:05:07 +08:00