Skip to content

Commit

Permalink
Added results servlet
Browse files Browse the repository at this point in the history
  • Loading branch information
stvoutsin committed Jun 24, 2024
1 parent 85a66e0 commit 077ce08
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ lsst-tap-service is versioned with [semver](https://semver.org/). Dependencies a
Find changes for the upcoming release in the project's [changelog.d](https://github.com/lsst-sqre/lsst-tap-service/tree/main/changelog.d/).

<!-- scriv-insert-here -->
# 2024-06-24

## Other Changes

- Change result handling, to use a redirect servlet. Addresses issue with async failing due to auth header propagation with clients like pyvo, topcat

# 2024-06-18

Expand Down
9 changes: 6 additions & 3 deletions src/main/java/org/opencadc/tap/impl/ResultStoreImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ public class ResultStoreImpl implements ResultStore {
private static final String bucket = System.getProperty("gcs_bucket");
private static final String bucketURL = System.getProperty("gcs_bucket_url");
private static final String bucketType = System.getProperty("gcs_bucket_type");

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,
Expand Down Expand Up @@ -166,11 +167,13 @@ private OutputStream getOutputStreamGCS() {
}

private URL getURL() throws MalformedURLException {
String filepath = "";
if (bucketType.equals(new String("S3"))) {
return new URL(new URL(bucketURL), "/"+bucket+"/"+filename);
filepath = "/" + bucket + "/" + filename;
} else {
return new URL(new URL(bucketURL), filename);
filepath = filename;
}
return new URL(baseURL + pathPrefix + "/results/" + filepath);
}

private URI getURI() {
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/org/opencadc/tap/impl/ResultsServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.opencadc.tap.impl;

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;
}
}
10 changes: 10 additions & 0 deletions src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@
<load-on-startup>3</load-on-startup>
</servlet>

<servlet>
<servlet-name>ResultsServlet</servlet-name>
<servlet-class>org.opencadc.tap.impl.ResultsServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>ResultsServlet</servlet-name>
<url-pattern>/results/*</url-pattern>
</servlet-mapping>

<!-- the TAP Endpoints -->
<servlet-mapping>
<servlet-name>AsyncServlet</servlet-name>
Expand Down
66 changes: 66 additions & 0 deletions src/test/java/org/opencadc/tap/impl/ResultsServletTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.opencadc.tap.impl;

import ca.nrc.cadc.tap.schema.ColumnDesc;
import ca.nrc.cadc.tap.schema.SchemaDesc;
import ca.nrc.cadc.tap.schema.TableDesc;
import ca.nrc.cadc.tap.schema.TapDataType;
import ca.nrc.cadc.tap.schema.TapSchema;
import ca.nrc.cadc.util.Log4jInit;
import ca.nrc.cadc.uws.Job;
import ca.nrc.cadc.uws.Parameter;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method;

public class ResultsServletTest {

private static final Logger log = Logger.getLogger(ResultsServletTest.class);

static
{
Log4jInit.setLevel("org.opencadc.tap.impl", Level.INFO);

}

Job job = new Job()
{
@Override
public String getID() { return "testJob"; }
};

public ResultsServletTest() { }

@Test
public void testGenerateRedirectUrl() throws Exception {
String bucketUrl = "https://tap-files.lsst.codes";
String expectedUrl = "https://tap-files.lsst.codes/result_qz4z5hf6qy5509p1.xml";
ResultsServlet resultsServlet = new ResultsServlet();
resultsServlet.init();
String path = "/result_qz4z5hf6qy5509p1.xml";

Method method = ResultsServlet.class.getDeclaredMethod("generateRedirectUrl", String.class, String.class);
method.setAccessible(true);
String actualUrl = (String) method.invoke(resultsServlet, bucketUrl, path);

assertEquals(expectedUrl, actualUrl);
}

@Test
public void testGenerateRedirectUrlWithBucket() throws Exception {
String bucketUrl = "https://tap-files.lsst.codes";
String expectedUrl = "https://tap-files.lsst.codes/bucket12345/result_qz4z5hf6qy5509p1.xml";
ResultsServlet resultsServlet = new ResultsServlet();
resultsServlet.init();
String path = "/bucket12345/result_qz4z5hf6qy5509p1.xml";

Method method = ResultsServlet.class.getDeclaredMethod("generateRedirectUrl", String.class, String.class);
method.setAccessible(true);
String actualUrl = (String) method.invoke(resultsServlet, bucketUrl, path);

assertEquals(expectedUrl, actualUrl);
}

}

0 comments on commit 077ce08

Please sign in to comment.