use of graphql.schema.GraphQLCodeRegistry in project graphql-java by graphql-java.
the class ValueFetcher method fetchValue.
public CompletableFuture<FetchedValue> fetchValue(ExecutionContext executionContext, Object source, Object localContext, MergedField sameFields, ExecutionStepInfo executionInfo) {
Field field = sameFields.getSingleField();
GraphQLFieldDefinition fieldDef = executionInfo.getFieldDefinition();
GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry();
GraphQLFieldsContainer parentType = getFieldsContainer(executionInfo);
Supplier<Map<String, Object>> argumentValues = FpKit.intraThreadMemoize(() -> valuesResolver.getArgumentValues(codeRegistry, fieldDef.getArguments(), field.getArguments(), executionContext.getVariables()));
QueryDirectivesImpl queryDirectives = new QueryDirectivesImpl(sameFields, executionContext.getGraphQLSchema(), executionContext.getVariables());
GraphQLOutputType fieldType = fieldDef.getType();
Supplier<ExecutableNormalizedOperation> normalizedQuery = executionContext.getNormalizedQueryTree();
Supplier<ExecutableNormalizedField> normalisedField = () -> normalizedQuery.get().getNormalizedField(sameFields, executionInfo.getObjectType(), executionInfo.getPath());
DataFetchingFieldSelectionSet selectionSet = DataFetchingFieldSelectionSetImpl.newCollector(executionContext.getGraphQLSchema(), fieldType, normalisedField);
DataFetchingEnvironment environment = newDataFetchingEnvironment(executionContext).source(source).localContext(localContext).arguments(argumentValues).fieldDefinition(fieldDef).mergedField(sameFields).fieldType(fieldType).executionStepInfo(executionInfo).parentType(parentType).selectionSet(selectionSet).queryDirectives(queryDirectives).build();
ExecutionId executionId = executionContext.getExecutionId();
ResultPath path = executionInfo.getPath();
return callDataFetcher(codeRegistry, parentType, fieldDef, environment, executionId, path).thenApply(rawFetchedValue -> FetchedValue.newFetchedValue().fetchedValue(rawFetchedValue).rawFetchedValue(rawFetchedValue).build()).exceptionally(exception -> handleExceptionWhileFetching(field, path, exception)).thenApply(result -> unboxPossibleDataFetcherResult(sameFields, path, result, localContext)).thenApply(this::unboxPossibleOptional);
}
use of graphql.schema.GraphQLCodeRegistry in project graphql-java by graphql-java.
the class ExecutionStrategy method createExecutionStepInfo.
/**
* 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
* @param fieldContainer the field container
*
* @return a new type info
*/
protected ExecutionStepInfo createExecutionStepInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLFieldDefinition fieldDefinition, GraphQLObjectType fieldContainer) {
MergedField field = parameters.getField();
ExecutionStepInfo parentStepInfo = parameters.getExecutionStepInfo();
GraphQLOutputType fieldType = fieldDefinition.getType();
List<GraphQLArgument> fieldArgDefs = fieldDefinition.getArguments();
Supplier<Map<String, Object>> argumentValues = Collections::emptyMap;
//
if (!fieldArgDefs.isEmpty()) {
List<Argument> fieldArgs = field.getArguments();
GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry();
argumentValues = FpKit.intraThreadMemoize(() -> valuesResolver.getArgumentValues(codeRegistry, fieldArgDefs, fieldArgs, executionContext.getVariables()));
}
return newExecutionStepInfo().type(fieldType).fieldDefinition(fieldDefinition).fieldContainer(fieldContainer).field(field).path(parameters.getPath()).parentInfo(parentStepInfo).arguments(argumentValues).build();
}
use of graphql.schema.GraphQLCodeRegistry in project graphql-java by graphql-java.
the class ExecutionStrategy method fetchField.
/**
* Called to fetch a value for a field from the {@link DataFetcher} associated with the field
* {@link GraphQLFieldDefinition}.
* <p>
* Graphql fragments mean that for any give logical field can have one or more {@link Field} values associated with it
* in the query, hence the fieldList. However the first entry is representative of the field for most purposes.
*
* @param executionContext contains the top level execution parameters
* @param parameters contains the parameters holding the fields to be executed and source object
*
* @return a promise to a fetched object
*
* @throws NonNullableFieldWasNullException in the future if a non null field resolves to a null value
*/
protected CompletableFuture<FetchedValue> fetchField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) {
MergedField field = parameters.getField();
GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType();
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field.getSingleField());
GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry();
GraphQLOutputType fieldType = fieldDef.getType();
// if the DF (like PropertyDataFetcher) does not use the arguments of execution step info then dont build any
Supplier<ExecutionStepInfo> executionStepInfo = FpKit.intraThreadMemoize(() -> createExecutionStepInfo(executionContext, parameters, fieldDef, parentType));
Supplier<Map<String, Object>> argumentValues = () -> executionStepInfo.get().getArguments();
Supplier<ExecutableNormalizedField> normalizedFieldSupplier = getNormalizedField(executionContext, parameters, executionStepInfo);
// DataFetchingFieldSelectionSet and QueryDirectives is a supplier of sorts - eg a lazy pattern
DataFetchingFieldSelectionSet fieldCollector = DataFetchingFieldSelectionSetImpl.newCollector(executionContext.getGraphQLSchema(), fieldType, normalizedFieldSupplier);
QueryDirectives queryDirectives = new QueryDirectivesImpl(field, executionContext.getGraphQLSchema(), executionContext.getVariables());
DataFetchingEnvironment environment = newDataFetchingEnvironment(executionContext).source(parameters.getSource()).localContext(parameters.getLocalContext()).arguments(argumentValues).fieldDefinition(fieldDef).mergedField(parameters.getField()).fieldType(fieldType).executionStepInfo(executionStepInfo).parentType(parentType).selectionSet(fieldCollector).queryDirectives(queryDirectives).build();
DataFetcher<?> dataFetcher = codeRegistry.getDataFetcher(parentType, fieldDef);
Instrumentation instrumentation = executionContext.getInstrumentation();
InstrumentationFieldFetchParameters instrumentationFieldFetchParams = new InstrumentationFieldFetchParameters(executionContext, environment, parameters, dataFetcher instanceof TrivialDataFetcher);
InstrumentationContext<Object> fetchCtx = instrumentation.beginFieldFetch(instrumentationFieldFetchParams);
CompletableFuture<Object> fetchedValue;
dataFetcher = instrumentation.instrumentDataFetcher(dataFetcher, instrumentationFieldFetchParams);
ExecutionId executionId = executionContext.getExecutionId();
try {
Object fetchedValueRaw = dataFetcher.get(environment);
fetchedValue = Async.toCompletableFuture(fetchedValueRaw);
} catch (Exception e) {
if (logNotSafe.isDebugEnabled()) {
logNotSafe.debug(String.format("'%s', field '%s' fetch threw exception", executionId, executionStepInfo.get().getPath()), e);
}
fetchedValue = new CompletableFuture<>();
fetchedValue.completeExceptionally(e);
}
fetchCtx.onDispatched(fetchedValue);
return fetchedValue.handle((result, exception) -> {
fetchCtx.onCompleted(result, exception);
if (exception != null) {
return handleFetchingException(executionContext, environment, exception);
} else {
return CompletableFuture.completedFuture(result);
}
}).thenCompose(Function.identity()).thenApply(result -> unboxPossibleDataFetcherResult(executionContext, parameters, result));
}
use of graphql.schema.GraphQLCodeRegistry in project graphql-java by graphql-java.
the class ExecutionStepInfoFactory method newExecutionStepInfoForSubField.
public ExecutionStepInfo newExecutionStepInfoForSubField(ExecutionContext executionContext, MergedField mergedField, ExecutionStepInfo parentInfo) {
GraphQLObjectType parentType = (GraphQLObjectType) parentInfo.getUnwrappedNonNullType();
GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDef(executionContext.getGraphQLSchema(), parentType, mergedField.getName());
GraphQLOutputType fieldType = fieldDefinition.getType();
List<Argument> fieldArgs = mergedField.getArguments();
GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry();
Supplier<Map<String, Object>> argumentValues = FpKit.intraThreadMemoize(() -> valuesResolver.getArgumentValues(codeRegistry, fieldDefinition.getArguments(), fieldArgs, executionContext.getVariables()));
ResultPath newPath = parentInfo.getPath().segment(mergedField.getResultKey());
return parentInfo.transform(builder -> builder.parentInfo(parentInfo).type(fieldType).fieldDefinition(fieldDefinition).fieldContainer(parentType).field(mergedField).path(newPath).arguments(argumentValues));
}
use of graphql.schema.GraphQLCodeRegistry in project graphql-java by graphql-java.
the class NodeVisitorWithTypeTracking method visitField.
@Override
public TraversalControl visitField(Field field, TraverserContext<Node> context) {
QueryTraversalContext parentEnv = context.getVarFromParents(QueryTraversalContext.class);
GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDef(schema, (GraphQLCompositeType) unwrapAll(parentEnv.getOutputType()), field.getName());
boolean isTypeNameIntrospectionField = fieldDefinition == schema.getIntrospectionTypenameFieldDefinition();
GraphQLFieldsContainer fieldsContainer = !isTypeNameIntrospectionField ? (GraphQLFieldsContainer) unwrapAll(parentEnv.getOutputType()) : null;
GraphQLCodeRegistry codeRegistry = schema.getCodeRegistry();
Map<String, Object> argumentValues = valuesResolver.getArgumentValues(codeRegistry, fieldDefinition.getArguments(), field.getArguments(), variables);
QueryVisitorFieldEnvironment environment = new QueryVisitorFieldEnvironmentImpl(isTypeNameIntrospectionField, field, fieldDefinition, parentEnv.getOutputType(), fieldsContainer, parentEnv.getEnvironment(), argumentValues, parentEnv.getSelectionSetContainer(), context, schema);
if (context.getPhase() == LEAVE) {
postOrderCallback.visitField(environment);
return TraversalControl.CONTINUE;
}
if (!conditionalNodes.shouldInclude(variables, field.getDirectives())) {
return TraversalControl.ABORT;
}
TraversalControl traversalControl = preOrderCallback.visitFieldWithControl(environment);
GraphQLUnmodifiedType unmodifiedType = unwrapAll(fieldDefinition.getType());
QueryTraversalContext fieldEnv = (unmodifiedType instanceof GraphQLCompositeType) ? new QueryTraversalContext(fieldDefinition.getType(), environment, field) : // Terminal (scalar) node, EMPTY FRAME
new QueryTraversalContext(null, environment, field);
context.setVar(QueryTraversalContext.class, fieldEnv);
return traversalControl;
}
Aggregations