Skip to content

Commit

Permalink
core: add minimumRequirements to Workflow, #TASK-6445
Browse files Browse the repository at this point in the history
  • Loading branch information
pfurio committed Sep 20, 2024
1 parent cdb2e89 commit 857b41d
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.opencb.commons.datastore.core.ObjectMap;
import org.opencb.commons.utils.DockerUtils;
import org.opencb.opencga.analysis.tools.OpenCgaToolScopeStudy;
import org.opencb.opencga.analysis.utils.InputFileUtils;
import org.opencb.opencga.catalog.utils.InputFileUtils;
import org.opencb.opencga.core.common.TimeUtils;
import org.opencb.opencga.core.exceptions.ToolException;
import org.opencb.opencga.core.models.common.Enums;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.opencb.commons.datastore.core.QueryOptions;
import org.opencb.commons.utils.DockerUtils;
import org.opencb.opencga.analysis.tools.OpenCgaToolScopeStudy;
import org.opencb.opencga.analysis.utils.InputFileUtils;
import org.opencb.opencga.catalog.utils.InputFileUtils;
import org.opencb.opencga.catalog.db.api.WorkflowDBAdaptor;
import org.opencb.opencga.core.common.JacksonUtils;
import org.opencb.opencga.core.common.TimeUtils;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.opencb.opencga.catalog.io.IOManagerFactory;
import org.opencb.opencga.catalog.models.InternalGetDataResult;
import org.opencb.opencga.catalog.utils.CatalogFqn;
import org.opencb.opencga.catalog.utils.InputFileUtils;
import org.opencb.opencga.catalog.utils.ParamUtils;
import org.opencb.opencga.catalog.utils.UuidUtils;
import org.opencb.opencga.core.api.FieldConstants;
Expand Down Expand Up @@ -379,7 +380,12 @@ private void autoCompleteNewJob(String organizationId, Study study, Job job, Jwt
job.setInput(Collections.emptyList());
} else {
// We only check input files if the job does not depend on other job that might be creating the necessary file.
List<File> inputFiles = getJobInputFilesFromParams(study.getFqn(), job, tokenPayload.getToken());
List<File> inputFiles;
if (job.getTool().getId().equalsIgnoreCase("binary") || job.getTool().getId().equalsIgnoreCase("workflow")) {
inputFiles = getWorkflowJobInputFilesFromParams(study.getFqn(), job, tokenPayload.getToken());
} else {
inputFiles = getJobInputFilesFromParams(study.getFqn(), job, tokenPayload.getToken());
}
job.setInput(inputFiles);
}

Expand Down Expand Up @@ -433,7 +439,6 @@ public OpenCGAResult<Job> kill(String studyStr, String jobId, String token) thro
}
}


