diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 515c5e7..d87598f 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -49,11 +49,13 @@ jobs:
sam build --use-container
sam local invoke WDLParsingFunction -e events/event.json &> output.txt
grep "statusCode\": 200" output.txt
- - name: Test Nextflow parsing with SAM CLI build (no invoke)
+ - name: Test Nextflow parsing with SAM CLI build and invoke
working-directory: ./nextflow-parsing
# SAM build also runs the Java tests
run: |
sam build --use-container
+ sam local invoke HelloWorldFunction -e events/sarek.json &> output.txt
+ grep "statusCode\": 200" output.txt
- name: Build CWL packing with SAM CLI build (no invoke, no test)
working-directory: ./cwlpack
run: sam build --use-container
diff --git a/CLAUDE.md b/CLAUDE.md
index 35df70d..3cb57ba 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -11,7 +11,7 @@ A monorepo of small, independent AWS Lambda functions used by Dockstore ("backup
| `checkUrlExists/` | Node 22 (`lambda/index.js`) | Checks a URL (http/https/ftp/sftp) is reachable; always returns 200, body is true/false |
| `cwlpack/` | Python 3.12 (`cwl_pack_function/app.py`) | Clones a git repo with pygit2 and packs a CWL descriptor with sbpack |
| `wdl-parsing/` | Java 21 (`WDLParsingFunction`, Maven) | Parses WDL descriptors |
-| `nextflow-parsing/` | Java 11 template (`NextflowParsingFunction`, Maven) | Parses Nextflow descriptors |
+| `nextflow-parsing/` | Java 21 (`NextflowParsingFunction`, Maven) | Parses Nextflow descriptors |
| `cloud-watch-to-slack-testing/`, `upsertGitHubTag/` | Node (`deployment/index.js`) | Not SAM; zipped and uploaded to S3 by CircleCI. `upsertGitHubTag` relays API Gateway -> SQS -> Lambda -> Dockstore webservice |
## Commands
@@ -59,7 +59,10 @@ When creating a PR, always create it in draft mode. A human developer must be th
review/move it out of draft state — Claude Code should not do this itself.
Always check with the user before pushing changes to GitHub, even to a branch/PR already being worked on in
-the conversation — a push can kick off a long CI build or interrupt one that's already running.
+the conversation — a push can kick off a long CI build or interrupt one that's already running. Before asking,
+show the user what would be pushed (e.g. `git log` and `git diff` against the remote branch) so they can review
+it first. An earlier "push" request does not cover later commits, and a force-push (e.g. after a rebase)
+always needs explicit approval.
When a GitHub MCP server or `gh` is available, diff the current work against `develop` (or whatever branch the
PR targets) and try to minimize stylistic or otherwise-minor changes that inflate the diff and make it harder
diff --git a/nextflow-parsing/NextflowParsingFunction/ignore.xml b/nextflow-parsing/NextflowParsingFunction/ignore.xml
index d9492e9..242c9a5 100644
--- a/nextflow-parsing/NextflowParsingFunction/ignore.xml
+++ b/nextflow-parsing/NextflowParsingFunction/ignore.xml
@@ -13,4 +13,9 @@
+
+
+
+
+
diff --git a/nextflow-parsing/NextflowParsingFunction/pom.xml b/nextflow-parsing/NextflowParsingFunction/pom.xml
index 6106ef1..3077fbc 100644
--- a/nextflow-parsing/NextflowParsingFunction/pom.xml
+++ b/nextflow-parsing/NextflowParsingFunction/pom.xml
@@ -8,11 +8,11 @@
jar
Nextflow parser created for SAM CLI.
- 3.0.0-M5
- 11
- 11
- 5.7.2
- 2.34
+ 3.5.3
+ 21
+ 21
+ 5.9.1
+ 3.1.11
2.22.3
@@ -43,7 +43,7 @@
org.eclipse.jgit
org.eclipse.jgit
- 5.13.4.202507202350-r
+ 7.8.0.202609011348-r
@@ -56,17 +56,17 @@
jakarta.ws.rs
jakarta.ws.rs-api
- 2.1.6
+ 3.1.0
aws-lambda-java-core
com.amazonaws
- 1.2.1
+ 1.4.0
aws-lambda-java-events
com.amazonaws
- 3.6.0
+ 3.16.1
org.junit.jupiter
@@ -83,28 +83,35 @@
org.slf4j
slf4j-api
- 1.7.31
+ 2.0.18
com.google.guava
guava
- 32.0.0-jre
+ 33.6.0-jre
- org.codehaus.groovy
+ org.apache.groovy
groovy
- 3.0.8
+ 4.0.26
io.dockstore
openapi-java-client
- 1.12.0
+ 1.20.0
compile
io.nextflow
nextflow
- 21.04.3
+ 25.04.4
+
+
+
+ io.seqera
+ lib-trace
+
+
@@ -135,7 +142,7 @@
org.apache.maven.plugins
- 3.2.0
+ 3.6.1
spotbugs-maven-plugin
@@ -150,13 +157,14 @@
com.github.spotbugs
- 4.0.4
+ 4.8.3.1
maven-checkstyle-plugin
-
- https://raw.githubusercontent.com/dockstore/lambda/a6ae4d98592b0d057c495bdb7b40c54e062ff998/wdl-parsing/WDLParsingFunction/checkstyle.xml
+
+ https://raw.githubusercontent.com/dockstore/dockstore/1.20.0/checkstyle.xml
+ https://raw.githubusercontent.com/dockstore/dockstore/1.20.0/checkstyle-suppressions.xml
true
true
true
@@ -165,7 +173,7 @@
checkstyle
com.puppycrawl.tools
- 8.34
+ 10.0
@@ -182,6 +190,11 @@
fmt-maven-plugin
+
+
+
+ true
+
@@ -189,8 +202,8 @@
- com.coveo
- 2.10
+ com.spotify.fmt
+ 2.29
maven-shade-plugin
@@ -210,10 +223,10 @@
maven-compiler-plugin
org.apache.maven.plugins
- 3.8.1
+ 3.12.1
- 11
- 11
+ 21
+ 21
diff --git a/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/App.java b/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/App.java
index e525c17..3ae2f40 100644
--- a/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/App.java
+++ b/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/App.java
@@ -24,6 +24,7 @@
import io.dockstore.openapi.client.model.LanguageParsingRequest;
import io.dockstore.openapi.client.model.LanguageParsingResponse;
import io.dockstore.openapi.client.model.VersionTypeValidation;
+import jakarta.ws.rs.core.MediaType;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
@@ -35,7 +36,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.ws.rs.core.MediaType;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.slf4j.Logger;
@@ -43,122 +43,122 @@
/** Handler for requests to Lambda function. */
public class App
- implements RequestHandler {
+ implements RequestHandler {
- private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
- ObjectMapper mapper = new ObjectMapper();
+ private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
+ ObjectMapper mapper = new ObjectMapper();
- /**
- * Get a language parsing response from NextflowHandler.
- *
- * @param nextflowHandler NextflowHandler that contains all relevant Nextflow information
- * @return LanguageParsingResponse constructed after getting information from NextflowHandler
- */
- public static LanguageParsingResponse getResponse(NextflowHandler nextflowHandler) {
- LanguageParsingResponse response = new LanguageParsingResponse();
- String descriptorAbsolutePathString = nextflowHandler.getDescriptorTempAbsolutePath();
- response.setClonedRepositoryAbsolutePath(descriptorAbsolutePathString);
- VersionTypeValidation versionTypeValidation = nextflowHandler.getVersionTypeValidation();
- if (nextflowHandler.getDescriptorContents() == null) {
- versionTypeValidation.setValid(false);
- Map messageMap = new HashMap<>();
- // TODO: Don't use temp absolute path
- messageMap.put(nextflowHandler.getDescriptorTempAbsolutePath(), "File not found");
- versionTypeValidation.setMessage(messageMap);
- }
- if (nextflowHandler.getConfiguration() == null) {
- versionTypeValidation.setValid(false);
+ /**
+ * Get a language parsing response from NextflowHandler.
+ *
+ * @param nextflowHandler NextflowHandler that contains all relevant Nextflow information
+ * @return LanguageParsingResponse constructed after getting information from NextflowHandler
+ */
+ public static LanguageParsingResponse getResponse(NextflowHandler nextflowHandler) {
+ LanguageParsingResponse response = new LanguageParsingResponse();
+ String descriptorAbsolutePathString = nextflowHandler.getDescriptorTempAbsolutePath();
+ response.setClonedRepositoryAbsolutePath(descriptorAbsolutePathString);
+ VersionTypeValidation versionTypeValidation = nextflowHandler.getVersionTypeValidation();
+ if (nextflowHandler.getDescriptorContents() == null) {
+ versionTypeValidation.setValid(false);
+ Map messageMap = new HashMap<>();
+ // TODO: Don't use temp absolute path
+ messageMap.put(nextflowHandler.getDescriptorTempAbsolutePath(), "File not found");
+ versionTypeValidation.setMessage(messageMap);
+ }
+ if (nextflowHandler.getConfiguration() == null) {
+ versionTypeValidation.setValid(false);
+ }
+ // TODO: This should be an array, don't join
+ response.setAuthor(
+ String.join(
+ ", ", NextflowUtilities.getAuthors(nextflowHandler.getConfiguration())));
+ response.setDescription(
+ NextflowUtilities.getDescription(nextflowHandler.getConfiguration()));
+ versionTypeValidation.setValid(true);
+ response.setVersionTypeValidation(versionTypeValidation);
+ response.setSecondaryFilePaths(nextflowHandler.getSecondaryDescriptorPaths());
+ return response;
}
- // TODO: This should be an array, don't join
- response.setAuthor(
- String.join(", ", NextflowUtilities.getAuthors(nextflowHandler.getConfiguration())));
- response.setDescription(NextflowUtilities.getDescription(nextflowHandler.getConfiguration()));
- versionTypeValidation.setValid(true);
- response.setVersionTypeValidation(versionTypeValidation);
- response.setSecondaryFilePaths(nextflowHandler.getSecondaryDescriptorPaths());
- return response;
- }
- @Override
- public APIGatewayProxyResponseEvent handleRequest(
- final APIGatewayProxyRequestEvent input, final Context context) {
+ @Override
+ public APIGatewayProxyResponseEvent handleRequest(
+ final APIGatewayProxyRequestEvent input, final Context context) {
- Map headers = new HashMap<>();
- headers.put("Content-Type", MediaType.APPLICATION_JSON);
+ Map headers = new HashMap<>();
+ headers.put("Content-Type", MediaType.APPLICATION_JSON);
- APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent().withHeaders(headers);
- if (input != null && input.getBody() != null) {
- try {
- LanguageParsingRequest request =
- mapper.readValue(input.getBody(), LanguageParsingRequest.class);
- try {
- String s = parseFile(request);
- return response.withStatusCode(HttpURLConnection.HTTP_OK).withBody(s);
- } catch (IOException e) {
- String errorMessage = "Could not clone repository to temporary directory";
- LOGGER.error(errorMessage, e);
- return response
- .withBody(errorMessage)
- .withStatusCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
- } catch (GitAPIException e) {
- StringWriter sw = new StringWriter();
- e.printStackTrace(new PrintWriter(sw));
- String exceptionAsString = sw.toString();
- return response
- .withBody(exceptionAsString)
- .withStatusCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ APIGatewayProxyResponseEvent response =
+ new APIGatewayProxyResponseEvent().withHeaders(headers);
+ if (input != null && input.getBody() != null) {
+ try {
+ LanguageParsingRequest request =
+ mapper.readValue(input.getBody(), LanguageParsingRequest.class);
+ try {
+ String s = parseFile(request);
+ return response.withStatusCode(HttpURLConnection.HTTP_OK).withBody(s);
+ } catch (IOException e) {
+ String errorMessage = "Could not clone repository to temporary directory";
+ LOGGER.error(errorMessage, e);
+ return response.withBody(errorMessage)
+ .withStatusCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ } catch (GitAPIException e) {
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw));
+ String exceptionAsString = sw.toString();
+ return response.withBody(exceptionAsString)
+ .withStatusCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ }
+ } catch (IOException e) {
+ String errorMessage = "Could not process request";
+ LOGGER.error(errorMessage, e);
+ return response.withBody(errorMessage)
+ .withStatusCode(HttpURLConnection.HTTP_BAD_REQUEST);
+ }
+ } else {
+ return response.withBody("No body in request")
+ .withStatusCode(HttpURLConnection.HTTP_BAD_REQUEST);
}
- } catch (IOException e) {
- String errorMessage = "Could not process request";
- LOGGER.error(errorMessage, e);
- return response.withBody(errorMessage).withStatusCode(HttpURLConnection.HTTP_BAD_REQUEST);
- }
- } else {
- return response
- .withBody("No body in request")
- .withStatusCode(HttpURLConnection.HTTP_BAD_REQUEST);
}
- }
- private String parseFile(LanguageParsingRequest languageParsingRequest)
- throws IOException, GitAPIException {
- Path tempDirWithPrefix = Files.createTempDirectory("clonedRepository");
- Git.cloneRepository()
- .setCloneAllBranches(false)
- .setBranch(languageParsingRequest.getBranch())
- .setURI(languageParsingRequest.getUri())
- .setDirectory(tempDirWithPrefix.toFile())
- .call();
- Path descriptorAbsolutePath =
- tempDirWithPrefix.resolve(languageParsingRequest.getDescriptorRelativePathInGit());
- String descriptorAbsolutePathString = descriptorAbsolutePath.toString();
- NextflowHandler nextflowHandler = new NextflowHandler();
- nextflowHandler.setDescriptorTempAbsolutePath(descriptorAbsolutePathString);
- nextflowHandler.setConfiguration(
- NextflowUtilities.getConfig(new File(descriptorAbsolutePathString)));
- try {
- String s = Files.readString(Path.of(descriptorAbsolutePathString));
+ private String parseFile(LanguageParsingRequest languageParsingRequest)
+ throws IOException, GitAPIException {
+ Path tempDirWithPrefix = Files.createTempDirectory("clonedRepository");
+ Git.cloneRepository()
+ .setCloneAllBranches(false)
+ .setBranch(languageParsingRequest.getBranch())
+ .setURI(languageParsingRequest.getUri())
+ .setDirectory(tempDirWithPrefix.toFile())
+ .call();
+ Path descriptorAbsolutePath =
+ tempDirWithPrefix.resolve(languageParsingRequest.getDescriptorRelativePathInGit());
+ String descriptorAbsolutePathString = descriptorAbsolutePath.toString();
+ NextflowHandler nextflowHandler = new NextflowHandler();
+ nextflowHandler.setDescriptorTempAbsolutePath(descriptorAbsolutePathString);
+ nextflowHandler.setConfiguration(
+ NextflowUtilities.getConfig(new File(descriptorAbsolutePathString)));
+ try {
+ String s = Files.readString(Path.of(descriptorAbsolutePathString));
- nextflowHandler.setDescriptorContents(s);
- List strings =
- nextflowHandler.processImports(nextflowHandler.getDescriptorContents());
- nextflowHandler.setSecondaryDescriptorPaths(strings);
- } catch (IOException e) {
- LOGGER.error(e.getMessage());
- nextflowHandler.setDescriptorContents(null);
- }
- LanguageParsingResponse response = getResponse(nextflowHandler);
- response.setLanguageParsingRequest(languageParsingRequest);
- // Deleting a directory without Common IO
- Files.walk(tempDirWithPrefix)
- .sorted(Comparator.reverseOrder())
- .map(Path::toFile)
- .forEach(File::delete);
- if (response.getSecondaryFilePaths() != null) {
- response
- .getSecondaryFilePaths()
- .replaceAll(s -> s.replaceFirst(tempDirWithPrefix.toString(), ""));
+ nextflowHandler.setDescriptorContents(s);
+ List strings =
+ nextflowHandler.processImports(nextflowHandler.getDescriptorContents());
+ nextflowHandler.setSecondaryDescriptorPaths(strings);
+ } catch (IOException e) {
+ LOGGER.error(e.getMessage());
+ nextflowHandler.setDescriptorContents(null);
+ }
+ LanguageParsingResponse response = getResponse(nextflowHandler);
+ response.setLanguageParsingRequest(languageParsingRequest);
+ // Deleting a directory without Common IO
+ Files.walk(tempDirWithPrefix)
+ .sorted(Comparator.reverseOrder())
+ .map(Path::toFile)
+ .forEach(File::delete);
+ if (response.getSecondaryFilePaths() != null) {
+ response.getSecondaryFilePaths()
+ .replaceAll(s -> s.replaceFirst(tempDirWithPrefix.toString(), ""));
+ }
+ return mapper.writeValueAsString(response);
}
- return mapper.writeValueAsString(response);
- }
}
diff --git a/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/NextflowHandler.java b/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/NextflowHandler.java
index 1e895a9..8e601dd 100644
--- a/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/NextflowHandler.java
+++ b/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/NextflowHandler.java
@@ -32,113 +32,115 @@
public class NextflowHandler {
- private String descriptorContents;
- private String descriptorTempAbsolutePath;
- private ConfigObject configuration;
- private VersionTypeValidation versionTypeValidation = new VersionTypeValidation();
- private List secondaryDescriptorPaths;
- protected static final Pattern IMPORT_PATTERN =
- Pattern.compile("^\\s*include.+?from.+?'.+?'", Pattern.DOTALL | Pattern.MULTILINE);
- private static final Pattern INCLUDE_CONFIG_PATTERN =
- Pattern.compile("(?i)(?m)^[ \t]*includeConfig(.*)");
-
- public String getDescriptorTempAbsolutePath() {
- return descriptorTempAbsolutePath;
- }
-
- public void setDescriptorTempAbsolutePath(String descriptorTempAbsolutePath) {
- this.descriptorTempAbsolutePath = descriptorTempAbsolutePath;
- }
-
- public String getDescriptorContents() {
- return descriptorContents;
- }
-
- public void setDescriptorContents(String descriptorContents) {
- this.descriptorContents = descriptorContents;
- }
-
- /**
- * Get the relative path imports of the workflow.
- *
- * @param content The contents of the main descriptor file
- * @return
- */
- public List processImports(String content) {
- // FIXME: see{@link NextflowUtilities#grabConfig(String) grabConfig} method for comments on why
- // we have to look at imports in this crummy way
- final Matcher matcher = INCLUDE_CONFIG_PATTERN.matcher(content);
- Set suspectedConfigImports = new HashSet<>();
- while (matcher.find()) {
- suspectedConfigImports.add(CharMatcher.is('\'').trimFrom(matcher.group(1).trim()));
+ private String descriptorContents;
+ private String descriptorTempAbsolutePath;
+ private ConfigObject configuration;
+ private VersionTypeValidation versionTypeValidation = new VersionTypeValidation();
+ private List secondaryDescriptorPaths;
+ protected static final Pattern IMPORT_PATTERN =
+ Pattern.compile("^\\s*include.+?from.+?'.+?'", Pattern.DOTALL | Pattern.MULTILINE);
+ private static final Pattern INCLUDE_CONFIG_PATTERN =
+ Pattern.compile("(?i)(?m)^[ \t]*includeConfig(.*)");
+
+ public String getDescriptorTempAbsolutePath() {
+ return descriptorTempAbsolutePath;
}
- List imports = new ArrayList<>();
- // add the Nextflow scripts
- String mainScriptPath = "main.nf";
- String manifest = getManifest(configuration);
- if (manifest != null) {
- mainScriptPath = manifest;
+ public void setDescriptorTempAbsolutePath(String descriptorTempAbsolutePath) {
+ this.descriptorTempAbsolutePath = descriptorTempAbsolutePath;
}
- suspectedConfigImports.add(mainScriptPath);
-
- imports.addAll(handleNextflowImports("bin"));
- imports.addAll(handleNextflowImports("lib"));
- imports.addAll(suspectedConfigImports);
- return imports;
- }
-
- private String getManifest(ConfigObject configObject) {
- try {
- Map property = (Map) configObject.get("manifest");
- return (String) property.get("mainScript");
- } catch (Exception e) {
- return null;
+
+ public String getDescriptorContents() {
+ return descriptorContents;
+ }
+
+ public void setDescriptorContents(String descriptorContents) {
+ this.descriptorContents = descriptorContents;
+ }
+
+ /**
+ * Get the relative path imports of the workflow.
+ *
+ * @param content The contents of the main descriptor file
+ * @return
+ */
+ public List processImports(String content) {
+ // FIXME: see{@link NextflowUtilities#grabConfig(String) grabConfig} method for comments on
+ // why
+ // we have to look at imports in this crummy way
+ final Matcher matcher = INCLUDE_CONFIG_PATTERN.matcher(content);
+ Set suspectedConfigImports = new HashSet<>();
+ while (matcher.find()) {
+ suspectedConfigImports.add(CharMatcher.is('\'').trimFrom(matcher.group(1).trim()));
+ }
+ List imports = new ArrayList<>();
+
+ // add the Nextflow scripts
+ String mainScriptPath = "main.nf";
+ String manifest = getManifest(configuration);
+ if (manifest != null) {
+ mainScriptPath = manifest;
+ }
+ suspectedConfigImports.add(mainScriptPath);
+
+ imports.addAll(handleNextflowImports("bin"));
+ imports.addAll(handleNextflowImports("lib"));
+ imports.addAll(suspectedConfigImports);
+ return imports;
+ }
+
+ private String getManifest(ConfigObject configObject) {
+ try {
+ Map property = (Map) configObject.get("manifest");
+ return (String) property.get("mainScript");
+ } catch (Exception e) {
+ return null;
+ }
}
- }
-
- /**
- * Get relative file paths from directory.
- *
- * @param directory The directory to get files from
- * @return List of files relative to the main descriptor file
- */
- private List handleNextflowImports(String directory) {
- File binDirectory = Paths.get(descriptorTempAbsolutePath).resolveSibling(directory).toFile();
- List binFiles = new ArrayList<>();
- String[] binFileNames =
- binDirectory.list((current, name) -> !(new File(current, name).isDirectory()));
- if (binFileNames != null) {
- List binFileNamesList = List.of(binFileNames);
- binFiles =
- binFileNamesList.stream()
- .map(string -> directory + "/" + string)
- .collect(Collectors.toList());
+
+ /**
+ * Get relative file paths from directory.
+ *
+ * @param directory The directory to get files from
+ * @return List of files relative to the main descriptor file
+ */
+ private List handleNextflowImports(String directory) {
+ File binDirectory =
+ Paths.get(descriptorTempAbsolutePath).resolveSibling(directory).toFile();
+ List binFiles = new ArrayList<>();
+ String[] binFileNames =
+ binDirectory.list((current, name) -> !(new File(current, name).isDirectory()));
+ if (binFileNames != null) {
+ List binFileNamesList = List.of(binFileNames);
+ binFiles =
+ binFileNamesList.stream()
+ .map(string -> directory + "/" + string)
+ .collect(Collectors.toList());
+ }
+ return binFiles;
}
- return binFiles;
- }
- public ConfigObject getConfiguration() {
- return configuration;
- }
+ public ConfigObject getConfiguration() {
+ return configuration;
+ }
- public void setConfiguration(ConfigObject configuration) {
- this.configuration = configuration;
- }
+ public void setConfiguration(ConfigObject configuration) {
+ this.configuration = configuration;
+ }
- public VersionTypeValidation getVersionTypeValidation() {
- return this.versionTypeValidation;
- }
+ public VersionTypeValidation getVersionTypeValidation() {
+ return this.versionTypeValidation;
+ }
- public void setVersionTypeValidation(VersionTypeValidation versionTypeValidation) {
- this.versionTypeValidation = versionTypeValidation;
- }
+ public void setVersionTypeValidation(VersionTypeValidation versionTypeValidation) {
+ this.versionTypeValidation = versionTypeValidation;
+ }
- public List getSecondaryDescriptorPaths() {
- return secondaryDescriptorPaths;
- }
+ public List getSecondaryDescriptorPaths() {
+ return secondaryDescriptorPaths;
+ }
- public void setSecondaryDescriptorPaths(List secondaryDescriptorPaths) {
- this.secondaryDescriptorPaths = secondaryDescriptorPaths;
- }
+ public void setSecondaryDescriptorPaths(List secondaryDescriptorPaths) {
+ this.secondaryDescriptorPaths = secondaryDescriptorPaths;
+ }
}
diff --git a/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/NextflowUtilities.java b/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/NextflowUtilities.java
index fbed9ba..c57d8df 100644
--- a/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/NextflowUtilities.java
+++ b/nextflow-parsing/NextflowParsingFunction/src/main/java/io/dockstore/nextflowparsing/NextflowUtilities.java
@@ -22,51 +22,53 @@
import java.util.List;
import java.util.Map;
import nextflow.config.ConfigParser;
+import nextflow.config.ConfigParserFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class NextflowUtilities {
- private static final Logger LOG = LoggerFactory.getLogger(NextflowUtilities.class);
+ private static final Logger LOG = LoggerFactory.getLogger(NextflowUtilities.class);
- private NextflowUtilities() {
- // hide the default constructor for a utility class
- }
+ private NextflowUtilities() {
+ // hide the default constructor for a utility class
+ }
- /**
- * Get authors of the workflow.
- *
- * @param configuration The Nextflow configuration
- * @return
- */
- public static List getAuthors(ConfigObject configuration) {
- try {
- Map manifest = (Map) configuration.get("manifest");
- String author = (String) manifest.get("author");
- String[] authors = Arrays.stream(author.split(",")).map(String::trim).toArray(String[]::new);
- return Arrays.asList(authors);
- } catch (Exception e) {
- return null;
+ /**
+ * Get authors of the workflow.
+ *
+ * @param configuration The Nextflow configuration
+ * @return
+ */
+ public static List getAuthors(ConfigObject configuration) {
+ try {
+ Map manifest = (Map) configuration.get("manifest");
+ String author = (String) manifest.get("author");
+ String[] authors =
+ Arrays.stream(author.split(",")).map(String::trim).toArray(String[]::new);
+ return Arrays.asList(authors);
+ } catch (Exception e) {
+ return null;
+ }
}
- }
- /**
- * Get the description of the workflow.
- *
- * @param configuration The Nextflow configuration
- * @return
- */
- public static String getDescription(ConfigObject configuration) {
- try {
- Map manifest = (Map) configuration.get("manifest");
- return (String) manifest.get("description");
- } catch (Exception e) {
- return null;
+ /**
+ * Get the description of the workflow.
+ *
+ * @param configuration The Nextflow configuration
+ * @return
+ */
+ public static String getDescription(ConfigObject configuration) {
+ try {
+ Map manifest = (Map) configuration.get("manifest");
+ return (String) manifest.get("description");
+ } catch (Exception e) {
+ return null;
+ }
}
- }
- public static ConfigObject getConfig(File tempMainDescriptor) {
- ConfigParser configParser = new ConfigParser();
- return configParser.parse(tempMainDescriptor);
- }
+ public static ConfigObject getConfig(File tempMainDescriptor) {
+ ConfigParser configParser = ConfigParserFactory.create();
+ return configParser.parse(tempMainDescriptor);
+ }
}
diff --git a/nextflow-parsing/NextflowParsingFunction/src/test/java/io/dockstore/nextflowparsing/AppTest.java b/nextflow-parsing/NextflowParsingFunction/src/test/java/io/dockstore/nextflowparsing/AppTest.java
index 85c5ea8..aa22301 100644
--- a/nextflow-parsing/NextflowParsingFunction/src/test/java/io/dockstore/nextflowparsing/AppTest.java
+++ b/nextflow-parsing/NextflowParsingFunction/src/test/java/io/dockstore/nextflowparsing/AppTest.java
@@ -25,44 +25,45 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.dockstore.openapi.client.model.LanguageParsingRequest;
import io.dockstore.openapi.client.model.LanguageParsingResponse;
+import jakarta.ws.rs.core.MediaType;
import java.net.HttpURLConnection;
-import javax.ws.rs.core.MediaType;
import org.junit.jupiter.api.Test;
public class AppTest {
- @Test
- public void successfulResponse() throws Exception {
- LanguageParsingRequest request = new LanguageParsingRequest();
- request.setBranch("2.3");
- // Archived repository with tag that is unlikely to change
- request.setUri("https://github.com/SciLifeLab/Sarek.git");
- request.setDescriptorRelativePathInGit("nextflow.config");
- App app = new App();
- APIGatewayProxyRequestEvent requestEvent = new APIGatewayProxyRequestEvent();
- ObjectMapper objectMapper = new ObjectMapper();
- requestEvent.setBody(objectMapper.writeValueAsString(request));
- APIGatewayProxyResponseEvent result = app.handleRequest(requestEvent, null);
- System.out.println(result.getBody());
- assertEquals(HttpURLConnection.HTTP_OK, result.getStatusCode().intValue());
- assertEquals(MediaType.APPLICATION_JSON, result.getHeaders().get("Content-Type"));
- String content = result.getBody();
- assertNotNull(content);
- LanguageParsingResponse response =
- objectMapper.readValue(content, LanguageParsingResponse.class);
- assertNotNull(response.getVersionTypeValidation());
- assertNotNull(response.getVersionTypeValidation().isValid());
- assertTrue(response.getVersionTypeValidation().isValid());
- assertNotNull(response.getClonedRepositoryAbsolutePath());
- assertTrue(response.getClonedRepositoryAbsolutePath().contains("clonedRepository"));
- assertNotNull(response.getSecondaryFilePaths());
- final int knownSecondaryFilesCount = 23;
- assertEquals(
- knownSecondaryFilesCount,
- response.getSecondaryFilePaths().size(),
- "Should be 4 bin files, 16 config files, 2 lib files, and main.nf");
- assertEquals("Sarek - Workflow For Somatic And Germline Variations", response.getDescription());
- System.out.println(response.getClonedRepositoryAbsolutePath());
- assertEquals("Szilvester Juhos, Maxime Garcia", response.getAuthor());
- }
+ @Test
+ public void successfulResponse() throws Exception {
+ LanguageParsingRequest request = new LanguageParsingRequest();
+ request.setBranch("2.3");
+ // Archived repository with tag that is unlikely to change
+ request.setUri("https://github.com/SciLifeLab/Sarek.git");
+ request.setDescriptorRelativePathInGit("nextflow.config");
+ App app = new App();
+ APIGatewayProxyRequestEvent requestEvent = new APIGatewayProxyRequestEvent();
+ ObjectMapper objectMapper = new ObjectMapper();
+ requestEvent.setBody(objectMapper.writeValueAsString(request));
+ APIGatewayProxyResponseEvent result = app.handleRequest(requestEvent, null);
+ System.out.println(result.getBody());
+ assertEquals(HttpURLConnection.HTTP_OK, result.getStatusCode().intValue());
+ assertEquals(MediaType.APPLICATION_JSON, result.getHeaders().get("Content-Type"));
+ String content = result.getBody();
+ assertNotNull(content);
+ LanguageParsingResponse response =
+ objectMapper.readValue(content, LanguageParsingResponse.class);
+ assertNotNull(response.getVersionTypeValidation());
+ assertNotNull(response.getVersionTypeValidation().isValid());
+ assertTrue(response.getVersionTypeValidation().isValid());
+ assertNotNull(response.getClonedRepositoryAbsolutePath());
+ assertTrue(response.getClonedRepositoryAbsolutePath().contains("clonedRepository"));
+ assertNotNull(response.getSecondaryFilePaths());
+ final int knownSecondaryFilesCount = 23;
+ assertEquals(
+ knownSecondaryFilesCount,
+ response.getSecondaryFilePaths().size(),
+ "Should be 4 bin files, 16 config files, 2 lib files, and main.nf");
+ assertEquals(
+ "Sarek - Workflow For Somatic And Germline Variations", response.getDescription());
+ System.out.println(response.getClonedRepositoryAbsolutePath());
+ assertEquals("Szilvester Juhos, Maxime Garcia", response.getAuthor());
+ }
}
diff --git a/nextflow-parsing/events/sarek.json b/nextflow-parsing/events/sarek.json
new file mode 100644
index 0000000..aa94998
--- /dev/null
+++ b/nextflow-parsing/events/sarek.json
@@ -0,0 +1,5 @@
+{
+ "httpMethod": "POST",
+ "path": "/parse",
+ "body": "{\"uri\":\"https://github.com/SciLifeLab/Sarek.git\",\"branch\":\"2.3\",\"descriptorRelativePathInGit\":\"nextflow.config\"}"
+}
diff --git a/nextflow-parsing/template.yaml b/nextflow-parsing/template.yaml
index fa81242..eb6ea42 100644
--- a/nextflow-parsing/template.yaml
+++ b/nextflow-parsing/template.yaml
@@ -15,8 +15,8 @@ Resources:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: NextflowParsingFunction
- Handler: helloworld.App::handleRequest
- Runtime: java11
+ Handler: io.dockstore.nextflowparsing.App::handleRequest
+ Runtime: java21
MemorySize: 512
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables: