diff --git a/youcat/build.gradle b/youcat/build.gradle index 6ae07be7..5a5a8207 100644 --- a/youcat/build.gradle +++ b/youcat/build.gradle @@ -15,9 +15,9 @@ sourceCompatibility = 11 group = 'ca.nrc.cadc' war { - // Include the swagger-ui so that /cat provides the cat API documentation + // Include the swagger UI so that base URL provides API docs from(System.getenv('RPS') + '/resources/') { - include 'swagger-ui/' + include 'swagger-openapi/dist/' } } diff --git a/youcat/openapi-linter b/youcat/openapi-linter new file mode 100755 index 00000000..654ad8ca --- /dev/null +++ b/youcat/openapi-linter @@ -0,0 +1,10 @@ +#!/bin/bash + +test -d src/main/webapp && cd src/main/webapp + +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/youcat/rsync-openapi-components.sh b/youcat/rsync-openapi-components.sh new file mode 100755 index 00000000..9156ca93 --- /dev/null +++ b/youcat/rsync-openapi-components.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +VOSI=$HOME/work/dev/ivoa-std/VOSI.git +DALI=$HOME/work/dev/ivoa-std/DALI.git +TAP=$HOME/work/dev/ivoa-std/TAP.git + +ARGS="$1 -avc --delete" + +rsync $ARGS $VOSI/openapi/vosi src/main/webapp/openapi/ +rsync $ARGS $VOSI/openapi/uws src/main/webapp/openapi/ + +rsync $ARGS $DALI/openapi/dali src/main/webapp/openapi/ +rsync $ARGS $TAP/openapi/tap src/main/webapp/openapi/ + diff --git a/youcat/src/main/java/org/opencadc/youcat/YoucatInitAction.java b/youcat/src/main/java/org/opencadc/youcat/YoucatInitAction.java index 5895fd73..77b3266c 100644 --- a/youcat/src/main/java/org/opencadc/youcat/YoucatInitAction.java +++ b/youcat/src/main/java/org/opencadc/youcat/YoucatInitAction.java @@ -81,6 +81,10 @@ import ca.nrc.cadc.uws.server.impl.InitDatabaseUWS; import ca.nrc.cadc.vosi.actions.DeleteAction; import ca.nrc.cadc.vosi.actions.TablesAction; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import javax.naming.Context; import javax.naming.InitialContext; import javax.security.auth.Subject; @@ -107,6 +111,8 @@ public class YoucatInitAction extends InitAction { private Boolean createSchemaInDB = false; private String defaultVOTableSerialization = null; private String deletedSchemaName = null; + + private boolean adminConfigured = false; private String metadataValidation = null; public YoucatInitAction() { @@ -127,10 +133,12 @@ private void initConfig() { sb.append("\n\t").append(YOUCAT_ADMIN).append(": "); if (adminUserStr == null) { sb.append("MISSING"); + this.adminConfigured = false; } else { try { IdentityManager im = AuthenticationUtil.getIdentityManager(); admin = im.toSubject(adminUserStr); + this.adminConfigured = true; String str = admin.toString().replaceAll("\n", " "); sb.append(str).append(" OK"); } catch (Exception ex) { @@ -236,6 +244,25 @@ public void doInit() { DeleteAction.setDeletedSchemaName(deletedSchemaName); TablesAction.setValidatorConfig(prepareValidatorConfig(metadataValidation)); + initOpenApiDocs(); + } catch (Exception ex) { + throw new RuntimeException("INIT FAIL: " + ex.getMessage(), ex); + } + } + + private void initOpenApiDocs() { + try { + URL resURL = super.getResource("openapi-base.yaml"); + if (adminConfigured) { + resURL = super.getResource("openapi-youcat.yaml"); + } + + String path = resURL.getPath(); + log.debug("found openapi: " + resURL + " at " + path); + Path src = Path.of(resURL.toURI()); + Path dest = src.getParent().resolve("openapi.yaml"); + Files.copy(src, dest, StandardCopyOption.COPY_ATTRIBUTES); + log.info("api docs: " + src + " -> " + dest); } catch (Exception ex) { throw new RuntimeException("INIT FAIL: " + ex.getMessage(), ex); } diff --git a/youcat/src/main/webapp/index.html b/youcat/src/main/webapp/index.html index 67b991f8..840d229b 100644 --- a/youcat/src/main/webapp/index.html +++ b/youcat/src/main/webapp/index.html @@ -1,165 +1,85 @@ - + - - youcat API - - - - - - - - - - - - - - - - - - - - - - - - - + .topbar, + .swagger-ui .info span, + .swagger-ui .info .version, + .swagger-ui .scheme-container { + display: none !important; + height: 0; + margin: 0; + padding: 0; + overflow: hidden; + } + - - - -
 
-
+ +
+ + + + diff --git a/youcat/src/main/webapp/openapi-base.yaml b/youcat/src/main/webapp/openapi-base.yaml new file mode 100644 index 00000000..b7cc6bce --- /dev/null +++ b/youcat/src/main/webapp/openapi-base.yaml @@ -0,0 +1,41 @@ +openapi: 3.1.0 +info: + title: | + TAP: generic OpenCADC TAP service implementation + version: "0.9.4" + description: | + This service implements the WD-TAP-1.2 API specification with components imported from + VOSI, UWS, and DALI. Querying is completely compatible with the IVOA TAP-1.1 Recommendation. + + This service is configured for basic TAP operation only. While the service implements + the complete standard, the UWS job child paths described below are a subset. + +servers: +- url: /youcat + +tags: + - name: TAP Query + - name: VOSI Capabilities + - name: VOSI Table Metadata + +paths: + /sync: + $ref: ./openapi/tap/tap-sync.yaml + /async: + $ref: ./openapi/tap/tap-async.yaml + /async/{jobID}: + $ref: ./openapi/tap/tap-async-job.yaml + /async/{jobID}/phase: + $ref: ./openapi/tap/tap-async-job-phase.yaml + /async/{jobID}/results/result: + $ref: ./openapi/tap/tap-result.yaml + + /capabilities: + $ref: ./openapi/vosi/vosi-capabilities.yaml + + /tables: + $ref: ./openapi/vosi/vosi-tableset.yaml + /tables/{name}: + $ref: ./openapi/vosi/vosi-table-11.yaml + + diff --git a/youcat/src/main/webapp/openapi-youcat.yaml b/youcat/src/main/webapp/openapi-youcat.yaml new file mode 100644 index 00000000..d865c6c5 --- /dev/null +++ b/youcat/src/main/webapp/openapi-youcat.yaml @@ -0,0 +1,85 @@ +openapi: 3.1.0 +info: + title: | + youcat: an OpenCADC TAP service with support for user-owned and managed tables + version: "0.9.2" + description: | + This service implements the WD-TAP-1.2 API specification with components imported from + VOSI, UWS, and DALI. Querying is completely compatible with the IVOA TAP-1.1 Recommendation. + + The youcat service supports user management of permissions at both the schema and table level. + A schema owner is set when a YouCat allocation is created by the service operator. A table owner + is the user who created the table. Owners can set a flag for anonymous reading and can set + groups for read-only and read-write permissons. + + The following describes the three types of grants: + + {schema|table}.anon-read = false|true : true grants read-only permission to anonymous callers + + {schema|table}.read-only = NULL | {group URI} : grant read-only permission to a group + + {schema|table}.read-write = NULL | {group URI} : grant read-write permission to a group + + What these grants mean: + + read-only permission on a schema allows the TAP API to expose table existence and metadata + + read-only permission on table: allows the TAP API to expose content of a table (TAP query) + + read-write permissions on a schema: read-only + create table + + read-write permission on a table: read-only + create index, append rows, update (tap_schema) metadata + + owner of a schema has: read-write + drop (any) tables + + owner of a table has: read-write + drop table + + owner of a schema: change permissions on schema and (any) tables + + owner of a table: change permissions on table + + Group URIs are in the format: ivo://cadc.nrc.ca/gms?groupName + +servers: +- url: /youcat + +tags: + - name: TAP Query + - name: VOSI Capabilities + - name: VOSI Table Metadata + - name: VOSI Table Operations + - name: Deprecated + +paths: + /sync: + $ref: ./openapi/tap/tap-sync.yaml + /async: + $ref: ./openapi/tap/tap-async.yaml + /async/{jobID}: + $ref: ./openapi/tap/tap-async-job.yaml + /async/{jobID}/phase: + $ref: ./openapi/tap/tap-async-job-phase.yaml + /async/{jobID}/results/result: + $ref: ./openapi/tap/tap-result.yaml + + /capabilities: + $ref: ./openapi/vosi/vosi-capabilities.yaml + + /tables: + $ref: ./openapi/vosi/vosi-tableset.yaml + /tables/{name}: + $ref: ./openapi/vosi/vosi-table.yaml + +# note use of /table-update rather than /table-ops from VOSI + /table-update: + $ref: ./openapi/vosi/vosi-table-ops.yaml + /table-update/{jobID}: + $ref: ./openapi/vosi/vosi-table-ops-job.yaml + /table-update/{jobID}/phase: + $ref: ./openapi/vosi/vosi-table-ops-job-phase.yaml + + /load/{name}: + $ref: ./openapi/youcat-load.yaml + /permissions/{name}: + $ref: ./openapi/youcat-permissions.yaml + diff --git a/youcat/src/main/webapp/openapi/dali/dali-maxrec.yaml b/youcat/src/main/webapp/openapi/dali/dali-maxrec.yaml new file mode 100644 index 00000000..920b2189 --- /dev/null +++ b/youcat/src/main/webapp/openapi/dali/dali-maxrec.yaml @@ -0,0 +1,12 @@ +name: MAXREC +in: query +description: | + request a specific limit on number of records to return +required: false +schema: + type: integer + format: int64 + inclusiveMinimum: 0 + examples: + - 0 + - 100 diff --git a/youcat/src/main/webapp/openapi/dali/dali-responseformat.yaml b/youcat/src/main/webapp/openapi/dali/dali-responseformat.yaml new file mode 100644 index 00000000..8b3e4042 --- /dev/null +++ b/youcat/src/main/webapp/openapi/dali/dali-responseformat.yaml @@ -0,0 +1,9 @@ +name: RESPONSEFORMAT +in: query +description: select output table format +required: false +schema: + type: string + examples: + - application/x-votable+xml + - vot diff --git a/youcat/src/main/webapp/openapi/dali/dali-upload.yaml b/youcat/src/main/webapp/openapi/dali/dali-upload.yaml new file mode 100644 index 00000000..3b5fbdd2 --- /dev/null +++ b/youcat/src/main/webapp/openapi/dali/dali-upload.yaml @@ -0,0 +1,15 @@ +name: UPLOAD +in: query +description: | + specify a comma-separated name,location pair for a temporary + resource to be uploaded and used in the request +required: false +explode: true +schema: + type: array + items: + type: string + pattern: '^[a-zA-Z]\w*,\S+$' + example: + - tmp1,https://example.net/tmp.vot + - tmp2,param:inline-votable diff --git a/youcat/src/main/webapp/openapi/tap/tap-async-job-phase.yaml b/youcat/src/main/webapp/openapi/tap/tap-async-job-phase.yaml new file mode 100644 index 00000000..79ca646d --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-async-job-phase.yaml @@ -0,0 +1,37 @@ +get: + operationId: tap-job-phase-get + tags: + - TAP Query + summary: get a UWS job phase + description: job phase resource + parameters: + - $ref: ../uws/uws-jobid-param.yaml + responses: + '200': + description: successful response + content: + text/plain: + schema: + type: string + example: "PENDING" +post: + operationId: tap-job-phase-update + tags: + - TAP Query + 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/youcat/src/main/webapp/openapi/tap/tap-async-job.yaml b/youcat/src/main/webapp/openapi/tap/tap-async-job.yaml new file mode 100644 index 00000000..aeba4dea --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-async-job.yaml @@ -0,0 +1,18 @@ +get: + operationId: tap-job-get + tags: + - TAP Query + 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/youcat/src/main/webapp/openapi/tap/tap-async.yaml b/youcat/src/main/webapp/openapi/tap/tap-async.yaml new file mode 100644 index 00000000..78ccf602 --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-async.yaml @@ -0,0 +1,37 @@ +get: + operationId: query-job-list + tags: + - TAP Query + summary: list queries (UWS jobs) + description: TAP asynchronous query endpoint (list UWS Jobs) + 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/vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ../vosi/vosi-std-responses.yaml#/permission-denied +post: + operationId: query-job-create + tags: + - TAP Query + summary: create async query (UWS job) + description: TAP asynchronous query endpoint (create UWS Job) + parameters: + - $ref: ./tap-lang.yaml + - $ref: ./tap-query.yaml + - $ref: ./tap-format.yaml + - $ref: ../dali/dali-maxrec.yaml + - $ref: ../dali/dali-responseformat.yaml + - $ref: ../dali/dali-upload.yaml + responses: + '303': + $ref: ../uws/uws-responses.yaml#/created + '401': + $ref: ../vosi/vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ../vosi/vosi-std-responses.yaml#/permission-denied diff --git a/youcat/src/main/webapp/openapi/tap/tap-format.yaml b/youcat/src/main/webapp/openapi/tap/tap-format.yaml new file mode 100644 index 00000000..40c253bf --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-format.yaml @@ -0,0 +1,5 @@ +name: FORMAT +in: query +description: "supported for backwards compatibility to 1.0 (see: RESPONSEFORMAT)" +schema: + type: string diff --git a/youcat/src/main/webapp/openapi/tap/tap-lang.yaml b/youcat/src/main/webapp/openapi/tap/tap-lang.yaml new file mode 100644 index 00000000..99d3bb4c --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-lang.yaml @@ -0,0 +1,7 @@ +name: LANG +in: query +description: specify the query language used in the QUERY parameter +required: true +schema: + type: string + example: ADQL diff --git a/youcat/src/main/webapp/openapi/tap/tap-query.yaml b/youcat/src/main/webapp/openapi/tap/tap-query.yaml new file mode 100644 index 00000000..934213a7 --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-query.yaml @@ -0,0 +1,7 @@ +name: QUERY +in: query +description: specify the query +required: true +schema: + type: string + example: select * from tap_schema.tables diff --git a/youcat/src/main/webapp/openapi/tap/tap-responses.yaml b/youcat/src/main/webapp/openapi/tap/tap-responses.yaml new file mode 100644 index 00000000..14ccd462 --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-responses.yaml @@ -0,0 +1,17 @@ +# UWS create job response +invalid-query: + description: the requested TAP query job is invalid; this is usually the ADQL query + content: + application/x-votable+xml: + schema: + type: object + xml: + name: VOTABLE + namespace: http://www.ivoa.net/xml/VOTable/v1.3 + example: | + + + Table 'Y' is not found in TAP schema + + diff --git a/youcat/src/main/webapp/openapi/tap/tap-result.yaml b/youcat/src/main/webapp/openapi/tap/tap-result.yaml new file mode 100644 index 00000000..7b70047e --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-result.yaml @@ -0,0 +1,52 @@ +get: + operationId: tap-result + tags: + - TAP Query + summary: async query result + description: download async query result for a completed job + parameters: + - $ref: ../uws/uws-jobid-param.yaml + responses: + '200': + $ref: '#/components/schemas/queryResult' + '303': + description: redirect to the stored result (optional) + '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 + +components: + schemas: + queryResult: + description: query result (table) + content: + application/x-votable+xml: + schema: + type: object + xml: + name: VOTABLE + namespace: http://www.ivoa.net/xml/VOTable/v1.3 + example: | + + + + + schema name for reference to tap_schema.schemas + + + lists the utypes of schemas in the tableset + + + describes schemas in the tableset + + + recommended sort order when listing schemas + + +
+
+
diff --git a/youcat/src/main/webapp/openapi/tap/tap-sync.yaml b/youcat/src/main/webapp/openapi/tap/tap-sync.yaml new file mode 100644 index 00000000..d385a2d5 --- /dev/null +++ b/youcat/src/main/webapp/openapi/tap/tap-sync.yaml @@ -0,0 +1,49 @@ +get: + operationId: sync-query-job-get + tags: + - TAP Query + summary: execute sync query + description: TAP synchronous query endpoint + parameters: + - $ref: ./tap-lang.yaml + - $ref: ./tap-query.yaml + - $ref: ./tap-format.yaml + - $ref: ../dali/dali-maxrec.yaml + - $ref: ../dali/dali-responseformat.yaml + - $ref: ../dali/dali-upload.yaml + responses: + '200': + $ref: './tap-result.yaml#/components/schemas/queryResult' + '303': + description: redirect to the job result (optional) + '400': + $ref: ./tap-responses.yaml#/invalid-query + '401': + $ref: ../vosi/vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ../vosi/vosi-std-responses.yaml#/permission-denied +post: + operationId: sync-query-job-create + tags: + - TAP Query + summary: execute sync query + description: TAP synchronous query endpoint + parameters: + - $ref: ./tap-lang.yaml + - $ref: ./tap-query.yaml + - $ref: ./tap-format.yaml + - $ref: ../dali/dali-maxrec.yaml + - $ref: ../dali/dali-responseformat.yaml + - $ref: ../dali/dali-upload.yaml + responses: + '200': + $ref: './tap-result.yaml#/components/schemas/queryResult' + '303': + description: redirect to the job result (optional) + '400': + $ref: ./tap-responses.yaml#/invalid-query + '401': + $ref: ../vosi/vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ../vosi/vosi-std-responses.yaml#/permission-denied + diff --git a/youcat/src/main/webapp/openapi/uws/uws-after-param.yaml b/youcat/src/main/webapp/openapi/uws/uws-after-param.yaml new file mode 100644 index 00000000..c5afec81 --- /dev/null +++ b/youcat/src/main/webapp/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/youcat/src/main/webapp/openapi/uws/uws-jobid-param.yaml b/youcat/src/main/webapp/openapi/uws/uws-jobid-param.yaml new file mode 100644 index 00000000..2c03a07b --- /dev/null +++ b/youcat/src/main/webapp/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/youcat/src/main/webapp/openapi/uws/uws-last-param.yaml b/youcat/src/main/webapp/openapi/uws/uws-last-param.yaml new file mode 100644 index 00000000..93a53b70 --- /dev/null +++ b/youcat/src/main/webapp/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/youcat/src/main/webapp/openapi/uws/uws-phase-change-param.yaml b/youcat/src/main/webapp/openapi/uws/uws-phase-change-param.yaml new file mode 100644 index 00000000..7a0f156a --- /dev/null +++ b/youcat/src/main/webapp/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/youcat/src/main/webapp/openapi/uws/uws-phase-param.yaml b/youcat/src/main/webapp/openapi/uws/uws-phase-param.yaml new file mode 100644 index 00000000..610991bd --- /dev/null +++ b/youcat/src/main/webapp/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/youcat/src/main/webapp/openapi/uws/uws-responses.yaml b/youcat/src/main/webapp/openapi/uws/uws-responses.yaml new file mode 100644 index 00000000..6fd58db5 --- /dev/null +++ b/youcat/src/main/webapp/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: object + 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: object + 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/youcat/src/main/webapp/openapi/uws/uws-wait-param.yaml b/youcat/src/main/webapp/openapi/uws/uws-wait-param.yaml new file mode 100644 index 00000000..31fadab3 --- /dev/null +++ b/youcat/src/main/webapp/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/youcat/src/main/webapp/openapi/vosi/vosi-capabilities.yaml b/youcat/src/main/webapp/openapi/vosi/vosi-capabilities.yaml new file mode 100644 index 00000000..b60a3827 --- /dev/null +++ b/youcat/src/main/webapp/openapi/vosi/vosi-capabilities.yaml @@ -0,0 +1,56 @@ +head: + operationId: probe-capabilities + tags: + - VOSI Capabilities + summary: VOSI Capabilities with SSO-next prototype + description: | + Get standard headers for the service. The standard headers should include + AAI related headers (www-authenticate challenges or x-vo-authenticated + indicator) if applicable, server name and version info, and other + applicable header information. SSO-next: clients use this operation to probe + for available authentication methods. + responses: + '200': + $ref: ./vosi-std-responses.yaml#/authenticated + '401': + $ref: ./vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi-std-responses.yaml#/permission-denied +get: + operationId: read-capabilities + tags: + - VOSI Capabilities + summary: VOSI Capabilities with SSO-next prototype + description: Get the set of VOResource capability descriptions for this service. + responses: + '200': + $ref: '#/components/schemas/capabilities' + '401': + $ref: ./vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi-std-responses.yaml#/permission-denied + +components: + schemas: + capabilities: + description: A VOSI Capabilities document + content: + text/xml: + schema: + type: object + xml: + name: capabilities + prefix: vosi + namespace: http://www.ivoa.net/xml/VOSICapabilities/v1.0 + example: | + + + + https://example.net/tap-service/capabilities + + + ... + diff --git a/youcat/src/main/webapp/openapi/vosi/vosi-std-responses.yaml b/youcat/src/main/webapp/openapi/vosi/vosi-std-responses.yaml new file mode 100644 index 00000000..853a6b66 --- /dev/null +++ b/youcat/src/main/webapp/openapi/vosi/vosi-std-responses.yaml @@ -0,0 +1,49 @@ +# standard +authenticated: + description: a response header indicating that authentication was successful + headers: + x-vo-authenticated: + schema: + type: string + +not-authenticated: + description: authentication is required and current attempt failed + headers: + www-authenticate: + schema: + type: string + +permission-denied: + description: caller not authorized to perform operation + content: + text/plain: + schema: + type: string + +bad-request: + description: invalid request/input + content: + text/plain: + schema: + type: string + +not-found: + description: resource not found + content: + text/plain: + schema: + type: string + +not-implemented: + description: this response indicates that the service does not support this operation + content: + text/plain: + schema: + type: string + +too-large: + description: the request content exceeds a server-side limitation on size + content: + text/plain: + schema: + type: string diff --git a/youcat/src/main/webapp/openapi/vosi/vosi-table-11.yaml b/youcat/src/main/webapp/openapi/vosi/vosi-table-11.yaml new file mode 100644 index 00000000..21fb3043 --- /dev/null +++ b/youcat/src/main/webapp/openapi/vosi/vosi-table-11.yaml @@ -0,0 +1,94 @@ +# this is the read-only /tables/{tableName} endpoint from VOSI-1.1 +get: + operationId: read-table-metadata + tags: + - VOSI Table Metadata + summary: get metadata for the specified table + description: provides the table metadata for a single schema or table + parameters: + - in: path + name: name + description: a single schema name or table name as provided in tap_schema + required: true + schema: + type: string + responses: + '200': + $ref: '#/components/schemas/tableDoc' + '401': + $ref: ./vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi-std-responses.yaml#/permission-denied + '404': + $ref: ./vosi-std-responses.yaml#/not-found + +components: + schemas: + tableDoc: + description: metadata for the specified schema or table + content: + text/xml: + schema: + type: object + xml: + name: table + prefix: vosi + namespace: http://www.ivoa.net/xml/VOSITables/v1.0 + example: | + + tap_schema.schemas + description of schemas in this tableset + + schema_name + schema name for reference to tap_schema.schemas + char + indexed + + + utype + lists the utypes of schemas in the tableset + char + + + description + describes schemas in the tableset + char + + + schema_index + recommended sort order when listing schemas + int + + + + application/x-votable+xml: + schema: + type: object + xml: + name: VOTABLE + namespace: http://www.ivoa.net/xml/VOTable/v1.3 + example: | + + + + + schema name for reference to tap_schema.schemas + + + lists the utypes of schemas in the tableset + + + describes schemas in the tableset + + + recommended sort order when listing schemas + + +
+
+
+ diff --git a/youcat/src/main/webapp/openapi/vosi/vosi-table-ops-job-phase.yaml b/youcat/src/main/webapp/openapi/vosi/vosi-table-ops-job-phase.yaml new file mode 100644 index 00000000..5c382f9e --- /dev/null +++ b/youcat/src/main/webapp/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/youcat/src/main/webapp/openapi/vosi/vosi-table-ops-job.yaml b/youcat/src/main/webapp/openapi/vosi/vosi-table-ops-job.yaml new file mode 100644 index 00000000..fb12a57a --- /dev/null +++ b/youcat/src/main/webapp/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/youcat/src/main/webapp/openapi/vosi/vosi-table-ops.yaml b/youcat/src/main/webapp/openapi/vosi/vosi-table-ops.yaml new file mode 100644 index 00000000..f54bee8f --- /dev/null +++ b/youcat/src/main/webapp/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 (NOT IMPLEMENTED) a comma-separated list of columns; order matters + required: true + schema: + type: string + #pattern: ?? + - name: INDEX_TYPE + in: query + description: | + NOT IMPLEMENTED: 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/youcat/src/main/webapp/openapi/vosi/vosi-table.yaml b/youcat/src/main/webapp/openapi/vosi/vosi-table.yaml new file mode 100644 index 00000000..2bee6556 --- /dev/null +++ b/youcat/src/main/webapp/openapi/vosi/vosi-table.yaml @@ -0,0 +1,180 @@ +# this is the VOSI-1.2 /tables/{tablename} endpoint +get: + operationId: read-table-metadata + tags: + - VOSI Table Metadata + summary: get metadata for the specified table + description: provides the table metadata for a single schema or table + parameters: + - in: path + name: name + description: a single schema name or table name as provided in tap_schema + required: true + schema: + type: string + responses: + '200': + $ref: '#/components/schemas/tableDoc' + '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: update-table + tags: + - VOSI Table Metadata + summary: proto - update table metadata and/or content (optional) + description: update the table metadata from a table description; may include rows to append if input format supports it + parameters: + - in: path + name: name + description: the fully qualified name of the table to create + required: true + schema: + type: string + requestBody: + description: a table description + $ref: '#/components/schemas/tableDoc' + responses: + '204': + description: table updated + '400': + $ref: ./vosi-std-responses.yaml#/bad-request + '401': + $ref: ./vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi-std-responses.yaml#/permission-denied + '404': + $ref: ./vosi-std-responses.yaml#/not-found + '405': + $ref: ./vosi-std-responses.yaml#/not-implemented + '413': + $ref: ./vosi-std-responses.yaml#/too-large +put: + operationId: create-table + tags: + - VOSI Table Metadata + summary: proto - create table (optional) + description: create table from a table description; may include rows if input format supports it + parameters: + - in: path + name: name + description: the fully qualified name of the table to create + required: true + schema: + type: string + requestBody: + description: a table description + $ref: '#/components/schemas/tableDoc' + responses: + '201': + description: table created + '400': + $ref: ./vosi-std-responses.yaml#/bad-request + '401': + $ref: ./vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi-std-responses.yaml#/permission-denied + '404': + $ref: ./vosi-std-responses.yaml#/not-found + '405': + $ref: ./vosi-std-responses.yaml#/not-implemented + '413': + $ref: ./vosi-std-responses.yaml#/too-large +delete: + operationId: delete-table + tags: + - VOSI Table Metadata + summary: proto - delete table (optional) + description: delete table by name + parameters: + - name: name + in: path + description: the table to delete + required: true + schema: + type: string + responses: + '204': + description: table deleted + '400': + $ref: ./vosi-std-responses.yaml#/bad-request + '401': + $ref: ./vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi-std-responses.yaml#/permission-denied + '404': + $ref: ./vosi-std-responses.yaml#/not-found + +components: + schemas: + tableDoc: + description: metadata for the specified schema or table + content: + text/xml: + schema: + type: object + xml: + name: table + prefix: vosi + namespace: http://www.ivoa.net/xml/VOSITables/v1.0 + example: | + + tap_schema.schemas + description of schemas in this tableset + + schema_name + schema name for reference to tap_schema.schemas + char + indexed + + + utype + lists the utypes of schemas in the tableset + char + + + description + describes schemas in the tableset + char + + + schema_index + recommended sort order when listing schemas + int + + + application/x-votable+xml: + schema: + type: object + xml: + name: VOTABLE + namespace: http://www.ivoa.net/xml/VOTable/v1.3 + example: | + + + + + schema name for reference to tap_schema.schemas + + + lists the utypes of schemas in the tableset + + + describes schemas in the tableset + + + recommended sort order when listing schemas + + +
+
+
+ + diff --git a/youcat/src/main/webapp/openapi/vosi/vosi-tableset.yaml b/youcat/src/main/webapp/openapi/vosi/vosi-tableset.yaml new file mode 100644 index 00000000..cf54408b --- /dev/null +++ b/youcat/src/main/webapp/openapi/vosi/vosi-tableset.yaml @@ -0,0 +1,68 @@ +get: + operationId: get-tableset + tags: + - VOSI Table Metadata + summary: VOSI TableSet + description: Provides the table metadata in the form of a TableSet description + parameters: + - name: detail + in: query + description: level of detail requested + required: false + schema: + type: string + enum: [min, max] + responses: + '200': + $ref: '#/components/schemas/tablesetDoc' + '400': + $ref: ./vosi-std-responses.yaml#/bad-request + '401': + $ref: ./vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi-std-responses.yaml#/permission-denied + +components: + schemas: + tablesetDoc: + description: metadata for schemas and tables + content: + text/xml: + schema: + type: object + xml: + name: tableset + prefix: vosi + namespace: http://www.ivoa.net/xml/VOSITables/v1.0 + example: | + + + tap_schema + a special schema to describe TAP-1.1 tablesets + + tap_schema.schemas + description of schemas in this tableset +
+ + tap_schema.tables + description of tables in this tableset +
+ + tap_schema.columns + description of columns in this tableset +
+ + tap_schema.keys + description of foreign keys in this tableset +
+ + tap_schema.key_columns + description of foreign key columns in this tableset +
+
+ ... +
+ diff --git a/youcat/src/main/webapp/openapi/youcat-load.yaml b/youcat/src/main/webapp/openapi/youcat-load.yaml new file mode 100644 index 00000000..e9deb605 --- /dev/null +++ b/youcat/src/main/webapp/openapi/youcat-load.yaml @@ -0,0 +1,46 @@ +post: + operationId: youcat-bulk-load + tags: + - Deprecated + summary: bulk load or row data (deprecated) + description: youcat synchronous bulk load endpoint (deprecated) + parameters: + - name: name + in: path + description: a single table name as provided in tap_schema + required: true + schema: + type: string + requestBody: + $ref: '#/components/schemas/tableRows' + + responses: + '200': + description: | + rows loaded; + TBD: both partial or complete are possible + '401': + $ref: ./vosi/vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi/vosi-std-responses.yaml#/permission-denied + +components: + schemas: + tableRows: + description: tabular content with rows to be appended to the table + content: + text/tab-separated-values: + schema: + type: string + text/csv: + schema: + type: string + application/fits: + application/x-votable+xml: + schema: + type: object + xml: + name: VOTABLE + namespace: http://www.ivoa.net/xml/VOTable/v1.3 + + diff --git a/youcat/src/main/webapp/openapi/youcat-permissions.yaml b/youcat/src/main/webapp/openapi/youcat-permissions.yaml new file mode 100644 index 00000000..082714f6 --- /dev/null +++ b/youcat/src/main/webapp/openapi/youcat-permissions.yaml @@ -0,0 +1,54 @@ +get: + operationId: youcat-get-permissions + tags: + - Deprecated + summary: get permissions (deprecated) + description: youcat get schema and table permissions endpoint (deprecated) + parameters: + - name: name + in: path + description: a single schema or table name as provided in tap_schema + required: true + schema: + type: string + responses: + '200': + $ref: '#/components/schemas/permissionDoc' + '401': + $ref: ./vosi/vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi/vosi-std-responses.yaml#/permission-denied +post: + operationId: youcat-set-permissions + tags: + - Deprecated + summary: set permissions (deprecated) + description: youcat set schema and table permissions endpoint (deprecated) + parameters: + - name: name + in: path + description: a single schema or table name as provided in tap_schema + required: true + schema: + type: string + requestBody: + $ref: '#/components/schemas/permissionDoc' + + responses: + '200': + description: | + rows loaded; + TBD: both partial or complete are possible + '401': + $ref: ./vosi/vosi-std-responses.yaml#/not-authenticated + '403': + $ref: ./vosi/vosi-std-responses.yaml#/permission-denied + +components: + schemas: + permissionDoc: + description: document with permissions settings + content: + text/plain: + schema: + type: string diff --git a/youcat/src/main/webapp/service.json b/youcat/src/main/webapp/service.json deleted file mode 100644 index 3ce8e625..00000000 --- a/youcat/src/main/webapp/service.json +++ /dev/null @@ -1,819 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "version": "1.0", - "title": "user-managed TAP service (youcat)", - "description": "This page contains technical API information.\n\nThis service implements the IVOA TAP-1.1 Recommendation plus extensions to support table creation and bulk loading of content.\n\nThe endpoints listed below support both anonymous and authenticated access (using client certificate or cookie).\n\n YouCat supports user management of permissions at both the schema and table level. A schema owner is set when a YouCat allocation is created by the service operator. Table owners are set to be the user who created the table. Owners can set a flag for anonymous reading and can set groups for read-only and read-write permissons.\n The following describes how the permissions are enforced on schemas and tables:\n\n \t{schema|table}.public = false|true\n \t\tallows querying via TAP API\n \t{schema|table|.read-only = NULL | {group URI}\n \t\tread-only permission on a schema: allows TAP API to expose table\n \t\tread-only permission on table: allows TAP API to expose content of a table\n \t{schema|table}.read-write = NULL | {group URI}\n \t\tread-write permissions on a schema: read-only + create table\n \t\tread-write permission on a table: read-only + create index, append rows, update (tap_schema) metadata\n \t{schema|table}.owner\n \t\towner of a schema has: read-write + drop (any) table\n \t\towner of a table has: read-write + drop table\n \t\towner of a schema: change permissions on schema and all tables\n \t\towner of a table: change permissions on table\n\nGroup URIs are in the format:\n\n \tivo://cadc.nrc.ca/gms?groupName" - }, - "schemes": [ - "https" - ], - "basePath": "/youcat", - "paths": { - "/async": { - "post": { - "summary": "IVOA TAP v1.1", - "tags": [ - "TAP" - ], - "description": "TAP asynchronous query endpoint (create UWS Job)\n", - "parameters": [ - { - "name": "LANG", - "in": "query", - "description": "specify the query language used in the QUERY parameter", - "required": true, - "type": "string" - }, - { - "name": "QUERY", - "in": "query", - "description": "specify the query", - "required": true, - "type": "string" - }, - { - "name": "FORMAT", - "in": "query", - "description": "supported for backwards compatibility to 1.0 (see: RESPONSEFORMAT)", - "required": false, - "type": "string" - }, - { - "name": "RESPONSEFORMAT", - "in": "query", - "description": "select output table format", - "required": false, - "type": "string" - }, - { - "name": "MAXREC", - "in": "query", - "description": "request a specific limit on number of rows to return", - "required": false, - "type": "integer", - "format": "int64" - }, - { - "name": "DEST", - "in": "query", - "description": "specify destination where output should be written (VOSpace URI)", - "required": false, - "type": "string", - "format": "uri" - }, - { - "name": "UPLOAD", - "in": "query", - "collectionFormat": "multi", - "description": "specify name,location pair for a table to be uploaded and used in the query", - "required": false, - "type": "string" - } - ], - "produces": [ - "text/xml" - ], - "responses": { - "200": { - "description": "Successful response" - }, - "303": { - "description": "standard UWS redirect to the created job" - }, - "401": { - "description": "Unauthorized - User not authenticated" - }, - "403": { - "description": "Permission Denied - Table(s) not readable" - }, - "404": { - "description": "Not Found - Table(s) not found" - }, - "500": { - "description": "Internal error" - }, - "503": { - "description": "Service busy" - }, - "default": { - "description": "Unexpeced error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/sync": { - "get": { - "summary": "IVOA TAP v1.1", - "tags": [ - "TAP" - ], - "description": "TAP synchronous query endpoint\n", - "parameters": [ - { - "name": "LANG", - "in": "query", - "description": "specify the query language used in the QUERY parameter", - "required": true, - "type": "string" - }, - { - "name": "QUERY", - "in": "query", - "description": "specify the query", - "required": true, - "type": "string" - }, - { - "name": "FORMAT", - "in": "query", - "description": "supported for backwards compatibility to 1.0 (see: RESPONSEFORMAT)", - "required": false, - "type": "string" - }, - { - "name": "RESPONSEFORMAT", - "in": "query", - "description": "select output table format", - "required": false, - "type": "string" - }, - { - "name": "MAXREC", - "in": "query", - "description": "request a specific limit on number of rows to return", - "required": false, - "type": "integer", - "format": "int64" - }, - { - "name": "UPLOAD", - "in": "query", - "collectionFormat": "multi", - "description": "specify name,location pair for a table to be uploaded and used in the query", - "required": false, - "type": "string" - } - ], - "produces": [ - "application/x-votable+/xml" - ], - "responses": { - "200": { - "description": "Successful response" - }, - "401": { - "description": "Unauthorized - User not authenticated" - }, - "403": { - "description": "Permission Denied - Table(s) not readable" - }, - "404": { - "description": "Not Found - Table(s) not found" - }, - "500": { - "description": "Internal error" - }, - "503": { - "description": "Service busy" - }, - "default": { - "description": "Unexpeced error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - }, - "post": { - "summary": "IVOA TAP v1.1", - "tags": [ - "TAP" - ], - "description": "TAP synchronous query endpoint\n", - "parameters": [ - { - "name": "LANG", - "in": "query", - "description": "specify the query language used in the QUERY parameter", - "required": true, - "type": "string" - }, - { - "name": "QUERY", - "in": "query", - "description": "specify the query", - "required": true, - "type": "string" - }, - { - "name": "FORMAT", - "in": "query", - "description": "supported for backwards compatibility to 1.0 (see: RESPONSEFORMAT)", - "required": false, - "type": "string" - }, - { - "name": "RESPONSEFORMAT", - "in": "query", - "description": "select output table format", - "required": false, - "type": "string" - }, - { - "name": "MAXREC", - "in": "query", - "description": "request a specific limit on number of rows to return", - "required": false, - "type": "integer", - "format": "int64" - }, - { - "name": "UPLOAD", - "in": "query", - "collectionFormat": "multi", - "description": "specify name,location pair for a table to be uploaded and used in the query", - "required": false, - "type": "string" - } - ], - "produces": [ - "application/x-votable+/xml" - ], - "responses": { - "200": { - "description": "Successful response" - }, - "401": { - "description": "Unauthorized - User not authenticated" - }, - "403": { - "description": "Permission denied - Table(s) not readable" - }, - "404": { - "description": "Not Found - Table(s) not found" - }, - "500": { - "description": "Internal error" - }, - "503": { - "description": "Service busy" - }, - "default": { - "description": "Unexpeced error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/availability": { - "get": { - "tags": [ - "Support Interfaces" - ], - "summary": "VOSI Availability", - "description": "Indicates whether the service is operable and shows the reliability of the service for extended and scheduled requests. If the query parameter 'detail=min' is used, a light weight heart beat test will be performed. The heart beat test returns status 200 if the service is available.", - "parameters": [ - { - "name": "detail", - "in": "query", - "description": "specifies heart beat to be used to check for availability of this service, the value 'min' must be used, otherwise the full availability test will be performed", - "required": false, - "type": "string" - } - ], - "produces": [ - "text/xml" - ], - "responses": { - "200": { - "description": "A VOSI availability document in XML.", - "schema": { - "$ref": "#/definitions/availability" - } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/capabilities": { - "get": { - "summary": "VOSI Capabilities", - "tags": [ - "Support Interfaces" - ], - "description": "Provides the service metadata in the form of a list of Capability descriptions. Each of these descriptions is an \nXML element that:\n\n", - "produces": [ - "text/xml" - ], - "responses": { - "200": { - "description": "A VOSI Capabilities document in XML.", - "schema": { - "$ref": "#/definitions/capabilities" - } - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/tables": { - "get": { - "summary": "VOSI Tables", - "tags": [ - "Support Interfaces" - ], - "description": "Provides the table metadata in the form of a TableSet descriptions.\n", - "produces": [ - "text/xml" - ], - "responses": { - "200": { - "description": "A VOSI document in XML.", - "schema": { - "$ref": "#/definitions/tables" - } - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/tables/{name}?action={action}": { - "get": { - "summary": "Validate table metadata", - "tags": [ - "Support Interfaces" - ], - "description": "Validates table metadata and provides errors and warnings to improvise the table metadata.", - "parameters": [ - { - "name": "name", - "in": "path", - "description": "a single fully qualified table name (e.g. tap_schema.tables)", - "required": true, - "type": "string" - }, - { - "name": "action", - "in": "query", - "description": "specify 'validate' to validate the table metadata instead of retrieving it", - "required": false, - "type": "string", - "enum": ["validate"] - } - ], - "produces": [ - "text/plain" - ], - "responses": { - "200": { - "description": "'OK' for valid table metadata and 'Errors' followed by 'Warnings' for invalid table metadata." - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/tables/{name}": { - "get": { - "summary": "get table metadata (VOSI)", - "tags": [ - "Support Interfaces" - ], - "description": "Provides the table metadata for a single table.\n", - "parameters": [ - { - "name": "name", - "in": "path", - "description": "a single fully qualified table name (e.g. tap_schema.tables)", - "required": true, - "type": "string" - } - ], - "produces": [ - "text/xml" - ], - "responses": { - "200": { - "description": "A VOSI document in XML.", - "schema": { - "$ref": "#/definitions/tables" - } - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - }, - "put": { - "summary": "create table", - "description": "table description in VOSI table or VOTable (no rows) format\n", - "tags": [ - "Custom Features" - ], - "parameters": [ - { - "name": "name", - "in": "path", - "description": "the fully qualified name of the table to create\n", - "required": true, - "type": "string" - } - ], - "consumes": [ - "text/xml", - "application/x-votable+xml", - "application/vnd.apache.parquet" - ], - "responses": { - "201": { - "description": "table created" - }, - "400": { - "description": "create table failed due to invalid input" - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - }, - "delete": { - "summary": "drop table", - "tags": [ - "Custom Features" - ], - "parameters": [ - { - "name": "name", - "in": "path", - "description": "the table to drop", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "table dropped" - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/permissions/{name}": { - "get": { - "summary": "view schema or table permissions", - "tags": [ - "Custom Features" - ], - "description": "View the owner, public flag, read group, and write group of a schema or table.\n", - "parameters": [ - { - "name": "name", - "in": "path", - "description": "name of the schema or table to view.", - "required": true, - "type": "string" - } - ], - "provides": [ - "text/plain" - ], - "responses": { - "200": { - "description": "successful request" - }, - "400": { - "description": "invalid syntax" - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - }, - "post": { - "summary": "modify schema or table permissions", - "tags": [ - "Custom Features" - ], - "description": "Modify any of the public flag, readGroup or writeGroup of a schema or table. These operations are permitted by the owner of the schema and owners of the target tables. Parameters are in-line CFLF separated entries in key=value format. An example of a groupURI is ivo://cadc.nrc.ca/gms?myGroup\n", - "parameters": [ - { - "name": "name", - "in": "path", - "description": "name of the schema or table to modify.", - "required": true, - "type": "string" - }, - { - "name": "public", - "in": "body", - "description": "public=true or public=false", - "required": false, - "type": "string" - }, - { - "name": "r-group", - "in": "body", - "description": "set or clear read group. r-group=groupURI or r-group= to clear. group URI in format ivo://cadc.nrc.ca/gms?groupName", - "required": false, - "type": "string" - }, - { - "name": "rw-group", - "in": "body", - "description": "set or clear read/write group. rw-group=groupURI or rw-group= to clear. group URI in format ivo://cadc.nrc.ca/gms?groupName", - "required": false, - "type": "string" - } - ], - "consumes": [ - "text/plain" - ], - "responses": { - "200": { - "description": "permissions updated successfully" - }, - "400": { - "description": "invalid permission syntax" - }, - "403": { - "description": "Insufficient permission to change permissions" - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/load/{tableName}": { - "post": { - "summary": "sync streaming row insert", - "tags": [ - "Custom Features" - ], - "description": "Bulk load rows and append to the table. This currently supports input data in CSV and TSV format (with header), and FITS Binary Tables\n", - "parameters": [ - { - "name": "tableName", - "in": "path", - "description": "a single fully qualified table name (e.g. tap_schema.tables)", - "required": true, - "type": "string" - } - ], - "consumes": [ - "text/csv", - "text/tab-separated-values", - "application/fits" - ], - "responses": { - "200": { - "description": "rows successfully inserted", - "schema": { - "$ref": "#/definitions/tables" - } - }, - "400": { - "description": "insert rows failed due to invalid input" - }, - "500": { - "description": "Internal server error" - }, - "503": { - "description": "Service too busy" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - }, - "/table-update": { - "post": { - "summary": "async table update (create UWS Job)", - "tags": [ - "Custom Features" - ], - "description": "Asynchronous table update currently update supports index creation. In future it will also support loading content (rows) from a remote location (URI)", - "parameters": [ - { - "name": "TABLE", - "in": "query", - "description": "the table to update (TABLE={table name}): fully-qualified name of the table to update", - "required": true, - "type": "string" - }, - { - "name": "INDEX", - "in": "query", - "description": "index a column (INDEX={column name}): value is the name of the column to index; currently limited to single column only", - "required": true, - "type": "string" - }, - { - "name": "UNIQUE", - "in": "query", - "description": "create unique index (UNIQUE=true): use with INDEX={column name} to make a unique index (default: false)", - "required": false, - "type": "boolean" - } - ], - "produces": [ - "text/xml" - ], - "responses": { - "200": { - "description": "Successful response" - }, - "303": { - "description": "standard UWS redirect to the created job" - }, - "401": { - "description": "Unauthorized - User not authenticated" - }, - "404": { - "description": "Not Found - User not found" - }, - "500": { - "description": "Internal error" - }, - "503": { - "description": "Service busy" - }, - "default": { - "description": "Unexpeced error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - } - }, - "definitions": { - "Job": { - "type": "string" - }, - "availability": { - "type": "object", - "xml": { - "name": "availability", - "namespace": "http://www.ivoa.net/xml/VOSIAvailability/v1.0", - "prefix": "vosi" - }, - "properties": { - "available": { - "type": "boolean", - "xml": { - "attribute": true, - "prefix": "vosi" - } - }, - "note": { - "type": "string", - "xml": { - "attribute": true, - "prefix": "vosi" - } - } - } - }, - "tables": { - "type": "object", - "xml": { - "namespace": "http://www.ivoa.net/xml/VOSITables/v1.0", - "prefix": "vosi" - }, - "properties": { - "available": { - "type": "boolean", - "xml": { - "attribute": true, - "prefix": "vosi" - } - }, - "note": { - "type": "string", - "xml": { - "attribute": true, - "prefix": "vosi" - } - } - } - }, - "capabilities": { - "type": "object", - "xml": { - "namespace": "http://www.ivoa.net/xml/VOSICapabilities/v1.0", - "prefix": "vosi" - } - }, - "Error": { - "required": [ - "code", - "message" - ], - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - } - } - } - } -}