diff --git a/CHANGELOG.md b/CHANGELOG.md index e90643e..0a296fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ Find changes for the upcoming release in the project's [changelog.d](https://git + +## 1.18.0 (2024-06-24) + +### Changed + +- Change result handling, to use a redirect servlet. Addresses issue with async failing due to auth header propagation with clients like pyvo, topcat + + ## 1.17.3 (2024-06-18) diff --git a/tap/src/main/java/ca/nrc/cadc/sample/AuthenticatorImpl.java b/tap/src/main/java/ca/nrc/cadc/sample/AuthenticatorImpl.java index 3ff799f..a3f2839 100644 --- a/tap/src/main/java/ca/nrc/cadc/sample/AuthenticatorImpl.java +++ b/tap/src/main/java/ca/nrc/cadc/sample/AuthenticatorImpl.java @@ -29,14 +29,10 @@ 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. - * - * @author cbanek + * @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 */ +@Deprecated public class AuthenticatorImpl implements Authenticator { private static final Logger log = Logger.getLogger(AuthenticatorImpl.class); diff --git a/tap/src/main/java/ca/nrc/cadc/sample/ResultStoreImpl.java b/tap/src/main/java/ca/nrc/cadc/sample/ResultStoreImpl.java index 0298e23..7149a04 100644 --- a/tap/src/main/java/ca/nrc/cadc/sample/ResultStoreImpl.java +++ b/tap/src/main/java/ca/nrc/cadc/sample/ResultStoreImpl.java @@ -1,4 +1,3 @@ - /* ************************************************************************ ******************* CANADIAN ASTRONOMY DATA CENTRE ******************* @@ -94,7 +93,8 @@ public class ResultStoreImpl implements ResultStore { private String filename; private static final String bucket = System.getProperty("gcs_bucket"); private static final String bucketURL = System.getProperty("gcs_bucket_url"); - + private static final String baseURL = System.getProperty("base_url"); + private static final String pathPrefix = System.getProperty("path_prefix"); @Override public URL put(final ResultSet resultSet, @@ -135,14 +135,14 @@ public URL put(final ResultSet resultSet, private OutputStream getOutputStream() { Storage storage = StorageOptions.getDefaultInstance().getService(); BlobId blobId = BlobId.of(bucket, filename); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("application/x-votable+xml").build(); Blob blob = storage.create(blobInfo); return Channels.newOutputStream(blob.writer()); } private URL getURL() throws MalformedURLException { - URL bucket = new URL(bucketURL); - return new URL(bucket, filename); + return new URL(baseURL + pathPrefix + "/results/" + filename); } @Override @@ -157,4 +157,5 @@ public void setJob(Job _job) { public void setFilename(String filename) { this.filename = filename; } + } diff --git a/tap/src/main/java/ca/nrc/cadc/sample/ResultsServlet.java b/tap/src/main/java/ca/nrc/cadc/sample/ResultsServlet.java new file mode 100644 index 0000000..f18d0b4 --- /dev/null +++ b/tap/src/main/java/ca/nrc/cadc/sample/ResultsServlet.java @@ -0,0 +1,50 @@ +package ca.nrc.cadc.sample; + +import org.apache.log4j.Logger; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * A servlet that handles redirecting to specific job results. + * This servlet extracts the VOTable file name from the request path and constructs a URL to redirect the client. + * + * @author stvoutsin + */ +public class ResultsServlet extends HttpServlet { + private static final Logger log = Logger.getLogger(ResultsServlet.class); + private static final String bucketURL = System.getProperty("gcs_bucket_url"); + + /** + * Processes GET requests by extracting the result filename from the request path and redirecting to the corresponding results URL. + * The filename is assumed to be the path info of the request URL, following the first '/' character. + * + * @param request the HttpServletRequest object that contains the request + * @param response the HttpServletResponse object that contains the response + * @throws ServletException if an input or output error is detected when the servlet handles the GET request + * @throws IOException if the request for the GET could not be handled + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + String path = request.getPathInfo(); + String redirectUrl = generateRedirectUrl(bucketURL, path); + response.sendRedirect(redirectUrl); + } catch (Exception e) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An error occurred while processing the request."); + } + } + + /** + * Generates the redirect URL based on a path. + * + * @param path the request path + * @return the redirect URL constructed using the bucket URL and results file + */ + private String generateRedirectUrl(String bucketUrlString, String path) { + String resultsFile = path.substring(1); + return bucketUrlString + "/" + resultsFile; + } +} diff --git a/tap/src/main/webapp/WEB-INF/web.xml b/tap/src/main/webapp/WEB-INF/web.xml index 71a4aa6..1e0b550 100644 --- a/tap/src/main/webapp/WEB-INF/web.xml +++ b/tap/src/main/webapp/WEB-INF/web.xml @@ -193,6 +193,17 @@ SyncServlet /sync/* + + + ResultsServlet + ca.nrc.cadc.sample.ResultsServlet + + + + ResultsServlet + /results/* + + AsyncServlet /async/*