diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..fde83dd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,25 @@ +# Change log + +lsst-tap-service is versioned with [semver](https://semver.org/). Dependencies are updated to the latest available version during each release. Those changes are not noted here explicitly. + +Find changes for the upcoming release in the project's [changelog.d](https://github.com/lsst-sqre/lsst-tap-service/tree/main/changelog.d/). + + + +# 2024-06-11 + +## New features + +- Added UWSInitAction class to initialise a UWS database +- Added scriv changelogs + +## Other Changes + +- Changed the build.gradle to use fixed version of the latest cadc libs +- Changed Dockerfile for lsst-tap-service to use cadc-tomcat base image +- Deprecated AuthenticatorImpl class + +## Bug Fixes + +- Fixed capabilities output (securityMethods) + diff --git a/build.gradle b/build.gradle index 460a5bc..a791b62 100644 --- a/build.gradle +++ b/build.gradle @@ -40,16 +40,27 @@ configurations { } dependencies { - implementation 'log4j:log4j:[1.2,2.0)' - implementation 'org.opencadc:cadc-log:[1.0,)' - implementation 'org.opencadc:cadc-util:[1.2,)' - implementation 'org.opencadc:cadc-dali:[1.1,)' - implementation 'org.opencadc:cadc-uws:[1.0,)' - implementation 'org.opencadc:cadc-uws-server:[1.2,)' - implementation 'org.opencadc:cadc-tap-server:[1.1.5,)' - implementation 'org.opencadc:cadc-vosi:[1.4.1,)' - implementation 'org.opencadc:cadc-adql:[1.1.13,)' - implementation 'org.opencadc:cadc-tap-server-oracle:[1.0.0,)' + implementation 'log4j:log4j:1.2.+' + implementation 'org.opencadc:cadc-adql:1.1.13' + implementation 'org.opencadc:cadc-cdp:1.3.7' + implementation 'org.opencadc:cadc-dali:1.2.17' + implementation 'org.opencadc:cadc-dali-pg:0.3.1' + implementation 'org.opencadc:cadc-gms:1.0.12' + implementation 'org.opencadc:cadc-jsqlparser-compat:0.6.5' + implementation 'org.opencadc:cadc-log:1.2.1' + implementation 'org.opencadc:cadc-registry:1.7.6' + implementation 'org.opencadc:cadc-rest:1.3.18' + implementation 'org.opencadc:cadc-tap:1.1.16' + implementation 'org.opencadc:cadc-tap-schema:1.1.32' + implementation 'org.opencadc:cadc-tap-server:1.1.23' + implementation 'org.opencadc:cadc-tap-server-pg:1.0.5' + implementation 'org.opencadc:cadc-tap-server-oracle:1.2.11' + implementation 'org.opencadc:cadc-util:1.10.6' + implementation 'org.opencadc:cadc-uws:1.0.5' + implementation 'org.opencadc:cadc-uws-server:1.2.20' + implementation 'org.opencadc:cadc-tap-server:1.1.23' + implementation 'org.opencadc:cadc-vosi:1.4.4' + implementation 'org.opencadc:cadc-adql:1.1.13' // Switch out this to use any supported database instead of PostgreSQL. // ## START CUSTOM DATABASE ## diff --git a/changelog.d/_template.md.jinja b/changelog.d/_template.md.jinja new file mode 100644 index 0000000..6e644b8 --- /dev/null +++ b/changelog.d/_template.md.jinja @@ -0,0 +1,7 @@ + +{%- for cat in config.categories %} + +### {{ cat }} + +- +{%- endfor %} diff --git a/changelog.d/scriv.ini b/changelog.d/scriv.ini new file mode 100644 index 0000000..e452bca --- /dev/null +++ b/changelog.d/scriv.ini @@ -0,0 +1,3 @@ +[scriv] +format = md +categories = Backwards-incompatible changes,New features,Bug fixes,Other changes diff --git a/docker/Dockerfile.lsst-tap-service b/docker/Dockerfile.lsst-tap-service index d670ac0..a2b7b9a 100644 --- a/docker/Dockerfile.lsst-tap-service +++ b/docker/Dockerfile.lsst-tap-service @@ -1,10 +1,15 @@ -FROM tomcat:9.0 +FROM images.opencadc.org/library/cadc-tomcat:1 -RUN rm -rf webapps/* +LABEL org.opencontainers.image.source = "https://github.com/lsst-sqre/lsst-tap-service" -RUN apt-get update && apt-get install -y zip unzip +RUN dnf update -y && dnf install -y zip unzip +# Copy start into container and set permissions ADD docker/start.sh /usr/local/bin/ -ADD docker/*.war webapps/ +RUN chmod +x /usr/local/bin/start.sh -CMD ["start.sh"] +# Copy war into tomcat webapps +ADD docker/*.war /usr/share/tomcat/webapps/ + +# Run the start script to handle the datalink task +RUN /usr/local/bin/start.sh diff --git a/docker/start.sh b/docker/start.sh index 12845a5..5ea4e56 100755 --- a/docker/start.sh +++ b/docker/start.sh @@ -6,5 +6,3 @@ if [ -n "$DATALINK_PAYLOAD_URL" ]; then curl -L "$DATALINK_PAYLOAD_URL" -o /tmp/datalink_payload.zip unzip /tmp/datalink_payload.zip -d /tmp/datalink fi - -exec catalina.sh run diff --git a/src/main/java/org/opencadc/tap/impl/AuthenticatorImpl.java b/src/main/java/org/opencadc/tap/impl/AuthenticatorImpl.java index 23b96f8..22374fa 100644 --- a/src/main/java/org/opencadc/tap/impl/AuthenticatorImpl.java +++ b/src/main/java/org/opencadc/tap/impl/AuthenticatorImpl.java @@ -29,14 +29,12 @@ import org.apache.log4j.Logger; /** - * Implementes the Authenticator for processing Gafaelfawr auth, - * and using it to authenticate against the TAP service. - * - * The token in the authorization header is used to make a call - * to Gafaelfawr to retrieve details such as the uid and uidNumber. - * + * @deprecated This class is deprecated and will be removed in future releases. + * The TAP Service now uses IdentityManager for authentication, available in the opencadc library + * * @author cbanek */ +@Deprecated public class AuthenticatorImpl implements Authenticator { private static final Logger log = Logger.getLogger(AuthenticatorImpl.class); diff --git a/src/main/java/org/opencadc/tap/impl/UWSInitAction.java b/src/main/java/org/opencadc/tap/impl/UWSInitAction.java new file mode 100644 index 0000000..f28dcdb --- /dev/null +++ b/src/main/java/org/opencadc/tap/impl/UWSInitAction.java @@ -0,0 +1,156 @@ +/* +************************************************************************ +******************* CANADIAN ASTRONOMY DATA CENTRE ******************* +************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** +* +* (c) 2022. (c) 2022. +* Government of Canada Gouvernement du Canada +* National Research Council Conseil national de recherches +* Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 +* All rights reserved Tous droits réservés +* +* NRC disclaims any warranties, Le CNRC dénie toute garantie +* expressed, implied, or énoncée, implicite ou légale, +* statutory, of any kind with de quelque nature que ce +* respect to the software, soit, concernant le logiciel, +* including without limitation y compris sans restriction +* any warranty of merchantability toute garantie de valeur +* or fitness for a particular marchande ou de pertinence +* purpose. NRC shall not be pour un usage particulier. +* liable in any event for any Le CNRC ne pourra en aucun cas +* damages, whether direct or être tenu responsable de tout +* indirect, special or general, dommage, direct ou indirect, +* consequential or incidental, particulier ou général, +* arising from the use of the accessoire ou fortuit, résultant +* software. Neither the name de l'utilisation du logiciel. Ni +* of the National Research le nom du Conseil National de +* Council of Canada nor the Recherches du Canada ni les noms +* names of its contributors may de ses participants ne peuvent +* be used to endorse or promote être utilisés pour approuver ou +* products derived from this promouvoir les produits dérivés +* software without specific prior de ce logiciel sans autorisation +* written permission. préalable et particulière +* par écrit. +* +* This file is part of the Ce fichier fait partie du projet +* OpenCADC project. OpenCADC. +* +* OpenCADC is free software: OpenCADC est un logiciel libre ; +* you can redistribute it and/or vous pouvez le redistribuer ou le +* modify it under the terms of modifier suivant les termes de +* the GNU Affero General Public la "GNU Affero General Public +* License as published by the License" telle que publiée +* Free Software Foundation, par la Free Software Foundation +* either version 3 of the : soit la version 3 de cette +* License, or (at your option) licence, soit (à votre gré) +* any later version. toute version ultérieure. +* +* OpenCADC is distributed in the OpenCADC est distribué +* hope that it will be useful, dans l’espoir qu’il vous +* but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE +* without even the implied GARANTIE : sans même la garantie +* warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ +* or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF +* PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence +* General Public License for Générale Publique GNU Affero +* more details. pour plus de détails. +* +* You should have received Vous devriez avoir reçu une +* a copy of the GNU Affero copie de la Licence Générale +* General Public License along Publique GNU Affero avec +* with OpenCADC. If not, see OpenCADC ; si ce n’est +* . pas le cas, consultez : +* . +* +************************************************************************ +*/ + +package org.opencadc.tap.impl; + +import ca.nrc.cadc.db.DBUtil; +import ca.nrc.cadc.rest.InitAction; +import ca.nrc.cadc.uws.server.impl.InitDatabaseUWS; +import javax.sql.DataSource; +import org.apache.log4j.Logger; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * + * @author pdowler + */ +public class UWSInitAction extends InitAction { + private static final Logger log = Logger.getLogger(UWSInitAction.class); + + public UWSInitAction() { + } + + @Override + public void doInit() { + DataSource uws = null; + try { + uws = DBUtil.findJNDIDataSource("jdbc/uws"); + if (!schemaExists(uws, "uws")) { + log.info("uws schema does not exist, creating..."); + createSchema(uws, "uws"); + log.info("uws schema created"); + // Continue with initialization only if the schema was just created + InitDatabaseUWS uwsi = new InitDatabaseUWS(uws, null, "uws"); + uwsi.doInit(); + log.info("init uws: OK"); + } else { + log.info("uws schema already exists"); + return; // Exit the method early if the schema already exists + } + } catch (Exception ex) { + throw new RuntimeException("INIT FAIL", ex); + } + } + + private boolean schemaExists(DataSource uws, String schemaName) throws SQLException { + Connection conn = null; + try { + conn = uws.getConnection(); + DatabaseMetaData dbMetaData = conn.getMetaData(); + ResultSet rs = dbMetaData.getSchemas(); + while (rs.next()) { + if (schemaName.equalsIgnoreCase(rs.getString("TABLE_SCHEM").trim())) { + return true; + } + } + } catch (Exception ex) { + throw new RuntimeException("Failed to check if schema exists", ex); + } finally { + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + log.error("Failed to close connection", e); + } + } + } + return false; + } + + private void createSchema(DataSource uws, String schemaName) throws SQLException { + Connection conn = null; + try { + conn = uws.getConnection(); + java.sql.Statement stmt = conn.createStatement(); + stmt.execute("CREATE SCHEMA " + schemaName); + } catch (Exception ex) { + throw new RuntimeException("Create Schema failed", ex); + } finally { + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + log.error("Failed to close connection", e); + } + } + } + } +} \ No newline at end of file diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml index f664e8b..2e1fc77 100644 --- a/src/main/webapp/META-INF/context.xml +++ b/src/main/webapp/META-INF/context.xml @@ -41,7 +41,7 @@ type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" minEvictableIdleTimeMillis="30000" - maxActive="1" maxIdle="1" maxWait="20000" initialSize="1" minIdle="1" + maxActive="${uws.maxActive}" maxIdle="1" maxWait="20000" initialSize="5" minIdle="1" username="${uws.username}" password="${uws.password}" driverClassName="${uws.driverClassName}" url="${uws.url}" @@ -49,6 +49,6 @@ removeAbandonedTimeout="600" logAbandoned="true" testOnBorrow="true" - validationQuery="SELECT 1 FROM JobAvailability" + validationQuery="SELECT 1" /> diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 1e5847c..d4cf863 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -59,6 +59,10 @@ 2 SyncServlet ca.nrc.cadc.uws.server.JobServlet + + init + org.opencadc.tap.impl.UWSInitAction + get ca.nrc.cadc.uws.web.SyncGetAction @@ -67,7 +71,6 @@ post ca.nrc.cadc.uws.web.SyncPostAction - ca.nrc.cadc.uws.server.JobManager org.opencadc.tap.ws.QueryJobManager diff --git a/src/main/webapp/capabilities.xml b/src/main/webapp/capabilities.xml index 3ec711a..298b3ca 100644 --- a/src/main/webapp/capabilities.xml +++ b/src/main/webapp/capabilities.xml @@ -1,8 +1,8 @@ + xmlns:vosi="http://www.ivoa.net/xml/VOSICapabilities/v1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:vs="http://www.ivoa.net/xml/VODataService/v1.1"> @@ -19,151 +19,94 @@ https://replace.me.com/api/tap/logControl + + + + + - https://replace.me.com/api/tap/tables - - - https://replace.me.com/api/tap/auth-tables - - - - https://replace.me.com/api/tap/tables + https://replace.me.com/api/tap/tables + - - - https://replace.me.com/api/tap/tables - + + + + xmlns:tr="http://www.ivoa.net/xml/TAPRegExt/v1.0" xsi:type="tr:TableAccess"> - https://example.net/api/tap - - - - https://example.net/api/tap/async - - - https://example.net/api/tap/auth-async - - - - https://example.net/api/tap/async - - - - https://example.net/api/tap/async - - - - - https://example.net/api/tap/sync - - - https://example.net/api/tap/auth-sync - - - - https://example.net/api/tap/sync - - - - https://example.net/api/tap/sync - + https://replace.me.com/api/tap + + + + + - - + ObsCore-1.1 - ADQL - 2.0 - ADQL-2.0 - - -
POINT
-
- -
CIRCLE
-
- -
DISTANCE
-
- -
POLYGON
-
- -
CONTAINS
-
- -
+ ADQL + 2.0 + ADQL-2.0 + + +
POINT
+
+ +
CIRCLE
+
+ +
DISTANCE
+
+ +
POLYGON
+
+ +
CONTAINS
+
+ +
- - application/x-votable+xml - votable + application/x-votable+xml + votable - - text/xml + text/xml - - text/csv - csv + text/csv + csv - - text/tab-separated-values - tsv + text/tab-separated-values + tsv - - - 604800 - 604800 + 604800 + 604800 - - 600 - 600 + 600 + 600 - - 134217728 - 134217728 + 134217728 + 134217728 - - 10000 - 10000 + 10000 + 10000 -
-