Skip to content

Commit

Permalink
Merge pull request #38 from icgc-argo/rc/2.4.0
Browse files Browse the repository at this point in the history
Rc/2.4.0
  • Loading branch information
jaserud authored Oct 28, 2020
2 parents 653825a + 6132e9d commit cfaf782
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 22 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>bio.overture</groupId>
<artifactId>song-search</artifactId>
<version>2.3.0</version>
<version>2.4.0</version>
<name>song-search</name>
<description>GQL microservice for searching maestro generated song indexes</description>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,27 @@

package bio.overture.songsearch.graphql;

import static bio.overture.songsearch.config.SearchFields.ANALYSIS_ID;
import static bio.overture.songsearch.config.SearchFields.RUN_ID;
import static bio.overture.songsearch.utils.CommonUtils.asImmutableMap;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.stream.Collectors.toList;

import bio.overture.songsearch.config.SongSearchProperties;
import bio.overture.songsearch.model.Analysis;
import bio.overture.songsearch.model.Run;
import bio.overture.songsearch.service.AnalysisService;
import bio.overture.songsearch.service.FileService;
import com.apollographql.federation.graphqljava._Entity;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import graphql.schema.DataFetcher;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -81,26 +87,59 @@ public DataFetcher getDataFetcher() {
if (runId instanceof String) {
return new Run(
(String) runId,
analysisService.getAnalysesByRunId((String) runId),
analysisService.getAnalysesById(ids));
producedAnalysesResolver((String) runId),
inputAnalysesResolver(ids));
}
}
return null;
})
.collect(toList());
}

private List<String> getRelevantAnalysisIdsFromRunParameters(Object parametersObj) {
val parametersBuilder = ImmutableMap.<String, Object>builder();
if (parametersObj instanceof Map) {
try {
val parametersMap = (Map<String, Object>) parametersObj;
parametersBuilder.putAll(parametersMap);
} catch (ClassCastException e) {
log.error("Failed to cast parametersObj to Map<String, Object>");
private DataFetcher<List<Analysis>> inputAnalysesResolver(List<String> inputAnalysisIds) {
return environment -> {
ImmutableMap<String, Object> filter = asImmutableMap(environment.getArgument("filter"));
val filerAnalysisId = filter.get(ANALYSIS_ID);

val multipleMergedFilters =
inputAnalysisIds.stream()
.map(
id -> {
Map<String, Object> map = new HashMap<>(filter);
map.put(ANALYSIS_ID, id);
return map;
})
.filter(f -> filerAnalysisId == null || f.get(ANALYSIS_ID).equals(filerAnalysisId))
.collect(toList());

// short circuit here, otherwise will get all analysis
if (multipleMergedFilters.size() < 1) {
return List.of();
}
}
val parameters = parametersBuilder.build();

return analysisService.getAnalyses(multipleMergedFilters);
};
}

private DataFetcher<List<Analysis>> producedAnalysesResolver(String runId) {
return environment -> {
ImmutableMap<String, Object> filter = asImmutableMap(environment.getArgument("filter"));
val filterRunId = filter.getOrDefault(RUN_ID, runId);

// short circuit here since can't find produced analysis for invalid runId
if (isNullOrEmpty(runId) || !runId.equals(filterRunId)) {
return List.of();
}

Map<String, Object> mergedFilter = new HashMap<>(filter);
mergedFilter.put(RUN_ID, runId);

return analysisService.getAnalyses(mergedFilter, null);
};
}

private List<String> getRelevantAnalysisIdsFromRunParameters(Object parametersObj) {
ImmutableMap<String, Object> parameters = asImmutableMap(parametersObj);

ImmutableList<String> analysisIdKeysToLookFor =
songSearchProperties.getWorkflowRunParameterKeys().getAnalysisId();
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/bio/overture/songsearch/model/Run.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
Expand All @@ -38,12 +40,22 @@ public class Run {

private String runId;

private List<Analysis> producedAnalyses;
private DataFetcher<List<Analysis>> producedAnalysesFetcher;

private List<Analysis> inputAnalyses;
private DataFetcher<List<Analysis>> inputAnalysesFetcher;

@SneakyThrows
public static Run parse(@NonNull Map<String, Object> sourceMap) {
return MAPPER.convertValue(sourceMap, Run.class);
}

@SneakyThrows
public List<Analysis> getInputAnalyses(DataFetchingEnvironment env) {
return inputAnalysesFetcher.get(env);
}

@SneakyThrows
public List<Analysis> getProducedAnalyses(DataFetchingEnvironment env) {
return producedAnalysesFetcher.get(env);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import static bio.overture.songsearch.model.enums.SpecimenType.NORMAL;
import static bio.overture.songsearch.model.enums.SpecimenType.TUMOUR;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toUnmodifiableList;

import bio.overture.songsearch.model.Analysis;
Expand Down Expand Up @@ -72,9 +71,7 @@ public List<Analysis> getAnalysesByRunId(String runId) {
return hitStream.map(AnalysisService::hitToAnalysis).collect(toUnmodifiableList());
}

public List<Analysis> getAnalysesById(List<String> analysisIds) {
val multipleFilters =
analysisIds.stream().map(id -> Map.of(ANALYSIS_ID, (Object) id)).collect(toList());
public List<Analysis> getAnalyses(List<Map<String, Object>> multipleFilters) {
val multiSearchResponse = analysisRepository.getAnalyses(multipleFilters, null);
return Arrays.stream(multiSearchResponse.getResponses())
.map(MultiSearchResponse.Item::getResponse)
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/bio/overture/songsearch/utils/CommonUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package bio.overture.songsearch.utils;

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import lombok.val;

@Slf4j
public final class CommonUtils {

private CommonUtils() {}

public static <K, V> ImmutableMap<K, V> asImmutableMap(Object obj) {
val newMap = ImmutableMap.<K, V>builder();
if (obj instanceof Map) {
try {
newMap.putAll((Map<? extends K, ? extends V>) obj);
} catch (ClassCastException e) {
log.error("Failed to cast obj to Map<K,V>");
}
}
return newMap.build();
}
}
6 changes: 4 additions & 2 deletions src/main/resources/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,13 @@ input Page {
from: Int!
}

directive @fetch(from : String!) on FIELD_DEFINITION

type Run @key(fields: "runId") @extends {
runId: ID! @external
parameters: JSON @external
producedAnalyses: [Analysis]
inputAnalyses: [Analysis] @requires(fields: "parameters")
producedAnalyses(filter: AnalysisFilter): [Analysis] @fetch(from: "producedAnalyses")
inputAnalyses(filter: AnalysisFilter): [Analysis] @requires(fields: "parameters") @fetch(from: "inputAnalyses")
}

type SampleMatchedAnalysisPair {
Expand Down

0 comments on commit cfaf782

Please sign in to comment.