Search in sources :

Example 6 with Instrumentation

use of graphql.execution.instrumentation.Instrumentation 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 7 with Instrumentation

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

the class ExecutionStrategy method resolveField.

/**
 * Called to fetch a value for a field and resolve it further in terms of the graphql query.  This will call
 * #fetchField followed by #completeField and the completed {@link ExecutionResult} is returned.
 * <p>
 * An execution strategy can iterate the fields to be executed and call this method for each one
 * <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 an {@link ExecutionResult}
 *
 * @throws NonNullableFieldWasNullException if a non null field resolves to a null value
 */
protected CompletableFuture<ExecutionResult> resolveField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) {
    GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().get(0));
    Instrumentation instrumentation = executionContext.getInstrumentation();
    InstrumentationContext<ExecutionResult> fieldCtx = instrumentation.beginField(new InstrumentationFieldParameters(executionContext, fieldDef, fieldTypeInfo(parameters, fieldDef)));
    CompletableFuture<ExecutionResult> result = fetchField(executionContext, parameters).thenCompose((fetchedValue) -> completeField(executionContext, parameters, fetchedValue));
    fieldCtx.onDispatched(result);
    result.whenComplete(fieldCtx::onCompleted);
    return result;
}
Also used : GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) Instrumentation(graphql.execution.instrumentation.Instrumentation) ExecutionResult(graphql.ExecutionResult) InstrumentationFieldParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldParameters)

Example 8 with Instrumentation

use of graphql.execution.instrumentation.Instrumentation 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)

Example 9 with Instrumentation

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

the class BatchedExecutionStrategy method fetchData.

private CompletableFuture<FetchedValues> fetchData(ExecutionContext executionContext, ExecutionStrategyParameters parameters, String fieldName, ExecutionNode node, GraphQLFieldDefinition fieldDef) {
    GraphQLObjectType parentType = node.getType();
    List<Field> fields = node.getFields().get(fieldName);
    List<MapOrList> parentResults = node.getParentResults();
    GraphqlFieldVisibility fieldVisibility = executionContext.getGraphQLSchema().getFieldVisibility();
    Map<String, Object> argumentValues = valuesResolver.getArgumentValues(fieldVisibility, fieldDef.getArguments(), fields.get(0).getArguments(), executionContext.getVariables());
    GraphQLOutputType fieldType = fieldDef.getType();
    DataFetchingFieldSelectionSet fieldCollector = DataFetchingFieldSelectionSetImpl.newCollector(executionContext, fieldType, fields);
    DataFetchingEnvironment environment = newDataFetchingEnvironment(executionContext).source(node.getSources()).arguments(argumentValues).fieldDefinition(fieldDef).fields(fields).fieldType(fieldDef.getType()).fieldTypeInfo(parameters.getTypeInfo()).parentType(parentType).selectionSet(fieldCollector).build();
    Instrumentation instrumentation = executionContext.getInstrumentation();
    InstrumentationFieldFetchParameters instrumentationFieldFetchParameters = new InstrumentationFieldFetchParameters(executionContext, fieldDef, environment);
    InstrumentationContext<Object> fetchCtx = instrumentation.beginFieldFetch(instrumentationFieldFetchParameters);
    CompletableFuture<Object> fetchedValue;
    try {
        DataFetcher<?> dataFetcher = instrumentation.instrumentDataFetcher(getDataFetcher(fieldDef), instrumentationFieldFetchParameters);
        Object fetchedValueRaw = dataFetcher.get(environment);
        fetchedValue = Async.toCompletableFuture(fetchedValueRaw);
    } catch (Exception e) {
        fetchedValue = new CompletableFuture<>();
        fetchedValue.completeExceptionally(e);
    }
    return fetchedValue.thenApply((result) -> assertResult(parentResults, result)).whenComplete(fetchCtx::onCompleted).handle(handleResult(executionContext, parameters, parentResults, fields, fieldDef, argumentValues, environment));
}
Also used : DataFetchingFieldSelectionSet(graphql.schema.DataFetchingFieldSelectionSet) Instrumentation(graphql.execution.instrumentation.Instrumentation) DataFetchingEnvironment(graphql.schema.DataFetchingEnvironment) DataFetchingEnvironmentBuilder.newDataFetchingEnvironment(graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment) 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)

Example 10 with Instrumentation

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

the class ExecutorServiceExecutionStrategy method execute.

