This is an automated email from the ASF dual-hosted git repository.
vinish pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-xtable.git
The following commit(s) were added to refs/heads/main by this push:
new d60e0469 Add open api REST spec for XTable Service (#705)
d60e0469 is described below
commit d60e0469a2e85a34fe6803df21e106f111a8bb19
Author: Rahil C <[email protected]>
AuthorDate: Wed Apr 30 21:39:58 2025 -0700
Add open api REST spec for XTable Service (#705)
---
.gitignore | 3 +
spec/Makefile | 72 ++++++++++++
spec/README.md | 53 +++++++++
spec/requirements.txt | 18 +++
spec/rest-service-open-api.yaml | 240 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 386 insertions(+)
diff --git a/.gitignore b/.gitignore
index 6fdaa623..5a59990d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,6 @@ demo/jars/*
demo/notebook/.ipynb_checkpoints/*
my_config.yaml
my_config_catalog.yaml
+
+# REST generated models
+spec/generated
\ No newline at end of file
diff --git a/spec/Makefile b/spec/Makefile
new file mode 100644
index 00000000..b7392b3f
--- /dev/null
+++ b/spec/Makefile
@@ -0,0 +1,72 @@
+# 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.
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements…
+# (your license header…)
+
+PYTHON := python3
+VENV_DIR := .venv
+PIP := $(VENV_DIR)/bin/pip
+VALIDATOR := $(VENV_DIR)/bin/openapi-spec-validator
+SPEC := rest-service-open-api.yaml
+
+# Configuration for model generation
+GEN_DIR := generated
+MODEL_PKG := org.apache.xtable.service.models
+
+.PHONY: all venv install lint clean clean-models
+
+all: lint
+
+# Create venv if it doesn't exist
+venv:
+ @echo "→ creating virtualenv in $(VENV_DIR)…"
+ $(PYTHON) -m venv $(VENV_DIR)
+ @echo "→ upgrading pip…"
+ $(PIP) install --upgrade pip
+
+# Install requirements into venv
+install: venv
+ @echo "→ installing validator…"
+ $(PIP) install -r requirements.txt
+
+# Validate your OpenAPI spec
+lint: install
+ @echo "→ linting $(SPEC)…"
+ $(VALIDATOR) --errors all $(SPEC)
+
+# Remove the virtualenv
+clean:
+ @echo "→ removing $(VENV_DIR)…"
+ rm -rf $(VENV_DIR)
+
+# Generate Java model classes from OpenAPI spec
+generate-models:
+ @echo "→ generating Java model classes from $(SPEC)…"
+ openapi-generator generate \
+ -i $(SPEC) \
+ -g java \
+ -o $(GEN_DIR) \
+ --model-package $(MODEL_PKG) \
+ --global-property models,modelTests=false,modelDocs=false
+ @echo "→ models generated in $(GEN_DIR)/src/main/java/$(subst
.,/,$(MODEL_PKG))"
+
+# Remove all generated model classes
+clean-models:
+ @echo "→ removing generated models in $(GEN_DIR)…"
+ rm -rf $(GEN_DIR)
\ No newline at end of file
diff --git a/spec/README.md b/spec/README.md
new file mode 100644
index 00000000..41fe212c
--- /dev/null
+++ b/spec/README.md
@@ -0,0 +1,53 @@
+<!--
+ - 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.
+ -->
+
+# Open API spec
+
+The `rest-service-open-api.yaml` defines the api contract for running table
format conversion using XTable's REST service.
+This spec is still under active development and is subject to changes.
+
+## Lint
+
+To make sure that the open-api definition is valid, you can run the `lint`
command:
+
+This will first run `make install`, which in turn will create the venv (if
needed) and install openapi-spec-validator
+```sh
+make lint
+```
+
+if you want to wipe out the venv and start fresh run make clean
+```sh
+make clean
+```
+
+## Generate
+
+Note: You’ll need the OpenAPI Generator CLI installed and on your `PATH`. You
can install it using Homebrew:
+```sh
+brew install openapi-generator
+```
+Then to generate the java models from the open-api spec, you can run the
`generate-models` command.
+
+```sh
+make generate-models
+```
+If you would to remove the generated models, you can run the `clean-models`
command:
+```sh
+make clean-models
+```
\ No newline at end of file
diff --git a/spec/requirements.txt b/spec/requirements.txt
new file mode 100644
index 00000000..2d08b021
--- /dev/null
+++ b/spec/requirements.txt
@@ -0,0 +1,18 @@
+# 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.
+
+openapi-spec-validator==0.7.1
\ No newline at end of file
diff --git a/spec/rest-service-open-api.yaml b/spec/rest-service-open-api.yaml
new file mode 100644
index 00000000..8314b291
--- /dev/null
+++ b/spec/rest-service-open-api.yaml
@@ -0,0 +1,240 @@
+#
+# 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.
+#
+openapi: 3.0.3
+info:
+ title: XTable REST Service API
+ license:
+ name: Apache 2.0
+ url: https://www.apache.org/licenses/LICENSE-2.0.html
+ version: 0.0.1
+ description: |
+ A REST API for initiating metadata conversion using Apache XTable. Note
this spec is still under active development and is subject to changes.
+
+servers:
+ - url: "{scheme}://{host}/{prefix}"
+ description: Server URL when the port can be inferred from the scheme
+ variables:
+ scheme:
+ description: The scheme of the URI, either http or https.
+ default: https
+ host:
+ description: The host address for the specified server
+ default: localhost
+ prefix:
+ description: Optional prefix to be appended to all routes
+ default: ""
+ - url: "{scheme}://{host}:{port}/{prefix}"
+ description: Generic base server URL, with all parts configurable
+ variables:
+ scheme:
+ description: The scheme of the URI, either http or https.
+ default: https
+ host:
+ description: The host address for the specified server
+ default: localhost
+ port:
+ description: The port used when addressing the host
+ default: "8080"
+ prefix:
+ description: Optional prefix to be appended to all routes
+ default: ""
+
+paths:
+ /v1/conversion/table:
+ post:
+ tags:
+ - XTable Service API
+ summary: Initiate XTable's runSync process to convert a source table
format to the requested target table formats.
+ description: |
+ Reads the source table metadata from storage, converts it to the
requested
+ target formats.
+ operationId: convertTable
+ parameters:
+ - in: header
+ name: Prefer
+ description: Use 'respond-async' to request asynchronous processing.
+ required: false
+ schema:
+ type: string
+ enum:
+ - respond-async
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ConvertTableRequest'
+ responses:
+ '200':
+ $ref: '#/components/responses/ConvertTableResponse'
+ '202':
+ $ref: '#/components/responses/SubmittedConversionResponse'
+ '403':
+ $ref: '#/components/responses/ForbiddenResponse'
+ '503':
+ $ref: '#/components/responses/ServiceUnavailableResponse'
+ default:
+ $ref: '#/components/responses/ErrorResponse'
+
+ /v1/conversion/table/{conversion-id}:
+ get:
+ tags:
+ - XTable Service API
+ summary: Polls on a conversion-id to see if converting a table has
finished.
+ operationId: getConversionStatus
+ parameters:
+ - in: path
+ name: conversion-id
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ $ref: '#/components/responses/ConvertTableResponse'
+ '202':
+ description: Still processing; conversion has not yet finished.
+ '403':
+ $ref: '#/components/responses/ForbiddenResponse'
+ '503':
+ $ref: '#/components/responses/ServiceUnavailableResponse'
+ default:
+ $ref: '#/components/responses/ErrorResponse'
+
+components:
+ schemas:
+ ConvertTableRequest:
+ type: object
+ required:
+ - source-format
+ - source-table-name
+ - source-table-path
+ - target-formats
+ properties:
+ source-format:
+ type: string
+ description: Name of the source table format (e.g., "ICEBERG",
"HUDI", "DELTA")
+ source-table-name:
+ type: string
+ description: Name of the source table
+ source-table-path:
+ type: string
+ description: Path to the source table's metadata
+ target-formats:
+ type: array
+ items:
+ type: string
+ description: List of desired output table formats (e.g., "ICEBERG",
"HUDI", "DELTA")
+ configurations:
+ type: object
+ description: Additional configuration key/value pairs (e.g., storage
credentials or other service configs)
+ additionalProperties:
+ type: string
+
+ TargetTable:
+ type: object
+ required:
+ - target-format
+ - target-metadata-path
+ properties:
+ target-format:
+ type: string
+ description: Name of the target format (e.g., "ICEBERG", "HUDI",
"DELTA")
+ target-metadata-path:
+ type: string
+ description: Path where the converted metadata was written
+ target-schema:
+ type: string
+ description: Schema definition of the converted table
+
+ ConvertTableResponse:
+ type: object
+ required:
+ - conversions
+ properties:
+ conversions:
+ type: array
+ description: A list of converted tables, one per requested format
+ items:
+ $ref: '#/components/schemas/TargetTable'
+
+ SubmittedConversionResponse:
+ type: object
+ properties:
+ conversion-id:
+ type: string
+ description: ID to use when polling for the final result
+
+ ErrorModel:
+ type: object
+ description: JSON error payload returned in a response with further
details on the error
+ required:
+ - message
+ - type
+ - code
+ properties:
+ message:
+ type: string
+ description: Human-readable error message
+ type:
+ type: string
+ description: Internal type definition of the error
+ code:
+ type: integer
+ minimum: 400
+ maximum: 600
+ description: HTTP response code
+ stack:
+ type: array
+ description: Optional stack trace elements for debugging
+ items:
+ type: string
+
+ responses:
+ ConvertTableResponse:
+ description: Successful conversion result
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ConvertTableResponse'
+
+ SubmittedConversionResponse:
+ description: Request accepted for asynchronous processing
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SubmittedConversionResponse'
+
+ ForbiddenResponse:
+ description: Caller does not have permission to perform this operation
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorModel'
+
+ ServiceUnavailableResponse:
+ description: Conversion service is temporarily unavailable
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorModel'
+
+ ErrorResponse:
+ description: Unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorModel'
\ No newline at end of file