Search in sources :

Example 1 with InstrumentationContext

use of graphql.execution.instrumentation.InstrumentationContext 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 fetched object
 *
 * @throws NonNullableFieldWasNullException if a non null field resolves to a null value
 */
protected CompletableFuture<Object> fetchField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) {
    Field field = parameters.getField().get(0);
    GraphQLObjectType parentType = parameters.getTypeInfo().castType(GraphQLObjectType.class);
    GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field);
    GraphqlFieldVisibility fieldVisibility = executionContext.getGraphQLSchema().getFieldVisibility();
    Map<String, Object> argumentValues = valuesResolver.getArgumentValues(fieldVisibility, fieldDef.getArguments(), field.getArguments(), executionContext.getVariables());
    GraphQLOutputType fieldType = fieldDef.getType();
    DataFetchingFieldSelectionSet fieldCollector = DataFetchingFieldSelectionSetImpl.newCollector(executionContext, fieldType, parameters.getField());
    ExecutionTypeInfo fieldTypeInfo = fieldTypeInfo(parameters, fieldDef);
    DataFetchingEnvironment environment = newDataFetchingEnvironment(executionContext).source(parameters.getSource()).arguments(argumentValues).fieldDefinition(fieldDef).fields(parameters.getField()).fieldType(fieldType).fieldTypeInfo(fieldTypeInfo).parentType(parentType).selectionSet(fieldCollector).build();
    Instrumentation instrumentation = executionContext.getInstrumentation();
    InstrumentationFieldFetchParameters instrumentationFieldFetchParams = new InstrumentationFieldFetchParameters(executionContext, fieldDef, environment);
    InstrumentationContext<Object> fetchCtx = instrumentation.beginFieldFetch(instrumentationFieldFetchParams);
    CompletableFuture<Object> fetchedValue;
    DataFetcher dataFetcher = fieldDef.getDataFetcher();
    dataFetcher = instrumentation.instrumentDataFetcher(dataFetcher, instrumentationFieldFetchParams);
    ExecutionId executionId = executionContext.getExecutionId();
    try {
        log.debug("'{}' fetching field '{}' using data fetcher '{}'...", executionId, fieldTypeInfo.getPath(), dataFetcher.getClass().getName());
        Object fetchedValueRaw = dataFetcher.get(environment);
        log.debug("'{}' field '{}' fetch returned '{}'", executionId, fieldTypeInfo.getPath(), fetchedValueRaw == null ? "null" : fetchedValueRaw.getClass().getName());
        fetchedValue = Async.toCompletableFuture(fetchedValueRaw);
    } catch (Exception e) {
        log.debug(String.format("'%s', field '%s' fetch threw exception", executionId, fieldTypeInfo.getPath()), e);
        fetchedValue = new CompletableFuture<>();
        fetchedValue.completeExceptionally(e);
    }
    fetchCtx.onDispatched(fetchedValue);
    return fetchedValue.handle((result, exception) -> {
        fetchCtx.onCompleted(result, exception);
        if (exception != null) {
            handleFetchingException(executionContext, parameters, field, fieldDef, argumentValues, environment, exception);
            return null;
        } else {
            return result;
        }
    }).thenApply(result -> unboxPossibleDataFetcherResult(executionContext, parameters, result)).thenApply(this::unboxPossibleOptional);
}
Also used : IntStream(java.util.stream.IntStream) DataFetchingEnvironment(graphql.schema.DataFetchingEnvironment) DataFetchingEnvironmentBuilder.newDataFetchingEnvironment(graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment) Array(java.lang.reflect.Array) GraphQLScalarType(graphql.schema.GraphQLScalarType) CompletableFuture.completedFuture(java.util.concurrent.CompletableFuture.completedFuture) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) LoggerFactory(org.slf4j.LoggerFactory) OptionalDouble(java.util.OptionalDouble) GraphQLInterfaceType(graphql.schema.GraphQLInterfaceType) GraphQLUnionType(graphql.schema.GraphQLUnionType) CompletableFuture(java.util.concurrent.CompletableFuture) GraphQLType(graphql.schema.GraphQLType) OptionalInt(java.util.OptionalInt) ArrayList(java.util.ArrayList) ExecutionResult(graphql.ExecutionResult) Introspection(graphql.introspection.Introspection) OptionalLong(java.util.OptionalLong) InstrumentationFieldFetchParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters) Map(java.util.Map) InstrumentationFieldCompleteParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters) DataFetcher(graphql.schema.DataFetcher) GraphQLSchema(graphql.schema.GraphQLSchema) ExecutionTypeInfo.newTypeInfo(graphql.execution.ExecutionTypeInfo.newTypeInfo) ExecutionResultImpl(graphql.ExecutionResultImpl) TypeMismatchError(graphql.TypeMismatchError) SerializationError(graphql.SerializationError) TypeResolutionEnvironment(graphql.TypeResolutionEnvironment) GraphQLObjectType(graphql.schema.GraphQLObjectType) CoercingSerializeException(graphql.schema.CoercingSerializeException) Logger(org.slf4j.Logger) PublicSpi(graphql.PublicSpi) GraphqlFieldVisibility(graphql.schema.visibility.GraphqlFieldVisibility) GraphQLOutputType(graphql.schema.GraphQLOutputType) CompletionException(java.util.concurrent.CompletionException) Field(graphql.language.Field) DataFetchingFieldSelectionSetImpl(graphql.schema.DataFetchingFieldSelectionSetImpl) InstrumentationContext(graphql.execution.instrumentation.InstrumentationContext) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) GraphQLList(graphql.schema.GraphQLList) Instrumentation(graphql.execution.instrumentation.Instrumentation) DataFetchingFieldSelectionSet(graphql.schema.DataFetchingFieldSelectionSet) Optional(java.util.Optional) InstrumentationFieldParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldParameters) GraphQLEnumType(graphql.schema.GraphQLEnumType) FieldCollectorParameters.newParameters(graphql.execution.FieldCollectorParameters.newParameters) DataFetchingFieldSelectionSet(graphql.schema.DataFetchingFieldSelectionSet) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) Instrumentation(graphql.execution.instrumentation.Instrumentation) DataFetchingEnvironment(graphql.schema.DataFetchingEnvironment) DataFetchingEnvironmentBuilder.newDataFetchingEnvironment(graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment) CoercingSerializeException(graphql.schema.CoercingSerializeException) CompletionException(java.util.concurrent.CompletionException) Field(graphql.language.Field) GraphqlFieldVisibility(graphql.schema.visibility.GraphqlFieldVisibility) GraphQLOutputType(graphql.schema.GraphQLOutputType) CompletableFuture(java.util.concurrent.CompletableFuture) GraphQLObjectType(graphql.schema.GraphQLObjectType) InstrumentationFieldFetchParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters) DataFetcher(graphql.schema.DataFetcher)