@Override
public CompletableFuture<ExecutionResult> execute(final ExecutionContext executionContext, final ExecutionStrategyParameters parameters) {
    if (executorService == null) {
        return new AsyncExecutionStrategy().execute(executionContext, parameters);
    }
    Instrumentation instrumentation = executionContext.getInstrumentation();
    InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters);
    InstrumentationContext<ExecutionResult> executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters);
    Map<String, List<Field>> fields = parameters.getFields();
    Map<String, Future<CompletableFuture<ExecutionResult>>> futures = new LinkedHashMap<>();
    for (String fieldName : fields.keySet()) {
        final List<Field> currentField = fields.get(fieldName);
        ExecutionPath fieldPath = parameters.getPath().segment(fieldName);
        ExecutionStrategyParameters newParameters = parameters.transform(builder -> builder.field(currentField).path(fieldPath));
        Callable<CompletableFuture<ExecutionResult>> resolveField = () -> resolveField(executionContext, newParameters);
        futures.put(fieldName, executorService.submit(resolveField));
    }
    CompletableFuture<ExecutionResult> overallResult = new CompletableFuture<>();
    executionStrategyCtx.onDispatched(overallResult);
    try {
        Map<String, Object> results = new LinkedHashMap<>();
        for (String fieldName : futures.keySet()) {
            ExecutionResult executionResult;
            try {
                executionResult = futures.get(fieldName).get().join();
            } catch (CompletionException e) {
                if (e.getCause() instanceof NonNullableFieldWasNullException) {
                    assertNonNullFieldPrecondition((NonNullableFieldWasNullException) e.getCause());
                    results = null;
                    break;
                } else {
                    throw e;
                }
            }
            results.put(fieldName, executionResult != null ? executionResult.getData() : null);
        }
        ExecutionResultImpl executionResult = new ExecutionResultImpl(results, executionContext.getErrors());
        overallResult.complete(executionResult);
        overallResult.whenComplete(executionStrategyCtx::onCompleted);
        return overallResult;
    } catch (InterruptedException | ExecutionException e) {
        executionStrategyCtx.onCompleted(null, e);
        throw new GraphQLException(e);
    }
}
Also used : Instrumentation(graphql.execution.instrumentation.Instrumentation) LinkedHashMap(java.util.LinkedHashMap) Field(graphql.language.Field) CompletableFuture(java.util.concurrent.CompletableFuture) InstrumentationExecutionStrategyParameters(graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters) List(java.util.List) GraphQLException(graphql.GraphQLException) ExecutionException(java.util.concurrent.ExecutionException) ExecutionResult(graphql.ExecutionResult) CompletionException(java.util.concurrent.CompletionException) ExecutionResultImpl(graphql.ExecutionResultImpl) CompletableFuture(java.util.concurrent.CompletableFuture) Future(java.util.concurrent.Future) InstrumentationExecutionStrategyParameters(graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters)

Aggregations

Instrumentation (graphql.execution.instrumentation.Instrumentation)12 ExecutionResult (graphql.ExecutionResult)9 Field (graphql.language.Field)7 List (java.util.List)7 CompletableFuture (java.util.concurrent.CompletableFuture)7 ArrayList (java.util.ArrayList)6 GraphQLFieldDefinition (graphql.schema.GraphQLFieldDefinition)5 GraphQLObjectType (graphql.schema.GraphQLObjectType)4 GraphqlFieldVisibility (graphql.schema.visibility.GraphqlFieldVisibility)4 CompletionException (java.util.concurrent.CompletionException)4 ExecutionResultImpl (graphql.ExecutionResultImpl)3 InstrumentationExecutionStrategyParameters (graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters)3 InstrumentationFieldParameters (graphql.execution.instrumentation.parameters.InstrumentationFieldParameters)3 GraphQLSchema (graphql.schema.GraphQLSchema)3 InstrumentationContext (graphql.execution.instrumentation.InstrumentationContext)2 SimpleInstrumentation (graphql.execution.instrumentation.SimpleInstrumentation)2 InstrumentationFieldCompleteParameters (graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters)2 InstrumentationFieldFetchParameters (graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters)2 DataFetchingEnvironment (graphql.schema.DataFetchingEnvironment)2 DataFetchingEnvironmentBuilder.newDataFetchingEnvironment (graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment)2