X Tutup
Skip to content
Open
13 changes: 12 additions & 1 deletion src/main/java/graphql/execution/ExecutionContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import graphql.execution.incremental.IncrementalCallState;
import graphql.execution.instrumentation.Instrumentation;
import graphql.execution.instrumentation.InstrumentationState;
import graphql.execution.instrumentation.parameters.InstrumentationCreateExecutableNormalizedOperationParameters;
import graphql.language.Document;
import graphql.language.FragmentDefinition;
import graphql.language.OperationDefinition;
Expand Down Expand Up @@ -100,7 +101,7 @@ public class ExecutionContext {
this.localContext = builder.localContext;
this.executionInput = builder.executionInput;
this.dataLoaderDispatcherStrategy = builder.dataLoaderDispatcherStrategy;
this.queryTree = FpKit.interThreadMemoize(() -> ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(graphQLSchema, operationDefinition, fragmentsByName, coercedVariables));
this.queryTree = FpKit.interThreadMemoize(this::createExecutableNormalizedOperation);
this.propagateErrorsOnNonNullContractFailure = builder.propagateErrorsOnNonNullContractFailure;
this.engineRunningState = builder.engineRunningState;
}
Expand Down Expand Up @@ -368,6 +369,16 @@ public ResultNodesInfo getResultNodesInfo() {
return resultNodesInfo;
}

private ExecutableNormalizedOperation createExecutableNormalizedOperation() {
var parameters = new InstrumentationCreateExecutableNormalizedOperationParameters(executionInput, graphQLSchema);
var instrument = instrumentation.beginCreateExecutableNormalizedOperation(parameters, instrumentationState);
var result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(graphQLSchema, operationDefinition, fragmentsByName, coercedVariables);
if (instrument != null) {
instrument.onCompleted(result, null);
}
return result;
}

@Internal
public boolean hasIncrementalSupport() {
GraphQLContext graphqlContext = getGraphQLContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import graphql.execution.Async;
import graphql.execution.ExecutionContext;
import graphql.execution.FieldValueInfo;
import graphql.execution.instrumentation.parameters.InstrumentationCreateExecutableNormalizedOperationParameters;
import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters;
import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters;
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters;
Expand All @@ -17,6 +18,7 @@
import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters;
import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters;
import graphql.language.Document;
import graphql.normalized.ExecutableNormalizedOperation;
import graphql.schema.DataFetcher;
import graphql.schema.GraphQLSchema;
import graphql.validation.ValidationError;
Expand Down Expand Up @@ -126,6 +128,12 @@ public InstrumentationContext<Document> beginParse(InstrumentationExecutionParam
return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginParse(parameters, specificState));
}

@Override
public InstrumentationContext<ExecutableNormalizedOperation> beginCreateExecutableNormalizedOperation(InstrumentationCreateExecutableNormalizedOperationParameters parameters, InstrumentationState state) {
return chainedCtx(state, (instrumentation, specificState) ->
instrumentation.beginCreateExecutableNormalizedOperation(parameters, specificState));
}


@Override
public InstrumentationContext<List<ValidationError>> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters;
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters;
import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters;
import graphql.execution.instrumentation.parameters.InstrumentationCreateExecutableNormalizedOperationParameters;
import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters;
import graphql.language.Document;
import graphql.normalized.ExecutableNormalizedOperation;
import graphql.schema.DataFetcher;
import graphql.schema.GraphQLSchema;
import graphql.validation.ValidationError;
Expand Down Expand Up @@ -120,6 +122,19 @@ default InstrumentationContext<ExecutionResult> beginExecuteOperation(Instrument
return noOp();
}

/**
* This is called just before the creation of the executable normalized operation is started.
*
* @param parameters the parameters to this step
* @param state the state created during the call to {@link #createState(InstrumentationCreateStateParameters)}
* @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null)
*/
@ExperimentalApi
@Nullable
default InstrumentationContext<ExecutableNormalizedOperation> beginCreateExecutableNormalizedOperation(InstrumentationCreateExecutableNormalizedOperationParameters parameters, InstrumentationState state) {
return noOp();
}

