diff --git a/openapi-linter b/openapi-linter
new file mode 100755
index 0000000..c4b88e3
--- /dev/null
+++ b/openapi-linter
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if [[ "$1" == "-it" ]]; then
+ docker run -it --rm -v $PWD:/work:ro dshanley/vacuum /bin/bash
+else
+ docker run --rm -v $PWD:/work:ro dshanley/vacuum lint --no-clip -d openapi.yaml
+fi
+
diff --git a/openapi-example.yaml b/openapi.yaml
similarity index 53%
rename from openapi-example.yaml
rename to openapi.yaml
index 211a8c8..cef1277 100644
--- a/openapi-example.yaml
+++ b/openapi.yaml
@@ -5,15 +5,29 @@ info:
description: This is an example of using VOSI-1.2 components.
servers:
- url: /example
+
+tags:
+ - name: VOSI Capabilities
+ - name: VOSI Table Metadata
+ - name: VOSI Table Operations
+
paths:
# notes: this is how another service like TAP would include VOSI endpoints using
# a local copy; the commented out $ref to a standard location would also work
/tables:
- $ref: ./vosi-tableset.yaml
+ $ref: ./openapi/vosi/vosi-tableset.yaml
#$ref: https://ivoa.net/std/VOSI/vosi-tableset.yaml
/tables/{name}:
- $ref: ./vosi-table.yaml
+ $ref: ./openapi/vosi/vosi-table.yaml
#$ref: https://ivoa.net/std/VOSI/vosi-table.yaml
+
/capabilities:
- $ref: ./paths/vosi-capabilities.yaml
+ $ref: ./openapi/vosi/vosi-capabilities.yaml
#$ref: https://ivoa.net/std/VOSI/vosi-capabilities.yaml
+
+ /table-ops:
+ $ref: ./openapi/vosi/vosi-table-ops.yaml
+ /table-ops/{jobID}:
+ $ref: ./openapi/vosi/vosi-table-ops-job.yaml
+ /table-ops/{jobID}/phase:
+ $ref: ./openapi/vosi/vosi-table-ops-job-phase.yaml
diff --git a/openapi/uws/uws-after-param.yaml b/openapi/uws/uws-after-param.yaml
new file mode 100644
index 0000000..c5afec8
--- /dev/null
+++ b/openapi/uws/uws-after-param.yaml
@@ -0,0 +1,8 @@
+name: AFTER
+in: query
+description: list jobs with creationTime after the specified value
+required: false
+schema:
+ type: string
+ format: date-time
+ example: "2017-07-21T17:32:28Z"
diff --git a/openapi/uws/uws-jobid-param.yaml b/openapi/uws/uws-jobid-param.yaml
new file mode 100644
index 0000000..2c03a07
--- /dev/null
+++ b/openapi/uws/uws-jobid-param.yaml
@@ -0,0 +1,7 @@
+name: jobID
+in: path
+description: unique job identifier generated by the server
+required: true
+schema:
+ type: string
+ example: a1b2c3
diff --git a/openapi/uws/uws-last-param.yaml b/openapi/uws/uws-last-param.yaml
new file mode 100644
index 0000000..93a53b7
--- /dev/null
+++ b/openapi/uws/uws-last-param.yaml
@@ -0,0 +1,11 @@
+name: LAST
+in: query
+description: |
+ limit the number of jobs listed to the specified value; use of LAST
+ also causes the server to return jobs in order of creationTime (descending)
+ with the most recent jobs first
+required: false
+schema:
+ type: integer
+ minimum: 0
+ example: 10
diff --git a/openapi/uws/uws-phase-change-param.yaml b/openapi/uws/uws-phase-change-param.yaml
new file mode 100644
index 0000000..7a0f156
--- /dev/null
+++ b/openapi/uws/uws-phase-change-param.yaml
@@ -0,0 +1,8 @@
+name: PHASE
+in: query
+description: attempt to change the phase
+required: true
+schema:
+ type: string
+ enum: [ABORT, RUN]
+ example: RUN
diff --git a/openapi/uws/uws-phase-param.yaml b/openapi/uws/uws-phase-param.yaml
new file mode 100644
index 0000000..610991b
--- /dev/null
+++ b/openapi/uws/uws-phase-param.yaml
@@ -0,0 +1,7 @@
+name: PHASE
+in: query
+description: list jobs in this execution phase
+required: false
+schema:
+ type: string
+ example: "EXECUTING"
diff --git a/openapi/uws/uws-responses.yaml b/openapi/uws/uws-responses.yaml
new file mode 100644
index 0000000..426a6e7
--- /dev/null
+++ b/openapi/uws/uws-responses.yaml
@@ -0,0 +1,61 @@
+# UWS create job response
+created:
+ description: standard UWS 1.1 redirect to the created job URL
+ headers:
+ location:
+ schema:
+ type: string
+ format: uri
+invalid-phase-change:
+ description: the requested phase change is invalid
+ content:
+ text/plain:
+ schema:
+ type: string
+job-listing:
+ description: list of jobs owned by the caller
+ content:
+ text/xml:
+ schema:
+ type: string
+ xml:
+ name: jobs
+ prefix: uws
+ namespace: http://www.ivoa.net/xml/UWS/v1.0
+ example: |
+
+
+ PENDING
+ TEST
+ somebody
+ 2024-07-16T16:38:33.090Z
+
+ ...
+
+
+job:
+ description: a single UWS Job
+ content:
+ text/xml:
+ schema:
+ type: string
+ xml:
+ name: job
+ prefix: uws
+ namespace: http://www.ivoa.net/xml/UWS/v1.0
+ example: |
+
+ loqqxg8jlah0r8wp
+ somebody
+ PENDING
+ 2024-07-17T16:38:33.089Z
+ 2024-07-16T16:38:33.090Z
+
+
+ 28800
+ 2024-07-23T16:38:33.089Z
+
+
+
+
+
diff --git a/openapi/uws/uws-wait-param.yaml b/openapi/uws/uws-wait-param.yaml
new file mode 100644
index 0000000..31fadab
--- /dev/null
+++ b/openapi/uws/uws-wait-param.yaml
@@ -0,0 +1,8 @@
+name: WAIT
+in: query
+description: wait for the specified time in seconds or until the phase changes
+required: false
+schema:
+ type: integer
+ example: 60
+
diff --git a/openapi/vosi/vosi-capabilities.yaml b/openapi/vosi/vosi-capabilities.yaml
index b60a382..8abd9bd 100644
--- a/openapi/vosi/vosi-capabilities.yaml
+++ b/openapi/vosi/vosi-capabilities.yaml
@@ -37,13 +37,13 @@ components:
content:
text/xml:
schema:
- type: object
+ type: string
xml:
name: capabilities
prefix: vosi
namespace: http://www.ivoa.net/xml/VOSICapabilities/v1.0
- example: |
-
@@ -53,4 +53,4 @@ components:
...
-
+
diff --git a/openapi/vosi/vosi-table-ops-job-phase.yaml b/openapi/vosi/vosi-table-ops-job-phase.yaml
new file mode 100644
index 0000000..5c382f9
--- /dev/null
+++ b/openapi/vosi/vosi-table-ops-job-phase.yaml
@@ -0,0 +1,38 @@
+get:
+ operationId: vosi-table-ops-job-phase-get
+ tags:
+ - VOSI Table Operations
+ summary: get a UWS job phase
+ description: job phase resource
+ parameters:
+ - $ref: ../uws/uws-jobid-param.yaml
+ responses:
+ '200':
+ description: the current phase
+ content:
+ text/plain:
+ schema:
+ type: string
+ example: "PENDING"
+
+post:
+ operationId: vosi-table-ops-job-phase-update
+ tags:
+ - VOSI Table Operations
+ summary: change a UWS job phase
+ description: update job
+ parameters:
+ - $ref: ../uws/uws-jobid-param.yaml
+ - $ref: ../uws/uws-phase-change-param.yaml
+ responses:
+ '200':
+ description: phase change successful
+ '400':
+ $ref: ../uws/uws-responses.yaml#/invalid-phase-change
+ '401':
+ $ref: ../vosi/vosi-std-responses.yaml#/not-authenticated
+ '403':
+ $ref: ../vosi/vosi-std-responses.yaml#/permission-denied
+ '404':
+ $ref: ../vosi/vosi-std-responses.yaml#/not-found
+
diff --git a/openapi/vosi/vosi-table-ops-job.yaml b/openapi/vosi/vosi-table-ops-job.yaml
new file mode 100644
index 0000000..fb12a57
--- /dev/null
+++ b/openapi/vosi/vosi-table-ops-job.yaml
@@ -0,0 +1,18 @@
+get:
+ operationId: vosi-table-ops-job-get
+ tags:
+ - VOSI Table Operations
+ summary: get a UWS job description
+ description: job resource
+ parameters:
+ - $ref: ../uws/uws-jobid-param.yaml
+ - $ref: ../uws/uws-wait-param.yaml
+ responses:
+ '200':
+ $ref: ../uws/uws-responses.yaml#/job
+ '401':
+ $ref: ../vosi/vosi-std-responses.yaml#/not-authenticated
+ '403':
+ $ref: ../vosi/vosi-std-responses.yaml#/permission-denied
+ '404':
+ $ref: ../vosi/vosi-std-responses.yaml#/not-found
diff --git a/openapi/vosi/vosi-table-ops.yaml b/openapi/vosi/vosi-table-ops.yaml
new file mode 100644
index 0000000..3c72366
--- /dev/null
+++ b/openapi/vosi/vosi-table-ops.yaml
@@ -0,0 +1,67 @@
+get:
+ operationId: vosi-table-ops-job-list
+ tags:
+ - VOSI Table Operations
+ summary: list async table update jobs
+ description: async job listing
+ parameters:
+ - $ref: ../uws/uws-phase-param.yaml
+ - $ref: ../uws/uws-after-param.yaml
+ - $ref: ../uws/uws-last-param.yaml
+ responses:
+ '200':
+ $ref: ../uws/uws-responses.yaml#/job-listing
+ '401':
+ $ref: ./vosi-std-responses.yaml#/not-authenticated
+ '403':
+ $ref: ./vosi-std-responses.yaml#/permission-denied
+ '404':
+ $ref: ./vosi-std-responses.yaml#/not-found
+post:
+ operationId: vosi-table-ops-job-create
+ tags:
+ - VOSI Table Operations
+ summary: create async table update job
+ description: TAP asynchronous table update (create UWS Job)
+ parameters:
+ - name: TABLE
+ in: query
+ description: a single table name as provided in tap_schema
+ required: true
+ explode: false
+ schema:
+ type: string
+ - name: INDEX
+ in: query
+ description: |
+ create index operation; value is a column name in the table
+ or a comma-separated list of columns; order matters
+ required: true
+ schema:
+ type: string
+ #pattern: ??
+ - name: INDEX_TYPE
+ in: query
+ description: |
+ qualifier to create a specialised index: a value of long-lat
+ requires 2 numeric columns which are used as longitude,latitude
+ pairs (spherical coordinates); a value of x-y requires 2 numeric
+ columns which are used as x,y pairs (cartesian coordinates);
+ required: false
+ # style: form (default), explode: true, and type: array
+ # means the normal zero or more param=value
+ explode: true
+ schema:
+ type: array
+ items:
+ type: string
+ enum: [long-lat,x-y,unique]
+ responses:
+ '303':
+ $ref: ../uws/uws-responses.yaml#/created
+ '401':
+ $ref: ./vosi-std-responses.yaml#/not-authenticated
+ '403':
+ $ref: ./vosi-std-responses.yaml#/permission-denied
+ '404':
+ $ref: ./vosi-std-responses.yaml#/not-found
diff --git a/openapi/vosi/vosi-tableset.yaml b/openapi/vosi/vosi-tableset.yaml
index cf54408..be950cc 100644
--- a/openapi/vosi/vosi-tableset.yaml
+++ b/openapi/vosi/vosi-tableset.yaml
@@ -29,7 +29,7 @@ components:
content:
text/xml:
schema:
- type: object
+ type: string
xml:
name: tableset
prefix: vosi