diff --git a/src/main/java/org/commonwl/view/cwl/CWLNotAWorkflowException.java b/src/main/java/org/commonwl/view/cwl/CWLNotAWorkflowException.java new file mode 100644 index 00000000..db0efa03 --- /dev/null +++ b/src/main/java/org/commonwl/view/cwl/CWLNotAWorkflowException.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.commonwl.view.cwl; + +/** Exception thrown when the provided CWL document is not a Workflow. */ +public class CWLNotAWorkflowException extends CWLValidationException { + + public CWLNotAWorkflowException(String message) { + super(message); + } + + public CWLNotAWorkflowException(Throwable throwable) { + super(throwable); + } + + public CWLNotAWorkflowException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/src/main/java/org/commonwl/view/cwl/CWLService.java b/src/main/java/org/commonwl/view/cwl/CWLService.java index e2c8fc0a..bd2e80ab 100644 --- a/src/main/java/org/commonwl/view/cwl/CWLService.java +++ b/src/main/java/org/commonwl/view/cwl/CWLService.java @@ -181,7 +181,8 @@ public List getWorkflowOverviewsFromPacked(File packedFile) th * @return The constructed workflow object */ public Workflow parseWorkflowNative( - InputStream workflowStream, String packedWorkflowId, String defaultLabel) throws IOException { + InputStream workflowStream, String packedWorkflowId, String defaultLabel) + throws IOException, WorkflowNotFoundException, CWLValidationException { // Parse file as yaml Map cwlFile = yamlStreamToJson(workflowStream); @@ -205,11 +206,15 @@ public Workflow parseWorkflowNative( } if (!found && !packedWorkflowId.isEmpty()) throw new WorkflowNotFoundException(); } - if (!found && extractProcess(cwlFile) == CWLProcess.WORKFLOW) { - // Check the current json node is a workflow - found = true; - } if (!found) { + if (extractProcess(cwlFile) == CWLProcess.WORKFLOW) { + // Check the current json node is a workflow + found = true; + } else { + throw new CWLNotAWorkflowException( + "Not a 'class: Workflow' CWL document, is a " + extractProcess(cwlFile)); + } + } else { throw new WorkflowNotFoundException(); } @@ -248,7 +253,7 @@ public Workflow parseWorkflowNative( * @return The constructed workflow object */ public Workflow parseWorkflowNative(Path workflowFile, String packedWorkflowId) - throws IOException { + throws IOException, WorkflowNotFoundException, CWLValidationException { // Check file size limit before parsing long fileSizeBytes = Files.size(workflowFile); diff --git a/src/main/java/org/commonwl/view/workflow/WorkflowController.java b/src/main/java/org/commonwl/view/workflow/WorkflowController.java index 86e88ed1..8a4ae242 100644 --- a/src/main/java/org/commonwl/view/workflow/WorkflowController.java +++ b/src/main/java/org/commonwl/view/workflow/WorkflowController.java @@ -30,8 +30,10 @@ import javax.validation.Valid; import org.apache.commons.lang.StringUtils; import org.commonwl.view.WebConfig; +import org.commonwl.view.cwl.CWLNotAWorkflowException; import org.commonwl.view.cwl.CWLService; import org.commonwl.view.cwl.CWLToolStatus; +import org.commonwl.view.cwl.CWLValidationException; import org.commonwl.view.git.GitDetails; import org.commonwl.view.graphviz.GraphVizService; import org.eclipse.jgit.api.errors.GitAPIException; @@ -163,6 +165,10 @@ public ModelAndView createWorkflow( logger.warn("git.notFound " + workflowForm, ex); bindingResult.rejectValue("url", "git.notFound"); return new ModelAndView("index"); + } catch (CWLNotAWorkflowException ex) { + logger.warn("cwl.notAWorkflow " + workflowForm, ex); + bindingResult.rejectValue("url", "cwl.notAWorkflow"); + return new ModelAndView("index"); } catch (Exception ex) { logger.warn("url.parsingError " + workflowForm, ex); bindingResult.rejectValue("url", "url.parsingError"); @@ -629,7 +635,11 @@ private ModelAndView getWorkflow(GitDetails gitDetails, RedirectAttributes redir } catch (WorkflowNotFoundException ex) { logger.warn("git.notFound " + workflowForm, ex); errors.rejectValue( - "url", "git.notFound", "The workflow could not be found within the repository"); + "url", "git.notFound", "The workflow could not be found within the repository."); + } catch (CWLValidationException ex) { + logger.warn("cwl.invalid " + workflowForm, ex); + errors.rejectValue( + "url", "cwl.invalid", "The workflow had a parsing error: " + ex.getMessage()); } catch (IOException ex) { logger.warn("url.parsingError " + workflowForm, ex); errors.rejectValue( @@ -658,7 +668,8 @@ private ModelAndView getWorkflow(GitDetails gitDetails, RedirectAttributes redir } } - private Resource getGraphFromInputStream(InputStream in, String format) throws IOException { + private Resource getGraphFromInputStream(InputStream in, String format) + throws IOException, WorkflowNotFoundException, CWLValidationException { Workflow workflow = cwlService.parseWorkflowNative(in, null, "workflow"); // first workflow will do InputStream out = graphVizService.getGraphStream(workflow.getVisualisationDot(), format); diff --git a/src/main/java/org/commonwl/view/workflow/WorkflowService.java b/src/main/java/org/commonwl/view/workflow/WorkflowService.java index 451eff7c..cf97282c 100644 --- a/src/main/java/org/commonwl/view/workflow/WorkflowService.java +++ b/src/main/java/org/commonwl/view/workflow/WorkflowService.java @@ -33,6 +33,7 @@ import org.commonwl.view.cwl.CWLService; import org.commonwl.view.cwl.CWLToolRunner; import org.commonwl.view.cwl.CWLToolStatus; +import org.commonwl.view.cwl.CWLValidationException; import org.commonwl.view.git.GitDetails; import org.commonwl.view.git.GitSemaphore; import org.commonwl.view.git.GitService; @@ -308,7 +309,7 @@ public File getROBundle(GitDetails gitDetails) throws ROBundleNotFoundException * @throws IOException Other file handling exceptions */ public QueuedWorkflow createQueuedWorkflow(GitDetails gitInfo) - throws GitAPIException, WorkflowNotFoundException, IOException { + throws GitAPIException, WorkflowNotFoundException, IOException, CWLValidationException { QueuedWorkflow queuedWorkflow; Git repo = null; @@ -338,7 +339,7 @@ public QueuedWorkflow createQueuedWorkflow(GitDetails gitInfo) // Check workflow is readable if (!Files.isReadable(workflowFile)) { - throw new WorkflowNotFoundException(); + throw new WorkflowNotFoundException("Unable to read workflow file on disk."); } // Handling of packed workflows diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index aa73cddc..cd14f8d8 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -6,5 +6,8 @@ git.retrievalError = The workflow could not be retrieved from the Git repository git.notFound = The workflow could not be found within the repository git.sshError = SSH URLs are not supported, please provide a HTTPS URL for the repository or submodules +cwl.invalid = An error with the CWL workflow itself +cwl.notAWorkflow = The provided CWL document is not a "class: Workflow" file. + url.parsingError = An unexpected error occurred when parsing the workflow url.noWorkflowsInDirectory = No workflow files were found in the given directory