/**
* This is called each time an {@link graphql.execution.ExecutionStrategy} is invoked, which may be multiple times
* per query as the engine recursively descends over the query.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters;
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters;
import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters;
import graphql.execution.instrumentation.parameters.InstrumentationCreateExecutableNormalizedOperationParameters;
import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters;
import graphql.language.Document;
import graphql.normalized.ExecutableNormalizedOperation;
import graphql.validation.ValidationError;
import org.jspecify.annotations.Nullable;

Expand Down Expand Up @@ -83,6 +85,11 @@ public ExecutionStrategyInstrumentationContext beginExecutionStrategy(Instrument
return runAll(state, (instrumentation, specificState) -> instrumentation.beginExecuteObject(parameters, specificState));
}

@Override
public @Nullable InstrumentationContext<ExecutableNormalizedOperation> beginCreateExecutableNormalizedOperation(InstrumentationCreateExecutableNormalizedOperationParameters parameters, InstrumentationState state) {
return runAll(state, (instrumentation, specificState) -> instrumentation.beginCreateExecutableNormalizedOperation(parameters, specificState));
}

@Override
public InstrumentationContext<ExecutionResult> beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) {
return runAll(state, (instrumentation, specificState) -> instrumentation.beginSubscribedFieldEvent(parameters, specificState));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package graphql.execution.instrumentation.parameters;

import graphql.ExecutionInput;
import graphql.ExperimentalApi;
import graphql.execution.instrumentation.Instrumentation;
import graphql.schema.GraphQLSchema;

/**
* Parameters sent to {@link Instrumentation} methods
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
@ExperimentalApi
public class InstrumentationCreateExecutableNormalizedOperationParameters extends InstrumentationExecutionParameters {
public InstrumentationCreateExecutableNormalizedOperationParameters(ExecutionInput executionInput, GraphQLSchema schema) {
super(executionInput, schema);
}
}
1 change: 1 addition & 0 deletions src/test/groovy/graphql/StarWarsData.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class StarWarsData {
static TypeResolver characterTypeResolver = new TypeResolver() {
@Override
GraphQLObjectType getType(TypeResolutionEnvironment env) {
env.getSelectionSet().getFields() // Used to validate instrumentation
def id = env.getObject().id
if (humanData[id] != null)
return StarWarsSchema.humanType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class ChainedInstrumentationStateTest extends Specification {
"start:fetch-hero",
"end:fetch-hero",
"start:complete-hero",
"start:create-executable-normalized-operation",
"end:create-executable-normalized-operation",

"start:execute-object",

Expand Down Expand Up @@ -143,6 +145,8 @@ class ChainedInstrumentationStateTest extends Specification {
"start:fetch-hero",
"end:fetch-hero",
"start:complete-hero",
"start:create-executable-normalized-operation",
"end:create-executable-normalized-operation",

"start:execute-object",

Expand Down Expand Up @@ -183,6 +187,8 @@ class ChainedInstrumentationStateTest extends Specification {
"start:fetch-hero",
"end:fetch-hero",
"start:complete-hero",
"start:create-executable-normalized-operation",
"end:create-executable-normalized-operation",

"start:execute-object",

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ class InstrumentationTest extends Specification {
"onDispatched:fetch-hero",
"end:fetch-hero",
"start:complete-hero",
"start:create-executable-normalized-operation",
"end:create-executable-normalized-operation",
"start:execute-object",
"start:field-id",
"start:fetch-id",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import graphql.execution.instrumentation.parameters.InstrumentationExecutionStra
import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters
import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters
import graphql.execution.instrumentation.parameters.InstrumentationCreateExecutableNormalizedOperationParameters
import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters
import graphql.language.Document
import graphql.normalized.ExecutableNormalizedOperation
import graphql.schema.DataFetcher
import graphql.schema.DataFetchingEnvironment
import graphql.schema.GraphQLSchema
Expand Down Expand Up @@ -73,6 +75,12 @@ class ModernTestingInstrumentation implements Instrumentation {
return new TestingInstrumentContext("execute-operation", executionList, throwableList, useOnDispatch)
}

@Override
InstrumentationContext<ExecutableNormalizedOperation> beginCreateExecutableNormalizedOperation(InstrumentationCreateExecutableNormalizedOperationParameters parameters, InstrumentationState state) {
assert state == instrumentationState
return new TestingInstrumentContext("create-executable-normalized-operation", executionList, throwableList, useOnDispatch)
}

@Override
InstrumentationContext<ExecutionResult> beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) {
assert state == instrumentationState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import graphql.execution.instrumentation.parameters.InstrumentationExecutionPara
import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters
import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters
import graphql.execution.instrumentation.parameters.InstrumentationCreateExecutableNormalizedOperationParameters
import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters
import graphql.language.Document
import graphql.normalized.ExecutableNormalizedOperation
import graphql.schema.DataFetcher
import graphql.validation.ValidationError

Expand Down Expand Up @@ -72,6 +74,12 @@ class NamedInstrumentation extends ModernTestingInstrumentation {
return super.beginFieldExecution(parameters, state)
}

@Override
InstrumentationContext<ExecutableNormalizedOperation> beginCreateExecutableNormalizedOperation(InstrumentationCreateExecutableNormalizedOperationParameters parameters, InstrumentationState state) {
assertState(state)
return super.beginCreateExecutableNormalizedOperation(parameters, state)
}

@Override
InstrumentationContext<Object> beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) {
assertState(state)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class NoContextChainedInstrumentationTest extends Specification {
"start:field-hero",
"start:fetch-hero",
"start:complete-hero",
"start:create-executable-normalized-operation",

"start:execute-object",

Expand Down
X Tutup