Search in sources :

Example 6 with GraphQLCodeRegistry

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);
}
Also used : DataFetchingEnvironment(graphql.schema.DataFetchingEnvironment) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) Internal(graphql.Internal) FetchedValue(graphql.execution.FetchedValue) ValuesResolver(graphql.execution.ValuesResolver) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) ExecutionContext(graphql.execution.ExecutionContext) ExecutableNormalizedField(graphql.normalized.ExecutableNormalizedField) Supplier(java.util.function.Supplier) DefaultValueUnboxer(graphql.execution.DefaultValueUnboxer) ArrayList(java.util.ArrayList) Collections.singletonList(java.util.Collections.singletonList) ImmutableKit(graphql.collect.ImmutableKit) ExecutionId(graphql.execution.ExecutionId) ExecutionStepInfo(graphql.execution.ExecutionStepInfo) ImmutableList(com.google.common.collect.ImmutableList) GraphQLError(graphql.GraphQLError) Map(java.util.Map) DataFetcher(graphql.schema.DataFetcher) GraphQLTypeUtil(graphql.schema.GraphQLTypeUtil) DataFetcherResult(graphql.execution.DataFetcherResult) Assert(graphql.Assert) LogKit(graphql.util.LogKit) Async(graphql.execution.Async) Logger(org.slf4j.Logger) ExceptionWhileDataFetching(graphql.ExceptionWhileDataFetching) MergedField(graphql.execution.MergedField) GraphQLOutputType(graphql.schema.GraphQLOutputType) ResultPath(graphql.execution.ResultPath) Field(graphql.language.Field) DataFetchingFieldSelectionSetImpl(graphql.schema.DataFetchingFieldSelectionSetImpl) ExecutableNormalizedOperation(graphql.normalized.ExecutableNormalizedOperation) List(java.util.List) QueryDirectivesImpl(graphql.execution.directives.QueryDirectivesImpl) CompletionStage(java.util.concurrent.CompletionStage) DataFetchingFieldSelectionSet(graphql.schema.DataFetchingFieldSelectionSet) FpKit(graphql.util.FpKit) DataFetchingEnvironmentImpl.newDataFetchingEnvironment(graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment) GraphQLFieldsContainer(graphql.schema.GraphQLFieldsContainer) Collections(java.util.Collections) DataFetchingFieldSelectionSet(graphql.schema.DataFetchingFieldSelectionSet) ExecutableNormalizedOperation(graphql.normalized.ExecutableNormalizedOperation) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) DataFetchingEnvironment(graphql.schema.DataFetchingEnvironment) DataFetchingEnvironmentImpl.newDataFetchingEnvironment(graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment) ExecutableNormalizedField(graphql.normalized.ExecutableNormalizedField) MergedField(graphql.execution.MergedField) Field(graphql.language.Field) GraphQLOutputType(graphql.schema.GraphQLOutputType) ExecutableNormalizedField(graphql.normalized.ExecutableNormalizedField) ResultPath(graphql.execution.ResultPath) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) QueryDirectivesImpl(graphql.execution.directives.QueryDirectivesImpl) GraphQLFieldsContainer(graphql.schema.GraphQLFieldsContainer) Map(java.util.Map) ExecutionId(graphql.execution.ExecutionId)

Example 7 with GraphQLCodeRegistry

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();
}
Also used : GraphQLOutputType(graphql.schema.GraphQLOutputType) GraphQLArgument(graphql.schema.GraphQLArgument) Argument(graphql.language.Argument) ExecutionStepInfo.newExecutionStepInfo(graphql.execution.ExecutionStepInfo.newExecutionStepInfo) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) GraphQLArgument(graphql.schema.GraphQLArgument) Map(java.util.Map)

Example 8 with GraphQLCodeRegistry

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));
}
Also used : GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) Instrumentation(graphql.execution.instrumentation.Instrumentation) DataFetchingEnvironment(graphql.schema.DataFetchingEnvironment) DataFetchingEnvironmentImpl.newDataFetchingEnvironment(graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment) CompletableFuture(java.util.concurrent.CompletableFuture) ExecutionStepInfo.newExecutionStepInfo(graphql.execution.ExecutionStepInfo.newExecutionStepInfo) ExecutableNormalizedField(graphql.normalized.ExecutableNormalizedField) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) DataFetchingFieldSelectionSet(graphql.schema.DataFetchingFieldSelectionSet) QueryDirectives(graphql.execution.directives.QueryDirectives) CoercingSerializeException(graphql.schema.CoercingSerializeException) CompletionException(java.util.concurrent.CompletionException) GraphQLOutputType(graphql.schema.GraphQLOutputType) GraphQLObjectType(graphql.schema.GraphQLObjectType) QueryDirectivesImpl(graphql.execution.directives.QueryDirectivesImpl) InstrumentationFieldFetchParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters) TrivialDataFetcher(graphql.TrivialDataFetcher) Map(java.util.Map)

Example 9 with GraphQLCodeRegistry

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));
}
Also used : GraphQLOutputType(graphql.schema.GraphQLOutputType) Argument(graphql.language.Argument) GraphQLObjectType(graphql.schema.GraphQLObjectType) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) Map(java.util.Map)

Example 10 with GraphQLCodeRegistry

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;
}
Also used : GraphQLCompositeType(graphql.schema.GraphQLCompositeType) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) GraphQLUnmodifiedType(graphql.schema.GraphQLUnmodifiedType) TraversalControl(graphql.util.TraversalControl) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) GraphQLFieldsContainer(graphql.schema.GraphQLFieldsContainer)

Aggregations

GraphQLCodeRegistry (graphql.schema.GraphQLCodeRegistry)13 GraphQLFieldDefinition (graphql.schema.GraphQLFieldDefinition)5 GraphQLObjectType (graphql.schema.GraphQLObjectType)5 GraphQLOutputType (graphql.schema.GraphQLOutputType)4 GraphQLSchema (graphql.schema.GraphQLSchema)4 Map (java.util.Map)4 DataFetcher (graphql.schema.DataFetcher)3 DataFetchingEnvironment (graphql.schema.DataFetchingEnvironment)3 ExecutionStepInfo.newExecutionStepInfo (graphql.execution.ExecutionStepInfo.newExecutionStepInfo)2 ValuesResolver (graphql.execution.ValuesResolver)2 QueryDirectivesImpl (graphql.execution.directives.QueryDirectivesImpl)2 Argument (graphql.language.Argument)2 ExecutableNormalizedField (graphql.normalized.ExecutableNormalizedField)2 DataFetchingEnvironmentImpl.newDataFetchingEnvironment (graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment)2 DataFetchingFieldSelectionSet (graphql.schema.DataFetchingFieldSelectionSet)2 GraphQLDirective (graphql.schema.GraphQLDirective)2 GraphQLFieldsContainer (graphql.schema.GraphQLFieldsContainer)2 ArrayList (java.util.ArrayList)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 ImmutableList (com.google.common.collect.ImmutableList)1