/** * Called to discover the field definition give the current parameters and the AST {@link Field} * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * @param field the field to find the definition of * * @return a {@link GraphQLFieldDefinition} */ protected GraphQLFieldDefinition getFieldDef(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Field field) { GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); return getFieldDef(executionContext.getGraphQLSchema(), parentType, field); }
@Override @SuppressWarnings("FutureReturnValueIgnored") public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { InstrumentationContext<ExecutionResult> executionStrategyCtx = executionContext.getInstrumentation() .beginExecutionStrategy(new InstrumentationExecutionStrategyParameters(executionContext, parameters)); GraphQLObjectType type = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); ExecutionNode root = new ExecutionNode(type, parameters.getExecutionStepInfo(), parameters.getFields().getSubFields(), singletonList(MapOrList.createMap(new LinkedHashMap<>())), Collections.singletonList(parameters.getSource()) ); Queue<ExecutionNode> nodes = new ArrayDeque<>(); CompletableFuture<ExecutionResult> result = new CompletableFuture<>(); executeImpl(executionContext, parameters, root, root, nodes, root.getFields().keySet().iterator(), result); executionStrategyCtx.onDispatched(result); result.whenComplete(executionStrategyCtx::onCompleted); return result; }
private BiFunction<List<Object>, Throwable, FetchedValues> handleResult(ExecutionContext executionContext, ExecutionStrategyParameters parameters, List<MapOrList> parentResults, DataFetchingEnvironment environment) { return (result, exception) -> { if (exception != null) { if (exception instanceof CompletionException) { exception = exception.getCause(); } DataFetcherExceptionHandlerParameters handlerParameters = DataFetcherExceptionHandlerParameters.newExceptionParameters() .dataFetchingEnvironment(environment) .exception(exception) .build(); DataFetcherExceptionHandlerResult handlerResult = dataFetcherExceptionHandler.onException(handlerParameters); handlerResult.getErrors().forEach(executionContext::addError); result = Collections.nCopies(parentResults.size(), null); } List<Object> values = result; List<FetchedValue> retVal = new ArrayList<>(); for (int i = 0; i < parentResults.size(); i++) { Object value = unboxPossibleOptional(values.get(i)); retVal.add(new FetchedValue(parentResults.get(i), value)); } return new FetchedValues(retVal, parameters.getExecutionStepInfo(), parameters.getPath()); }; }
private void handleTypeMismatchProblem(ExecutionContext context, ExecutionStrategyParameters parameters, Object result) { TypeMismatchError error = new TypeMismatchError(parameters.getPath(), parameters.getExecutionStepInfo().getUnwrappedNonNullType()); log.warn("{} got {}", error.getMessage(), result.getClass()); context.addError(error); parameters.deferredErrorSupport().onError(error); }
private void handleUnresolvedTypeProblem(ExecutionContext context, ExecutionStrategyParameters parameters, UnresolvedTypeException e) { UnresolvedTypeError error = new UnresolvedTypeError(parameters.getPath(), parameters.getExecutionStepInfo(), e); log.warn(error.getMessage(), e); context.addError(error); parameters.deferredErrorSupport().onError(error); }
@SuppressWarnings("FutureReturnValueIgnored") private Supplier<CompletableFuture<ExecutionResult>> deferredExecutionResult(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { return () -> { GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField()); GraphQLObjectType fieldContainer = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); Instrumentation instrumentation = executionContext.getInstrumentation(); DeferredFieldInstrumentationContext fieldCtx = instrumentation.beginDeferredField( new InstrumentationDeferredFieldParameters(executionContext, parameters, fieldDef, createExecutionStepInfo(executionContext, parameters, fieldDef, fieldContainer)) ); CompletableFuture<ExecutionResult> result = new CompletableFuture<>(); fieldCtx.onDispatched(result); CompletableFuture<FieldValueInfo> fieldValueInfoFuture = resolveFieldWithInfo(executionContext, parameters); fieldValueInfoFuture.whenComplete((fieldValueInfo, throwable) -> { fieldCtx.onFieldValueInfo(fieldValueInfo); CompletableFuture<ExecutionResult> execResultFuture = fieldValueInfo.getFieldValue(); execResultFuture = execResultFuture.whenComplete(fieldCtx::onCompleted); Async.copyResults(execResultFuture, result); }); return result; }; } }
ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); GraphQLFieldDefinition fieldDef = parameters.getExecutionStepInfo().getFieldDefinition(); GraphQLObjectType fieldContainer = parameters.getExecutionStepInfo().getFieldContainer();
private CompletableFuture<List<ExecutionNode>> resolveField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, String fieldName, ExecutionNode node) { GraphQLObjectType parentType = node.getType(); MergedField fields = node.getFields().get(fieldName); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, fields.getSingleField()); Instrumentation instrumentation = executionContext.getInstrumentation(); ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); InstrumentationContext<ExecutionResult> fieldCtx = instrumentation.beginField( new InstrumentationFieldParameters(executionContext, fieldDef, executionStepInfo) ); CompletableFuture<FetchedValues> fetchedData = fetchData(executionContext, parameters, fieldName, node, fieldDef); CompletableFuture<List<ExecutionNode>> result = fetchedData.thenApply((fetchedValues) -> { GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry(); Map<String, Object> argumentValues = valuesResolver.getArgumentValues( codeRegistry, fieldDef.getArguments(), fields.getSingleField().getArguments(), executionContext.getVariables()); return completeValues(executionContext, fetchedValues, executionStepInfo, fieldName, fields, argumentValues); }); fieldCtx.onDispatched(null); result = result.whenComplete((nodes, throwable) -> fieldCtx.onCompleted(null, throwable)); return result; }
ExecutionStepInfo currentParentExecutionStepInfo = parameters.getExecutionStepInfo(); ExecutionStepInfo newParentExecutionStepInfo = newExecutionStepInfo() .type(curNode.getType())
GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field.getSingleField());
.mergedField(fields) .fieldType(fieldDef.getType()) .executionStepInfo(parameters.getExecutionStepInfo()) .parentType(parentType) .selectionSet(fieldCollector)
GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field); ExecutionStepInfo executionStepInfo = createExecutionStepInfo(executionContext, parameters, fieldDef, parentType);
/** * Builds the type info hierarchy for the current field * * @param executionContext the execution context in play * @param parameters contains the parameters holding the fields to be executed and source object * @param fieldDefinition the field definition to build type info for * * @return a new type info */ protected ExecutionStepInfo createExecutionStepInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLFieldDefinition fieldDefinition, GraphQLObjectType fieldContainer) { GraphQLOutputType fieldType = fieldDefinition.getType(); List<Argument> fieldArgs = parameters.getField().getArguments(); GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry(); Map<String, Object> argumentValues = valuesResolver.getArgumentValues(codeRegistry, fieldDefinition.getArguments(), fieldArgs, executionContext.getVariables()); return newExecutionStepInfo() .type(fieldType) .fieldDefinition(fieldDefinition) .fieldContainer(fieldContainer) .field(parameters.getField()) .path(parameters.getPath()) .parentInfo(parameters.getExecutionStepInfo()) .arguments(argumentValues) .build(); }
/** * Called to turn an java object value into an graphql object value * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * @param resolvedObjectType the resolved object type * @param result the result to be coerced * * @return a promise to an {@link ExecutionResult} */ protected CompletableFuture<ExecutionResult> completeValueForObject(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLObjectType resolvedObjectType, Object result) { ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); FieldCollectorParameters collectorParameters = newParameters() .schema(executionContext.getGraphQLSchema()) .objectType(resolvedObjectType) .fragments(executionContext.getFragmentsByName()) .variables(executionContext.getVariables()) .build(); MergedSelectionSet subFields = fieldCollector.collectFields(collectorParameters, parameters.getField()); ExecutionStepInfo newExecutionStepInfo = executionStepInfo.changeTypeWithPreservedNonNull(resolvedObjectType); NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, newExecutionStepInfo); ExecutionStrategyParameters newParameters = parameters.transform(builder -> builder.executionStepInfo(newExecutionStepInfo) .fields(subFields) .nonNullFieldValidator(nonNullableFieldValidator) .source(result) ); // Calling this from the executionContext to ensure we shift back from mutation strategy to the query strategy. return executionContext.getQueryStrategy().execute(executionContext, newParameters); }
ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); Object result = UnboxPossibleOptional.unboxPossibleOptional(parameters.getSource()); GraphQLType fieldType = executionStepInfo.getUnwrappedNonNullType();
/** * Called to discover the field definition give the current parameters and the AST {@link Field} * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * @param field the field to find the definition of * * @return a {@link GraphQLFieldDefinition} */ protected GraphQLFieldDefinition getFieldDef(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Field field) { GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); return getFieldDef(executionContext.getGraphQLSchema(), parentType, field); }
private void handleTypeMismatchProblem(ExecutionContext context, ExecutionStrategyParameters parameters, Object result) { TypeMismatchError error = new TypeMismatchError(parameters.getPath(), parameters.getExecutionStepInfo().getUnwrappedNonNullType()); log.warn("{} got {}", error.getMessage(), result.getClass()); context.addError(error); parameters.deferredErrorSupport().onError(error); }
private void handleUnresolvedTypeProblem(ExecutionContext context, ExecutionStrategyParameters parameters, UnresolvedTypeException e) { UnresolvedTypeError error = new UnresolvedTypeError(parameters.getPath(), parameters.getExecutionStepInfo(), e); log.warn(error.getMessage(), e); context.addError(error); parameters.deferredErrorSupport().onError(error); }
@Override protected FieldValueInfo completeValue(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { graphql.schema.GraphQLType fieldType = parameters.getExecutionStepInfo().getType(); Object result = parameters.getSource(); if (result instanceof Enum && fieldType instanceof GraphQLEnumType) { Object value = ((GraphQLEnumType) fieldType).getCoercing().parseValue(((Enum) result).name()); return super.completeValue(executionContext, withSource(parameters, value)); } if (result instanceof Optional) { Object value = ((Optional<?>) result).orElse(null); return completeValue(executionContext, withSource(parameters, value)); } return super.completeValue(executionContext, parameters); }
private ExecutionStrategyParameters withSource(ExecutionStrategyParameters parameters, Object source) { return ExecutionStrategyParameters.newParameters() .arguments(parameters.getArguments()) .fields(parameters.getFields()) .nonNullFieldValidator(parameters.getNonNullFieldValidator()) .executionStepInfo(parameters.getExecutionStepInfo()) .source(source) .build(); }