diff --git a/src/main/java/org/icgc_argo/workflow/search/graphql/fetchers/EntityDataFetchers.java b/src/main/java/org/icgc_argo/workflow/search/graphql/fetchers/EntityDataFetchers.java index 46c5aad..5195438 100644 --- a/src/main/java/org/icgc_argo/workflow/search/graphql/fetchers/EntityDataFetchers.java +++ b/src/main/java/org/icgc_argo/workflow/search/graphql/fetchers/EntityDataFetchers.java @@ -62,8 +62,9 @@ public AsyncDataFetcher getDataFetcher() { } if (ANALYSIS_ENTITY.equals(values.get("__typename"))) { final Object analysisId = values.get("analysisId"); - if (analysisId instanceof String) { - return Mono.just(new Analysis((String) analysisId)); + final Object studyId = values.get("studyId"); + if (analysisId instanceof String || studyId instanceof String) { + return Mono.just(new Analysis((String) analysisId, (String) studyId); } } if (WORKFLOW_ENTITY.equals(values.get("__typename"))) { diff --git a/src/main/java/org/icgc_argo/workflow/search/graphql/fetchers/RunDataFetchers.java b/src/main/java/org/icgc_argo/workflow/search/graphql/fetchers/RunDataFetchers.java index 941cab8..b88f72a 100644 --- a/src/main/java/org/icgc_argo/workflow/search/graphql/fetchers/RunDataFetchers.java +++ b/src/main/java/org/icgc_argo/workflow/search/graphql/fetchers/RunDataFetchers.java @@ -21,6 +21,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; import static java.util.stream.Collectors.toUnmodifiableList; import static org.icgc_argo.workflow.search.model.SearchFields.ANALYSIS_ID; +import static org.icgc_argo.workflow.search.model.SearchFields.STUDY_ID; import static org.icgc_argo.workflow.search.util.Converter.asImmutableMap; import static org.icgc_argo.workflow.search.util.JacksonUtils.convertValue; @@ -108,17 +109,21 @@ public AsyncDataFetcher> getNestedRunInAnalysisDataFetcher() { return environment -> { val analysis = (Analysis) environment.getSource(); val analysisId = analysis.getAnalysisId(); + val studyId = analysis.getStudyId(); ImmutableMap filter = asImmutableMap(environment.getArgument("filter")); val filerAnalysisId = filter.getOrDefault(ANALYSIS_ID, analysisId); + val filterStudyId = filter.getOrDefault(STUDY_ID, studyId); // short circuit here since can't find runs for invalid analysisId - if (isNullOrEmpty(analysisId) || !analysisId.equals(filerAnalysisId)) { + if ((isNullOrEmpty(analysisId) || !analysisId.equals(filerAnalysisId)) + && (isNullOrEmpty(studyId) || !studyId.equals(filterStudyId))) { return Mono.empty(); } Map mergedFilter = new HashMap<>(filter); mergedFilter.put(ANALYSIS_ID, analysisId); + mergedFilter.put(STUDY_ID, studyId); // Need to cast to get appropriate jackson annotation (camelCase property naming) return runService.getRuns(mergedFilter, null); diff --git a/src/main/java/org/icgc_argo/workflow/search/model/SearchFields.java b/src/main/java/org/icgc_argo/workflow/search/model/SearchFields.java index abdf62a..36349e1 100644 --- a/src/main/java/org/icgc_argo/workflow/search/model/SearchFields.java +++ b/src/main/java/org/icgc_argo/workflow/search/model/SearchFields.java @@ -40,4 +40,5 @@ public class SearchFields { public static final String ANALYSIS_ID = "analysisId"; public static final String CPUS = "cpus"; public static final String MEMORY = "memory"; + public static final String STUDY_ID = "studyId"; } diff --git a/src/main/java/org/icgc_argo/workflow/search/model/graphql/Analysis.java b/src/main/java/org/icgc_argo/workflow/search/model/graphql/Analysis.java index 9774640..e10450b 100644 --- a/src/main/java/org/icgc_argo/workflow/search/model/graphql/Analysis.java +++ b/src/main/java/org/icgc_argo/workflow/search/model/graphql/Analysis.java @@ -29,7 +29,6 @@ import lombok.SneakyThrows; @Data -@AllArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class Analysis { @@ -37,8 +36,25 @@ public class Analysis { private String analysisId; + private String studyId; + + public Analysis(String analysisId, String studyId) { + if (null!=analysisId) { + this.analysisId = analysisId; + } else { + this.analysisId = ""; + } + if (null!=studyId) { + this.studyId = studyId; + } else { + this.studyId = ""; + } + } + @SneakyThrows public static Analysis parse(@NonNull Map sourceMap) { return MAPPER.convertValue(sourceMap, Analysis.class); } + + } diff --git a/src/main/java/org/icgc_argo/workflow/search/repository/RunRepository.java b/src/main/java/org/icgc_argo/workflow/search/repository/RunRepository.java index 7a1ad02..dde806a 100644 --- a/src/main/java/org/icgc_argo/workflow/search/repository/RunRepository.java +++ b/src/main/java/org/icgc_argo/workflow/search/repository/RunRepository.java @@ -59,6 +59,9 @@ public class RunRepository { "parameters.analysis_id", "parameters.normal_aln_analysis_id", "parameters.tumour_aln_analysis_id"); + + private static final String STUDY_SEARCH_FIELD ="parameters.study_id"; + private static final Map>> QUERY_RESOLVER = argumentPathMap(); @@ -182,6 +185,12 @@ private static Map>> argumentPa q.minimumShouldMatch("100%"); return q; }) + .put( + STUDY_ID, + value -> { + val q = new TermQueryBuilder(value, STUDY_SEARCH_FIELD); + return q; + }) .put(REPOSITORY, RunRepository::repositoryQueryFunc) .build(); } diff --git a/src/main/resources/schema.graphqls b/src/main/resources/schema.graphqls index 904c289..884c34e 100644 --- a/src/main/resources/schema.graphqls +++ b/src/main/resources/schema.graphqls @@ -17,6 +17,8 @@ type Run @key(fields: "runId") { commandLine: String engineParameters: EngineParameters tasks(taskId: String, state: String, tag: String): [Task] + producedAnalyses(filter: RunsFilter): [Analysis] @fetch(from: "producedAnalyses") + inputAnalyses(filter: RunsFilter): [Analysis] @requires(fields: "parameters") @fetch(from: "inputAnalyses") } type EngineParameters { @@ -75,6 +77,7 @@ input RunsFilter { state: String repository: String analysisId: String + studyId: String } input TasksFilter { @@ -94,6 +97,7 @@ directive @fetch(from : String!) on FIELD_DEFINITION type Analysis @key(fields: "analysisId") @extends { analysisId: ID! @external + studyId: String! @external inputForRuns(filter: RunsFilter): [Run] }