Example 2 with InstrumentationContext

use of graphql.execution.instrumentation.InstrumentationContext in project graphql-java by graphql-java.

the class GraphQL method executeAsync.

/**
 * Executes the graphql query using the provided input object
 * <p>
 * This will return a promise (aka {@link CompletableFuture}) to provide a {@link ExecutionResult}
 * which is the result of executing the provided query.
 *
 * @param executionInput {@link ExecutionInput}
 *
 * @return a promise to an {@link ExecutionResult} which can include errors
 */
public CompletableFuture<ExecutionResult> executeAsync(ExecutionInput executionInput) {
    try {
        log.debug("Executing request. operation name: '{}'. query: '{}'. variables '{}'", executionInput.getOperationName(), executionInput.getQuery(), executionInput.getVariables());
        InstrumentationState instrumentationState = instrumentation.createState();
        InstrumentationExecutionParameters inputInstrumentationParameters = new InstrumentationExecutionParameters(executionInput, this.graphQLSchema, instrumentationState);
        executionInput = instrumentation.instrumentExecutionInput(executionInput, inputInstrumentationParameters);
        InstrumentationExecutionParameters instrumentationParameters = new InstrumentationExecutionParameters(executionInput, this.graphQLSchema, instrumentationState);
        InstrumentationContext<ExecutionResult> executionInstrumentation = instrumentation.beginExecution(instrumentationParameters);
        GraphQLSchema graphQLSchema = instrumentation.instrumentSchema(this.graphQLSchema, instrumentationParameters);
        CompletableFuture<ExecutionResult> executionResult = parseValidateAndExecute(executionInput, graphQLSchema, instrumentationState);
        // 
        // finish up instrumentation
        executionResult = executionResult.whenComplete(executionInstrumentation::onCompleted);
        // 
        // allow instrumentation to tweak the result
        executionResult = executionResult.thenCompose(result -> instrumentation.instrumentExecutionResult(result, instrumentationParameters));
        return executionResult;
    } catch (AbortExecutionException abortException) {
        ExecutionResultImpl executionResult = new ExecutionResultImpl(abortException);
        if (!abortException.getUnderlyingErrors().isEmpty()) {
            executionResult = new ExecutionResultImpl(abortException.getUnderlyingErrors());
        }
        return CompletableFuture.completedFuture(executionResult);
    }
}
Also used : Execution(graphql.execution.Execution) ParseCancellationException(org.antlr.v4.runtime.misc.ParseCancellationException) AbortExecutionException(graphql.execution.AbortExecutionException) ExecutionStrategy(graphql.execution.ExecutionStrategy) InstrumentationExecutionParameters(graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) UnaryOperator(java.util.function.UnaryOperator) InstrumentationState(graphql.execution.instrumentation.InstrumentationState) PreparsedDocumentEntry(graphql.execution.preparsed.PreparsedDocumentEntry) AtomicReference(java.util.concurrent.atomic.AtomicReference) ExecutionId(graphql.execution.ExecutionId) Parser(graphql.parser.Parser) SubscriptionExecutionStrategy(graphql.execution.SubscriptionExecutionStrategy) Map(java.util.Map) AsyncExecutionStrategy(graphql.execution.AsyncExecutionStrategy) GraphQLSchema(graphql.schema.GraphQLSchema) NoOpPreparsedDocumentProvider(graphql.execution.preparsed.NoOpPreparsedDocumentProvider) Logger(org.slf4j.Logger) PreparsedDocumentProvider(graphql.execution.preparsed.PreparsedDocumentProvider) CompletionException(java.util.concurrent.CompletionException) InvalidSyntaxError.toInvalidSyntaxError(graphql.InvalidSyntaxError.toInvalidSyntaxError) ExecutionIdProvider(graphql.execution.ExecutionIdProvider) InstrumentationContext(graphql.execution.instrumentation.InstrumentationContext) Consumer(java.util.function.Consumer) InstrumentationValidationParameters(graphql.execution.instrumentation.parameters.InstrumentationValidationParameters) Document(graphql.language.Document) ValidationError(graphql.validation.ValidationError) List(java.util.List) Instrumentation(graphql.execution.instrumentation.Instrumentation) Assert.assertNotNull(graphql.Assert.assertNotNull) SimpleInstrumentation(graphql.execution.instrumentation.SimpleInstrumentation) AsyncSerialExecutionStrategy(graphql.execution.AsyncSerialExecutionStrategy) Validator(graphql.validation.Validator) InstrumentationState(graphql.execution.instrumentation.InstrumentationState) InstrumentationExecutionParameters(graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters) AbortExecutionException(graphql.execution.AbortExecutionException) GraphQLSchema(graphql.schema.GraphQLSchema)

Aggregations

Instrumentation (graphql.execution.instrumentation.Instrumentation)2 InstrumentationContext (graphql.execution.instrumentation.InstrumentationContext)2 GraphQLSchema (graphql.schema.GraphQLSchema)2 List (java.util.List)2 Map (java.util.Map)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 CompletionException (java.util.concurrent.CompletionException)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2 Assert.assertNotNull (graphql.Assert.assertNotNull)1 ExecutionResult (graphql.ExecutionResult)1 ExecutionResultImpl (graphql.ExecutionResultImpl)1 InvalidSyntaxError.toInvalidSyntaxError (graphql.InvalidSyntaxError.toInvalidSyntaxError)1 PublicSpi (graphql.PublicSpi)1 SerializationError (graphql.SerializationError)1 TypeMismatchError (graphql.TypeMismatchError)1 TypeResolutionEnvironment (graphql.TypeResolutionEnvironment)1 AbortExecutionException (graphql.execution.AbortExecutionException)1 AsyncExecutionStrategy (graphql.execution.AsyncExecutionStrategy)1 AsyncSerialExecutionStrategy (graphql.execution.AsyncSerialExecutionStrategy)1