# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

---

paths:

  /metalakes/{metalake}/catalogs:
    parameters:
      - $ref: "./openapi.yaml#/components/parameters/metalake"
    get:
      tags:
        - catalog
      summary: List catalogs (names)
      operationId: listCatalogs
      parameters:
        - $ref: "#/components/parameters/details"
      responses:
        "200":
          description: Returns the list of catalog objects if {details} is true, otherwise returns the list of catalog identifiers
          content:
            application/vnd.gravitino.v1+json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/CatalogListResponse"
                  - $ref: "#/components/schemas/CatalogInfoListResponse"
              examples:
                CatalogListResponse:
                  $ref: "#/components/examples/CatalogListResponse"
                CatalogInfoListResponse:
                  $ref: "#/components/examples/CatalogInfoListResponse"
        "400":
          $ref: "./openapi.yaml#/components/responses/BadRequestErrorResponse"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

    post:
      tags:
        - catalog
      summary: Create catalog
      operationId: createCatalog
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CatalogCreateRequest"
            examples:
              CatalogCreate:
                $ref: "#/components/examples/CatalogCreate"

      responses:
        "200":
          $ref: "#/components/responses/CatalogResponse"
        "409":
          description: Conflict - The target catalog already exists in the specified metalake
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                CatalogAlreadyExistsException:
                  $ref: "#/components/examples/CatalogAlreadyExistsException"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

  /metalakes/{metalake}/catalogs/testConnection:
    parameters:
      - $ref: "./openapi.yaml#/components/parameters/metalake"
    post:
      tags:
        - catalog
      summary: Test catalog connection
      operationId: testConnection
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CatalogCreateRequest"
            examples:
              CatalogCreate:
                $ref: "#/components/examples/CatalogCreate"
      responses:
        "200":
          description: Test connection completed
          content:
            application/vnd.gravitino.v1+json:
              schema:
                type: object
                required:
                  - code
                properties:
                  code:
                      type: integer
                      format: int32
                      description: Status code of the response
                  type:
                    type: string
                    description: Internal type definition of the exception
                  message:
                    type: string
                    description: The message of the exception
                  stack:
                    type: array
                    items:
                      type: string
                      description: The stack trace of the exception
              examples:
                TestConnectionSuccess:
                  value: {
                    "code": 0
                  }
                TestConnectionFailed:
                  $ref: "#/components/examples/ConnectionFailedException"
                CatalogAlreadyExists:
                  $ref: "#/components/examples/CatalogAlreadyExistsException"
                MetalakeNotFound:
                  $ref: "./metalakes.yaml#/components/examples/NoSuchMetalakeException"
        "400":
          $ref: "./openapi.yaml#/components/responses/BadRequestErrorResponse"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"



  /metalakes/{metalake}/catalogs/{catalog}:
    parameters:
      - $ref: "./openapi.yaml#/components/parameters/metalake"
      - $ref: "./openapi.yaml#/components/parameters/catalog"

    get:
      tags:
        - catalog
      summary: Get catalog
      operationId: loadCatalog
      description: Returns the specified catalog information in the specified metalake
      responses:
        "200":
          $ref: "#/components/responses/CatalogResponse"
        "404":
          description: Not Found - The specified catalog does not exist in the specified metalake
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                NoSuchMetalakeException:
                  $ref: "./metalakes.yaml#/components/examples/NoSuchMetalakeException"
                NoSuchCatalogException:
                  $ref: "#/components/examples/NoSuchCatalogException"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

    put:
      tags:
        - catalog
      summary: Update catalog
      operationId: alterCatalog
      description: Alters the specified catalog information in the specified metalake
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CatalogUpdatesRequest"
      responses:
        "200":
          $ref: "#/components/responses/CatalogResponse"
        "404":
          description: Not Found - The specified catalog does not exist in the specified metalake
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                NoSuchMetalakeException:
                  $ref: "./metalakes.yaml#/components/examples/NoSuchMetalakeException"
                NoSuchCatalogException:
                  $ref: "#/components/examples/NoSuchCatalogException"
        "409":
            description: Conflict - The target catalog already exists in the specified metalake
            content:
              application/vnd.gravitino.v1+json:
                schema:
                  $ref: "./openapi.yaml#/components/schemas/ErrorModel"
                examples:
                  CatalogAlreadyExistsException:
                    $ref: "#/components/examples/CatalogAlreadyExistsException"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"

    patch:
      tags:
        - catalog
      summary: set catalog in-use
      operationId: setCatalog
      description: Set a specific catalog in-use or not in-use
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CatalogSetRequest"
      responses:
        "200":
          $ref: "./openapi.yaml#/components/responses/BaseResponse"
        "404":
          description: Not Found - The metalake does not exist
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"
              examples:
                NoSuchMetalakeException:
                  $ref: "#/components/examples/NoSuchCatalogException"
        "500":
          description:
            Internal server error. It is possible that the server
            encountered a storage issue.
          content:
            application/vnd.gravitino.v1+json:
              schema:
                $ref: "./openapi.yaml#/components/schemas/ErrorModel"



    delete:
      tags:
        - catalog
      summary: Drop catalog
      operationId: dropCatalog
      parameters:
        - $ref: "./openapi.yaml#/components/parameters/force"
      responses:
        "200":
          $ref: "./openapi.yaml#/components/responses/DropResponse"
        "400":
          $ref: "./openapi.yaml#/components/responses/BadRequestErrorResponse"
        "5xx":
          $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"



