Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d1d37c1
youcat: initial openapi based api docs
pdowler Jul 15, 2024
bf2ddfc
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Sep 3, 2024
b9ade10
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Sep 5, 2024
d9a9d27
progress on decomposing TAP openapi into importable fragments
pdowler Sep 5, 2024
7d69203
vosi openapi cleanup
pdowler Sep 10, 2024
944f57a
start on reusable response descriptions
pdowler Sep 12, 2024
5d52f3f
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Oct 3, 2024
16af2b7
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Oct 4, 2024
0cb03bd
minor openapi tweaks
pdowler Oct 4, 2024
1cef3b9
tidy openapi for clarity
pdowler Oct 15, 2024
9fe886c
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Oct 16, 2024
8ddb9f7
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Oct 16, 2024
4100e63
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Oct 17, 2024
574240a
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Nov 29, 2024
4c063bd
Merge branch 'main' into openapi
pdowler May 8, 2025
c7582e8
openapi updates for youcat
pdowler May 9, 2025
0d40459
Merge branch 'rubin' of https://github.com/opencadc/tap into openapi
pdowler May 12, 2025
b71c51c
youcat rename in TAP/openapi.yaml
pdowler May 15, 2025
6952d38
update OpenAPI specs by pulling in components from ivoa-std repos
pdowler May 16, 2025
9fc30a9
Merge branch 'rubin' into openapi
pdowler May 16, 2025
718c8fd
youcat: openapi docs synced with ivoa-std versions
pdowler May 22, 2025
206769d
Merge branch 'openapi' of https://github.com/pdowler/tap into openapi
pdowler May 26, 2025
eb2ab98
youcat: add customm CADC styling to API docs
pdowler May 26, 2025
d7b6bd4
youcat: add required version attribute
pdowler May 26, 2025
e191eea
Merge branch 'main' into openapi
pdowler May 30, 2025
36c20f1
merge old service description into openapi docs
pdowler May 30, 2025
90ff602
Merge branch 'openapi' of https://github.com/pdowler/tap into openapi
pdowler May 30, 2025
47d15b1
add note about undocumented permissions endpoint
pdowler May 30, 2025
8acf6c6
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Jun 11, 2025
6dc4f96
Merge branch 'main' into openapi
pdowler Sep 19, 2025
f430216
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Feb 17, 2026
8fbc608
added some padding to the swagger-ui div
pdowler Feb 17, 2026
6a450e7
Merge branch 'main' into openapi
pdowler Feb 25, 2026
93c3948
youcat: import latest openapi components from ivoa-std
pdowler Feb 26, 2026
4ed4681
Merge branch 'main' into openapi
pdowler Mar 25, 2026
bddd8d4
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Mar 31, 2026
3a1c877
added deprecated load and permissions endpoints to api docs
pdowler Apr 1, 2026
2b2ce33
include vosi-table-ops
pdowler Apr 1, 2026
076507c
update documented table-ops endpoint to match current build
pdowler Apr 1, 2026
33fbee3
Merge branch 'main' into openapi
pdowler Apr 1, 2026
caeff76
Merge branch 'main' into openapi
pdowler Apr 9, 2026
8a65184
youcat: sync openapi from VOSI and TAP
pdowler Apr 9, 2026
c5c47fd
Merge branch 'main' of https://github.com/opencadc/tap into openapi
pdowler Apr 9, 2026
145a4ec
change rsync to pull UWS from VOSI repo
pdowler Apr 9, 2026
e356647
youcat: deliver OpenAPI docs appropriate to the config
pdowler Apr 28, 2026
1554976
Merge branch 'main' into openapi
pdowler May 4, 2026
38ad210
update openapi components from upstream
pdowler May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions youcat/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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/'
}
}

Expand Down
10 changes: 10 additions & 0 deletions youcat/openapi-linter
Original file line number Diff line number Diff line change
@@ -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

14 changes: 14 additions & 0 deletions youcat/rsync-openapi-components.sh
Original file line number Diff line number Diff line change
@@ -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/