public List<File> getJobInputFilesFromParams(String study, Job job, String token) throws CatalogException {
// Look for input files
String fileParamSuffix = "file";
Expand All @@ -457,10 +462,9 @@ public List<File> getJobInputFilesFromParams(String study, Job job, String token
// We look for files in the dynamic params
Map<String, Object> dynamicParams = (Map<String, Object>) entry.getValue();
for (Map.Entry<String, Object> subEntry : dynamicParams.entrySet()) {
String subEntryKey = subEntry.getKey().toLowerCase();
if (!subEntryKey.contains("profile") && subEntryKey.endsWith(fileParamSuffix)) {
if (subEntry.getKey().toLowerCase().endsWith(fileParamSuffix)) {
// We assume that every variable ending in 'file' corresponds to input files that need to be accessible in
// catalog (except words such as 'profile')
// catalog
try {
// Validate the user has access to the file
File file = catalogManager.getFileManager().get(study, (String) subEntry.getValue(),
Expand All @@ -478,6 +482,46 @@ public List<File> getJobInputFilesFromParams(String study, Job job, String token
return inputFiles;
}

public List<File> getWorkflowJobInputFilesFromParams(String study, Job job, String token) throws CatalogException {
InputFileUtils inputFileUtils = new InputFileUtils(catalogManager);
// Look for input files
List<File> inputFiles = new ArrayList<>();
if (job.getParams() != null) {
for (Map.Entry<String, Object> entry : job.getParams().entrySet()) {
if (entry.getValue() instanceof String) {
String fileStr = (String) entry.getValue();
if (inputFileUtils.isValidOpenCGAFile(fileStr)) {
try {
File file = inputFileUtils.getOpenCGAFile(study, fileStr, token);
inputFiles.add(file);
} catch (CatalogException e) {
throw new CatalogException("Cannot find file '" + entry.getValue() + "' from job param '" + entry.getKey()
+ "'; (study = " + study + ") :" + e.getMessage(), e);
}
}
} else if (entry.getValue() instanceof Map) {
// We look for files in the dynamic params
Map<String, Object> dynamicParams = (Map<String, Object>) entry.getValue();
for (Map.Entry<String, Object> subEntry : dynamicParams.entrySet()) {
if (subEntry.getValue() instanceof String) {
String fileStr = (String) subEntry.getValue();
if (inputFileUtils.isValidOpenCGAFile(fileStr)) {
try {
File file = inputFileUtils.getOpenCGAFile(study, fileStr, token);
inputFiles.add(file);
} catch (CatalogException e) {
throw new CatalogException("Cannot find file '" + subEntry.getValue() + "' from variable '"
+ entry.getKey() + "." + subEntry.getKey() + "'. ", e);
}
}
}
}
}
}
}
return inputFiles;
}

public OpenCGAResult<Job> retry(String studyStr, JobRetryParams jobRetry, Enums.Priority priority, String jobId, String jobDescription,
List<String> jobDependsOn, List<String> jobTags, String jobScheduledStartTime, String token)
throws CatalogException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,6 @@ private WorkflowDBAdaptor.QueryParams getFieldFilter(List<String> idList) throws

private void validateNewWorkflow(Workflow workflow, String userId) throws CatalogParameterException {
ParamUtils.checkIdentifier(workflow.getId(), ID.key());
ParamUtils.checkObj(workflow.getType(), TYPE.key());
if (workflow.getManager() == null) {
workflow.setManager(new WorkflowSystem());
}
Expand All @@ -571,6 +570,7 @@ private void validateNewWorkflow(Workflow workflow, String userId) throws Catalo
if (StringUtils.isEmpty(workflow.getManager().getVersion())) {
workflow.getManager().setVersion("24.04.4");
}
workflow.setType(ParamUtils.defaultObject(workflow.getType(), Workflow.Type.OTHER));
workflow.setTags(workflow.getTags() != null ? workflow.getTags() : Collections.emptyList());
workflow.setScripts(workflow.getScripts() != null ? workflow.getScripts() : Collections.emptyList());
boolean main = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.opencb.opencga.analysis.utils;
package org.opencb.opencga.catalog.utils;

import org.opencb.opencga.catalog.exceptions.CatalogException;
import org.opencb.opencga.catalog.managers.CatalogManager;
Expand All @@ -16,8 +16,7 @@ public class InputFileUtils {
private final CatalogManager catalogManager;

private static final Pattern OPERATION_PATTERN = Pattern.compile("^(?i)(ocga://|opencga://|file://)(.+)$");

private final static Logger logger = LoggerFactory.getLogger(InputFileUtils.class);
private final Logger logger = LoggerFactory.getLogger(InputFileUtils.class);

public InputFileUtils(CatalogManager catalogManager) {
this.catalogManager = catalogManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,13 @@ public class FieldConstants {
public static final String WORKFLOW_SCRIPTS_DESCRIPTION = "List of scripts used by the Workflow.";
public static final String WORKFLOW_TAGS_DESCRIPTION = "List of tags.";
public static final String WORKFLOW_VARIABLES_DESCRIPTION = "List of variables accepted by the Workflow.";
public static final String WORKFLOW_MINIMUM_REQUIREMENTS_DESCRIPTION = "Minimum requirements to execute the workflow.";
public static final String WORKFLOW_INTERNAL_DESCRIPTION = "Workflow internal information.";

public static final String WORKFLOW_MIN_REQUIREMENTS_CPU_DESCRIPTION = "Minimum number of cpu cores required to execute the workflow.";
public static final String WORKFLOW_MIN_REQUIREMENTS_MEMORY_DESCRIPTION = "Minimum memory required to execute the workflow"
+ " (expressed in GB).";

public static final String WORKFLOW_SYSTEM_ID_DESCRIPTION = "Workflow system id. Valid values: NEXTFLOW.";
public static final String WORKFLOW_SYSTEM_VERSION_DESCRIPTION = "Workflow system version to use.";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public class Workflow extends PrivateStudyUid {
@DataField(id = "variables", description = FieldConstants.WORKFLOW_VARIABLES_DESCRIPTION)
private List<Variable> variables;

@DataField(id = "minimumRequirements", description = FieldConstants.WORKFLOW_MINIMUM_REQUIREMENTS_DESCRIPTION)
private WorkflowMinimumRequirements minimumRequirements;

@DataField(id = "internal", description = FieldConstants.WORKFLOW_INTERNAL_DESCRIPTION)
private WorkflowInternal internal;

Expand All @@ -66,7 +69,7 @@ public class Workflow extends PrivateStudyUid {
public enum Type {
CLINICAL_INTERPRETATION,
SECONDARY_ANALYSIS,
RESEARCH,
RESEARCH_ANALYSIS,
OTHER
}

Expand All @@ -75,7 +78,8 @@ public Workflow() {

public Workflow(String id, String name, String description, boolean draft, Type type, WorkflowSystem manager,
WorkflowRepository repository, List<WorkflowScript> scripts, List<String> tags, List<Variable> variables,
WorkflowInternal internal, String creationDate, String modificationDate, Map<String, Object> attributes) {
WorkflowMinimumRequirements minimumRequirements, WorkflowInternal internal, String creationDate,
String modificationDate, Map<String, Object> attributes) {
this.id = id;
this.name = name;
this.description = description;
Expand All @@ -86,6 +90,7 @@ public Workflow(String id, String name, String description, boolean draft, Type
this.scripts = scripts;
this.tags = tags;
this.variables = variables;
this.minimumRequirements = minimumRequirements;
this.internal = internal;
this.creationDate = creationDate;
this.modificationDate = modificationDate;
Expand All @@ -108,6 +113,7 @@ public String toString() {
sb.append(", scripts=").append(scripts);
sb.append(", tags=").append(tags);
sb.append(", variables=").append(variables);
sb.append(", minimumRequirements=").append(minimumRequirements);
sb.append(", internal=").append(internal);
sb.append(", creationDate='").append(creationDate).append('\'');
sb.append(", modificationDate='").append(modificationDate).append('\'');
Expand Down Expand Up @@ -240,6 +246,15 @@ public Workflow setVariables(List<Variable> variables) {
return this;
}

public WorkflowMinimumRequirements getMinimumRequirements() {
return minimumRequirements;
}

public Workflow setMinimumRequirements(WorkflowMinimumRequirements minimumRequirements) {
this.minimumRequirements = minimumRequirements;
return this;
}

public WorkflowInternal getInternal() {
return internal;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public class WorkflowCreateParams {
@DataField(id = "variables", description = FieldConstants.WORKFLOW_VARIABLES_DESCRIPTION)
private List<Variable> variables;

@DataField(id = "minimumRequirements", description = FieldConstants.WORKFLOW_MINIMUM_REQUIREMENTS_DESCRIPTION)
private WorkflowMinimumRequirements minimumRequirements;

@DataField(id = "scripts", description = FieldConstants.WORKFLOW_SCRIPTS_DESCRIPTION)
private List<WorkflowScript> scripts;

Expand All @@ -53,8 +56,9 @@ public WorkflowCreateParams() {
}

public WorkflowCreateParams(String id, String name, String description, WorkflowSystem manager, Workflow.Type type, List<String> tags,
boolean draft, WorkflowRepository repository, List<Variable> variables, List<WorkflowScript> scripts,
String creationDate, String modificationDate, Map<String, Object> attributes) {
boolean draft, WorkflowRepository repository, List<Variable> variables,
WorkflowMinimumRequirements minimumRequirements, List<WorkflowScript> scripts, String creationDate,
String modificationDate, Map<String, Object> attributes) {
this.id = id;
this.name = name;
this.description = description;
Expand All @@ -64,6 +68,7 @@ public WorkflowCreateParams(String id, String name, String description, Workflow
this.draft = draft;
this.repository = repository;
this.variables = variables;
this.minimumRequirements = minimumRequirements;
this.scripts = scripts;
this.creationDate = creationDate;
this.modificationDate = modificationDate;
Expand All @@ -82,6 +87,7 @@ public String toString() {
sb.append(", draft=").append(draft);
sb.append(", repository=").append(repository);
sb.append(", variables=").append(variables);
sb.append(", minimumRequirements=").append(minimumRequirements);
sb.append(", scripts=").append(scripts);
sb.append(", creationDate='").append(creationDate).append('\'');
sb.append(", modificationDate='").append(modificationDate).append('\'');
Expand All @@ -91,8 +97,8 @@ public String toString() {
}

public Workflow toWorkflow() {
return new Workflow(id, name, description, draft, type, manager, repository, scripts, tags, variables, new WorkflowInternal(),
creationDate, modificationDate, attributes);
return new Workflow(id, name, description, draft, type, manager, repository, scripts, tags, variables, minimumRequirements,
new WorkflowInternal(), creationDate, modificationDate, attributes);
}

public String getId() {
Expand Down Expand Up @@ -176,6 +182,15 @@ public WorkflowCreateParams setVariables(List<Variable> variables) {
return this;
}

public WorkflowMinimumRequirements getMinimumRequirements() {
return minimumRequirements;
}

public WorkflowCreateParams setMinimumRequirements(WorkflowMinimumRequirements minimumRequirements) {
this.minimumRequirements = minimumRequirements;
return this;
}

public List<WorkflowScript> getScripts() {
return scripts;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.opencb.opencga.core.models.workflow;

import org.opencb.commons.annotations.DataField;
import org.opencb.opencga.core.api.FieldConstants;

public class WorkflowMinimumRequirements {

@DataField(id = "cpu", description = FieldConstants.WORKFLOW_MIN_REQUIREMENTS_CPU_DESCRIPTION)
private int cpu;

@DataField(id = "memory", description = FieldConstants.WORKFLOW_MIN_REQUIREMENTS_MEMORY_DESCRIPTION)
private int memory;

public WorkflowMinimumRequirements() {
}

public WorkflowMinimumRequirements(int cpu, int memory) {
this.cpu = cpu;
this.memory = memory;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("WorkflowMinimumRequirements{");
sb.append("cpu=").append(cpu);
sb.append(", memory=").append(memory);
sb.append('}');
return sb.toString();
}

public int getCpu() {
return cpu;
}

public WorkflowMinimumRequirements setCpu(int cpu) {
this.cpu = cpu;
return this;
}

public int getMemory() {
return memory;
}

public WorkflowMinimumRequirements setMemory(int memory) {
this.memory = memory;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public class WorkflowUpdateParams {
@DataField(id = "variables", description = FieldConstants.WORKFLOW_VARIABLES_DESCRIPTION)
private List<Variable> variables;

@DataField(id = "minimumRequirements", description = FieldConstants.WORKFLOW_MINIMUM_REQUIREMENTS_DESCRIPTION)
private WorkflowMinimumRequirements minimumRequirements;

@DataField(id = "creationDate", indexed = true, description = FieldConstants.GENERIC_CREATION_DATE_DESCRIPTION)
private String creationDate;

Expand All @@ -50,7 +53,8 @@ public WorkflowUpdateParams() {

public WorkflowUpdateParams(String name, String description, WorkflowSystem manager, Workflow.Type type, List<String> tags,
boolean draft, WorkflowRepository repository, List<WorkflowScript> scripts, List<Variable> variables,
String creationDate, String modificationDate, Map<String, Object> attributes) {
WorkflowMinimumRequirements minimumRequirements, String creationDate, String modificationDate,
Map<String, Object> attributes) {
this.name = name;
this.description = description;
this.manager = manager;
Expand All @@ -60,6 +64,7 @@ public WorkflowUpdateParams(String name, String description, WorkflowSystem mana
this.repository = repository;
this.scripts = scripts;
this.variables = variables;
this.minimumRequirements = minimumRequirements;
this.creationDate = creationDate;
this.modificationDate = modificationDate;
this.attributes = attributes;
Expand All @@ -77,6 +82,7 @@ public String toString() {
sb.append(", repository=").append(repository);
sb.append(", scripts=").append(scripts);
sb.append(", variables=").append(variables);
sb.append(", minimumRequirements=").append(minimumRequirements);
sb.append(", creationDate='").append(creationDate).append('\'');
sb.append(", modificationDate='").append(modificationDate).append('\'');
sb.append(", attributes=").append(attributes);
Expand Down

0 comments on commit 857b41d

Please sign in to comment.