components:
  parameters:
    details:
      name: details
      in: query
      description: Include detailed information about the catalogs
      required: false
      schema:
        type: boolean
        default: false

  schemas:

    Catalog:
      type: object
      description: A catalog
      required:
        - name
        - type
        - provider
        - audit
      properties:
        name:
          type: string
          description: The name of the catalog
        type:
          type: string
          description: The type of the catalog
          enum:
            - relational
            - fileset
            - messaging
        provider:
          type: string
          description: The provider of the catalog
          enum:
            - hive
            - lakehouse-iceberg
            - lakehouse-paimon
            - jdbc-mysql
            - jdbc-postgresql
            - jdbc-doris
            - hadoop
            - kafka
        comment:
          type: string
          description: A comment about the catalog
          nullable: true
        audit:
          $ref: "./openapi.yaml#/components/schemas/Audit"
        properties:
          type: object
          description: Configured string to string map of properties for the catalog
          default: { }
          additionalProperties:
            type: string

    CatalogListResponse:
      type: object
      properties:
        code:
          type: integer
          format: int32
          description: Status code of the response
          enum:
            - 0
        identifiers:
          type: array
          items:
            $ref: "./openapi.yaml#/components/schemas/NameIdentifier"

    CatalogInfoListResponse:
      type: object
      properties:
        code:
          type: integer
          format: int32
          description: Status code of the response
          enum:
            - 0
        catalogs:
          type: array
          description: A list of catalog objects
          items:
            $ref: "#/components/schemas/Catalog"

    CatalogCreateRequest:
      type: object
      required:
        - name
        - type
        - provider
      properties:
        name:
          type: string
          description: The name of the catalog
        type:
          type: string
          description: The type of the catalog
          enum:
            - relational
            - fileset
            - stream
        provider:
          type: string
          description: The provider of the catalog
          enum:
            - hive
            - lakehouse-iceberg
            - lakehouse-paimon
            - lakehouse-hudi
            - jdbc-mysql
            - jdbc-postgresql
            - jdbc-doris
            - jdbc-oceanbase
            - hadoop
            - kafka
        comment:
          type: string
          description: A comment for the catalog
          nullable: true
        properties:
          type: object
          description: A map of properties for the catalog
          nullable: true
          default: { }
          additionalProperties:
            type: string

    CatalogSetRequest:
      type: object
      required:
        - inUse
      properties:
        inUse:
          type: boolean
          description: The in-use status of the catalog to set
      example: {
        "inUse": true
      }

    CatalogUpdatesRequest:
      type: object
      required:
        - updates
      properties:
        updates:
          type: array
          items:
            $ref: "#/components/schemas/CatalogUpdateRequest"

    CatalogUpdateRequest:
      oneOf:
        - $ref: "#/components/schemas/RenameCatalogRequest"
        - $ref: "#/components/schemas/UpdateCatalogCommentRequest"
        - $ref: "#/components/schemas/SetCatalogPropertyRequest"
        - $ref: "#/components/schemas/RemoveCatalogPropertyRequest"
      discriminator:
        propertyName: "@type"
        mapping:
          rename: "#/components/schemas/RenameCatalogRequest"
          updateComment: "#/components/schemas/UpdateCatalogCommentRequest"
          setProperty: "#/components/schemas/SetCatalogPropertyRequest"
          removeProperty: "#/components/schemas/RemoveCatalogPropertyRequest"

    RenameCatalogRequest:
      type: object
      required:
        - "@type"
        - newName
      properties:
        "@type":
          type: string
          enum:
            - rename
        newName:
          type: string
          description: The new name of the catalog
      example: {
        "@type": "rename",
        "newName": "my_catalog_new"
      }

    UpdateCatalogCommentRequest:
      type: object
      required:
        - "@type"
        - newComment
      properties:
        "@type":
          type: string
          enum:
            - updateComment
        newComment:
          type: string
          description: The new comment of the catalog
      example: {
        "@type": "updateComment",
        "newComment": "This is my new catalog comment"
      }

    SetCatalogPropertyRequest:
      type: object
      required:
        - "@type"
        - property
        - value
      properties:
        "@type":
          type: string
          enum:
            - setProperty
        property:
          type: string
          description: The property to set
        value:
          type: string
          description: The value to set
      example: {
        "@type": "setProperty",
        "property": "key1",
        "value": "value1"
      }

    RemoveCatalogPropertyRequest:
      type: object
      required:
        - "@type"
        - property
      properties:
        "@type":
          type: string
          enum:
            - removeProperty
        property:
          type: string
          description: The property to remove
      example: {
        "@type": "removeProperty",
        "property": "key2"
      }


  responses:

    CatalogResponse:
      description: Returns included catalog object
      content:
        application/vnd.gravitino.v1+json:
          schema:
            type: object
            properties:
              code:
                type: integer
                format: int32
                description: Status code of the response
                enum:
                  - 0
              catalog:
                $ref: "#/components/schemas/Catalog"
          examples:
            CatalogResponse:
              $ref: "#/components/examples/CatalogResponse"


  examples:
    CatalogListResponse:
      value: {
        "code": 0,
        "identifiers": [
          {
            "namespace": [
              "my_metalake"
            ],
            "name": "my_hive_catalog"
          }
        ]
      }

    CatalogInfoListResponse:
      value: {
        "code": 0,
        "catalogs": [
          {
            "name": "my_hive_catalog",
            "type": "relational",
            "provider": "hive",
            "comment": "This is my hive catalog",
            "properties": {
              "key1": "value1",
              "gravitino.bypass.hive.metastore.client.capability.check": "false",
              "metastore.uris": "thrift://127.0.0.1:9083"
            },
            "audit": {
              "creator": "gravitino",
              "createTime": "2023-12-08T03:41:25.595Z"
            }
          },
          {
            "name": "my_hadoop_catalog",
            "type": "fileset",
            "provider": "hadoop",
            "comment": "This is my hadoop catalog",
            "properties": {
              "key2": "value2"
            },
            "audit": {
              "creator": "gravitino",
              "createTime": "2023-12-08T06:41:25.595Z"
            }
          }
        ]
      }

    CatalogCreate:
      value: {
        "name": "my_hive_catalog",
        "type": "relational",
        "provider": "hive",
        "comment": "This is my hive catalog",
        "properties": {
          "metastore.uris": "thrift://127.0.0.1:9083",
          "key1": "value1"
        }
      }

    CatalogResponse:
      value: {
        "code": 0,
        "catalog": {
          "name": "my_hive_catalog",
          "type": "relational",
          "provider": "hive",
          "comment": "This is my hive catalog",
          "properties": {
            "key1": "value1",
            "gravitino.bypass.hive.metastore.client.capability.check": "false",
            "metastore.uris": "thrift://127.0.0.1:9083"
          },
          "audit": {
            "creator": "gravitino",
            "createTime": "2023-12-08T03:41:25.595Z"
          }
        }
      }

    CatalogAlreadyExistsException:
      value: {
        "code": 1004,
        "type": "CatalogAlreadyExistsException",
        "message": "Failed to operate catalog(s) [my_catalog] operation [CREATE], reason [CatalogAlreadyExistsException]",
        "stack": [
          "org.apache.gravitino.exceptions.CatalogAlreadyExistsException: Catalog my_catalog already exists",
          "..."
        ]
      }

    ConnectionFailedException:
      value: {
        "code": 1007,
        "type": "ConnectionFailedException",
        "message": "Failed to run getAllDatabases in Hive Metastore: Failed to connect to Hive Metastore",
        "stack": [
          "org.apache.gravitino.exceptions.ConnectionFailedException: Failed to run getAllDatabases in Hive Metastore: Failed to connect to Hive Metastore",
          "..."
        ]
      }

    NoSuchCatalogException:
      value: {
        "code": 1003,
        "type": "NoSuchCatalogException",
        "message": "Failed to operate catalog(s) [test] operation [LOAD] under metalake [my_test_metalake], reason [NoSuchCatalogException]",
        "stack": [
          "org.apache.gravitino.exceptions.NoSuchCatalogException: Catalog my_test_metalake.test does not exist",
          "..."
        ]
      }