27 changes: 27 additions & 0 deletions youcat/src/main/java/org/opencadc/youcat/YoucatInitAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() {
Expand All @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand Down
206 changes: 63 additions & 143 deletions youcat/src/main/webapp/index.html
Original file line number Diff line number Diff line change
@@ -1,165 +1,85 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>youcat API</title>
<link rel="icon" type="image/png"
href="swagger-ui/images/favicon-32x32.png" sizes="32x32"/>
<link rel="icon" type="image/png"
href="swagger-ui/images/favicon-16x16.png" sizes="16x16"/>
<link href='swagger-ui/css/typography.css' media='screen'
rel='stylesheet' type='text/css'/>
<link href='swagger-ui/css/reset.css' media='screen' rel='stylesheet'
type='text/css'/>
<link href='swagger-ui/css/screen.css' media='screen' rel='stylesheet'
type='text/css'/>
<link href='swagger-ui/css/reset.css' media='print' rel='stylesheet'
type='text/css'/>
<link href='swagger-ui/css/print.css' media='print' rel='stylesheet'
type='text/css'/>
<script src='swagger-ui/lib/jquery-1.8.0.min.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/jquery.slideto.min.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/jquery.wiggle.min.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/jquery.ba-bbq.min.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/handlebars-2.0.0.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/js-yaml.min.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/lodash.min.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/backbone-min.js'
type='text/javascript'></script>
<script src='swagger-ui/swagger-ui.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/highlight.9.1.0.pack.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/highlight.9.1.0.pack_extended.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/jsoneditor.min.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/marked.js'
type='text/javascript'></script>
<script src='swagger-ui/lib/swagger-oauth.js'
type='text/javascript'></script>

<style type="text/css">
<meta charset="UTF-8">
<link rel="icon" type="image/png" href="swagger-openapi/dist/favicon-32x32.png" sizes="32x32"/>
<link rel="icon" type="image/png" href="swagger-openapi/dist/favicon-16x16.png" sizes="16x16"/>
<link href='swagger-openapi/dist/index.css' rel='stylesheet' type='text/css'/>
<link href='swagger-openapi/dist/swagger-ui.css'rel='stylesheet' type='text/css'/>
<title>YouCat API</title>
<style>
/*
Custom CSS from CADC.
jenkinsd 2016.03.01
*/
.swagger-section #header {
background-color: rgba(42, 125, 166, 0.7);
padding: 14px;
}

.swagger-section #header #logo {
padding: 0;
color: white;
font-size: 1.5em;
font-weight: bold;
text-decoration: none;
}

.swagger-section #header a#logo {
background: transparent;
.swagger-section .swagger-ui,
.swagger-section .swagger-ui-wrap {
max-width: 960px;
margin-left: auto;
margin-right: auto;
line-height: 1;
font-family: "Droid Sans", sans-serif;
}
</style>

<script type="text/javascript">
$(function ()
{
var url = "service.json";

hljs.configure({
highlightSizeThreshold: 5000
});

// Pre load translate...
if (window.SwaggerTranslator)
{
window.SwaggerTranslator.translate();
}
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get'],
onComplete: function (swaggerApi, swaggerUi)
{
if (typeof initOAuth == "function")
{
initOAuth({
clientId: "your-client-id",
clientSecret: "your-client-secret-if-required",
realm: "your-realms",
appName: "your-app-name",
scopeSeparator: ",",
additionalQueryStringParams: {}
});
}

if (window.SwaggerTranslator)
{
window.SwaggerTranslator.translate();
}

// addApiKeyAuthorization();
},
onFailure: function (data)
{
log("Unable to Load SwaggerUI");
},
docExpansion: "list",
jsonEditor: false,
apisSorter: "alpha",
defaultModelRendering: 'schema',
showRequestHeaders: true,
validatorUrl: null
});

function addApiKeyAuthorization()
{
var key = encodeURIComponent($('#input_apiKey')[0].value);
if (key && key.trim() != "")
{
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
log("added key " + key);
}
}

$('#input_apiKey').change(addApiKeyAuthorization);

// if you have an apiKey you would like to pre-populate on the page for demonstration purposes...
/*
var apiKey = "myApiKeyXXXX123456789";
$('#input_apiKey').val(apiKey);
*/
.swagger-ui .wrapper,
.swagger-ui .opblock-tag {
padding: 10;
}

window.swaggerUi.load();
.swagger-ui .info .title {
font-size: 25px;
font-weight: bold;
color: black;
}

function log()
{
if ('console' in window)
{
console.log.apply(console, arguments);
}
}
});
</script>
.topbar,
.swagger-ui .info span,
.swagger-ui .info .version,
.swagger-ui .scheme-container {
display: none !important;
height: 0;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>

<body class="swagger-section">
<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="${request.servletPath}">youcat API</a>
<!-- <form id='api_selector'>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
<div class='input'><a id="explore" href="#" data-sw-translate>Explore</a></div>
</form> -->
</div>
</div>

<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
<body>
<div id="swagger-ui"></div>
<script src='swagger-openapi/dist/swagger-ui-bundle.js' type='text/javascript'></script>
<script src='swagger-openapi/dist/swagger-ui-standalone-preset.js' type='text/javascript'></script>

<script>
window.onload = () => {
window.ui = SwaggerUIBundle({
url: "openapi.yaml",
dom_id: "#swagger-ui",
deepLinking: true,
validatorUrl: "none",
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
};
</script>
</body>
</html>
41 changes: 41 additions & 0 deletions youcat/src/main/webapp/openapi-base.yaml
Original file line number Diff line number Diff line change
@@ -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


Loading
Loading