use of graphql.execution.ExecutionStepInfo in project graphql-orchestrator-java by intuit.
the class SubtreeBatchResultTransformerTest method producesPartitionedResult.
@Test
public void producesPartitionedResult() {
Map<String, Object> data = new HashMap<>();
data.put("consumer", new HashMap<String, String>() {
{
put("finance", "test");
put("shouldBeIgnored", null);
}
});
final ExecutionStepInfo executionStepInfo = buildCompleteExecutionStepInfo(document, "consumer", "finance");
DataFetchingEnvironment dataFetchingEnvironment = newDataFetchingEnvironment().mergedField(executionStepInfo.getField()).executionStepInfo(executionStepInfo).build();
DataFetcherResult<Map<String, Object>> dataFetcherResult = DataFetcherResult.<Map<String, Object>>newResult().data(data).build();
final List<DataFetcherResult<Object>> results = new SubtreeBatchResultTransformer().toBatchResult(dataFetcherResult, Collections.singletonList(dataFetchingEnvironment));
assertThat(results).hasSize(1).extracting(DataFetcherResult::getData).containsExactly("test");
}
use of graphql.execution.ExecutionStepInfo in project graphql-orchestrator-java by intuit.
the class SubtreeBatchResultTransformerTest method addErrorsToPartitionedResult.
@Test
public void addErrorsToPartitionedResult() {
Map<String, Object> data = new HashMap<>();
data.put("consumer", new HashMap<String, String>() {
{
put("finance", "test");
put("experiences", "test");
put("financialProfile", "test");
put("shouldBeIgnored", null);
}
});
List<GraphQLError> errors = new ArrayList<GraphQLError>() {
{
add(GraphqlErrorBuilder.newError().message("Exception while fetching data (/consumer/shouldBeIgnored)").build());
}
};
final ExecutionStepInfo executionStepInfo1 = buildCompleteExecutionStepInfo(document, "consumer", "finance");
final ExecutionStepInfo executionStepInfo2 = buildCompleteExecutionStepInfo(document, "consumer", "experiences");
final ExecutionStepInfo executionStepInfo3 = buildCompleteExecutionStepInfo(document, "consumer", "financialProfile");
DataFetchingEnvironment dfe1 = newDataFetchingEnvironment().mergedField(executionStepInfo1.getField()).executionStepInfo(executionStepInfo1).build();
DataFetchingEnvironment dfe2 = newDataFetchingEnvironment().mergedField(executionStepInfo2.getField()).executionStepInfo(executionStepInfo2).build();
DataFetchingEnvironment dfe3 = newDataFetchingEnvironment().mergedField(executionStepInfo3.getField()).executionStepInfo(executionStepInfo3).build();
DataFetcherResult<Map<String, Object>> dataFetcherResult = DataFetcherResult.<Map<String, Object>>newResult().data(data).errors(errors).build();
final List<DataFetcherResult<Object>> results = new SubtreeBatchResultTransformer().toBatchResult(dataFetcherResult, new ArrayList<>(Arrays.asList(dfe1, dfe2, dfe3)));
assertThat(results).hasSize(3).extracting(DataFetcherResult::getData).containsExactly("test", "test", "test");
assertThat(results.stream().flatMap(result -> result.getErrors().stream()).collect(Collectors.toList())).hasSize(1);
}
use of graphql.execution.ExecutionStepInfo in project graphql-orchestrator-java by intuit.
the class SubtreeBatchResultTransformerTest method nullDataPathReturnsNull.
@Test
public void nullDataPathReturnsNull() {
Map<String, Object> data = new HashMap<>();
data.put("consumer", new HashMap<String, String>() {
{
put("finance", null);
}
});
final ExecutionStepInfo executionStepInfo = buildCompleteExecutionStepInfo(document, "consumer", "finance");
DataFetchingEnvironment dataFetchingEnvironment = newDataFetchingEnvironment().mergedField(executionStepInfo.getField()).executionStepInfo(executionStepInfo).build();
DataFetcherResult<Map<String, Object>> dataFetcherResult = DataFetcherResult.<Map<String, Object>>newResult().data(data).build();
final List<DataFetcherResult<Object>> results = new SubtreeBatchResultTransformer().toBatchResult(dataFetcherResult, Collections.singletonList(dataFetchingEnvironment));
assertThat(results).hasSize(1);
assertThat(results.get(0).getData()).isNull();
}
use of graphql.execution.ExecutionStepInfo in project graphql-orchestrator-java by intuit.
the class ResolverArgumentDataFetcherHelper method callBatchLoaderWithArguments.
/**
* Modifies the provided DataFetchingEnvironment by attaching arguments, variable definitions, and variable references
* to objects in the environment that need them.
*
* Rebuilding the DataFetchingEnvironment relies on APIs that are marked with @Internal in GraphQL-Java. The stability
* of this code depends on changes of the DataFetchingEnvironmentImpl.
*
* Note that only the ExecutionStepInfo is used to build the query in the QueryExecutorBatchLoader, but a majority of
* the fields must change to achieve consistency for the most commonly used getters (field, mergedField, etc.)
*
* Below are the fields in the DataFetchingEnvironment that are changed:
*
* executionStepInfo: QueryExecutorBatchLoader extracts field information from the root ExecutionStepInfo. Arguments
* must be injected into each level.
*
* arguments: Add argument data
*
* mergedField: Add list of arguments to the mergedField
*
* operationDefinition: Adds a new list of variable definitions generated by this method to the operationDefinition
*
* @param env a data fetching environment that will accept arguments
* @param resolvedArgumentData argument data that should be bound to the data fetching environment
* @return A DataFetcherResult with the value
*/
public CompletableFuture<DataFetcherResult<Object>> callBatchLoaderWithArguments(DataFetchingEnvironment env, Map<ResolverArgumentDirective, Object> resolvedArgumentData) {
Map<String, Object> variables = new HashMap<>();
List<VariableDefinition> variableDefinitions = new ArrayList<>();
List<Argument> fieldArguments = new ArrayList<>();
int uniqueIdentifier = 0;
for (final Entry<ResolverArgumentDirective, Object> entry : resolvedArgumentData.entrySet()) {
final ResolverArgumentDirective resolverArgumentDirective = entry.getKey();
final Object argumentData = entry.getValue();
// add inc to make argument globally unique
String variableBinding = String.format(VARIABLE_REFERENCE_FORMAT, resolverArgumentDirective.getArgumentName(), uniqueIdentifier++);
variables.put(variableBinding, argumentData);
variableDefinitions.add(VariableDefinition.newVariableDefinition().name(variableBinding).type(createTypeBasedOnGraphQLType(resolverArgumentDirective.getInputType())).build());
fieldArguments.add(Argument.newArgument().name(resolverArgumentDirective.getArgumentName()).value(VariableReference.newVariableReference().name(variableBinding).build()).build());
}
final OperationDefinition queryOperation = env.getOperationDefinition();
final MergedField newMergedField = env.getMergedField().transform(builder -> builder.fields(singletonList(env.getField().transform(fieldBuilder -> fieldBuilder.arguments(fieldArguments)))));
final OperationDefinition opDefWithVariables = queryOperation.transform(builder -> builder.variableDefinitions(variableDefinitions));
Map<String, Object> dfeArguments = resolvedArgumentData.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey().getArgumentName(), Entry::getValue));
DataFetchingEnvironment dfeWithArgs = DataFetchingEnvironmentImpl.newDataFetchingEnvironment(env).operationDefinition(opDefWithVariables).executionStepInfo(executionStepInfoModifier.addArgumentsToExecutionStepInfo(env, fieldArguments)).mergedField(newMergedField).variables(variables).arguments(dfeArguments).build();
return dfeWithArgs.<DataFetchingEnvironment, DataFetcherResult<Object>>getDataLoader(namespace).load(dfeWithArgs);
}
use of graphql.execution.ExecutionStepInfo in project graphql-orchestrator-java by intuit.
the class SubtreeBatchResultTransformer method buildDataFetchingPath.
private Stack<String> buildDataFetchingPath(ExecutionStepInfo leafInfo) {
Stack<String> hierarchy = new Stack<>();
ExecutionStepInfo curr = leafInfo;
// ignore Query/Mutation
while (curr != null && curr.getPath().getLevel() != 0) {
final Field field = curr.getField().getSingleField();
hierarchy.push(field.getAlias() != null ? field.getAlias() : field.getName());
curr = curr.getParent();
}
return hierarchy;
}
Aggregations