use of graphql.normalized.ExecutableNormalizedField in project graphql-java by graphql-java.
the class DataFetchingFieldSelectionSetImpl method computeValuesLazily.
private void computeValuesLazily() {
if (computedValues) {
return;
}
// this supplier is a once only thread synced call - so do it outside this lock
// if only to have only 1 lock in action at a time
ExecutableNormalizedField currentNormalisedField = normalizedFieldSupplier.get();
synchronized (this) {
if (computedValues) {
return;
}
flattenedFieldsForGlobSearching = new LinkedHashSet<>();
normalisedSelectionSetFields = new LinkedHashMap<>();
ImmutableList.Builder<SelectedField> immediateFieldsBuilder = ImmutableList.builder();
traverseSubSelectedFields(currentNormalisedField, immediateFieldsBuilder, "", "", true);
immediateFields = immediateFieldsBuilder.build();
computedValues = true;
}
}
use of graphql.normalized.ExecutableNormalizedField 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.normalized.ExecutableNormalizedField 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.normalized.ExecutableNormalizedField in project graphql-java by graphql-java.
the class NQBenchmark2 method main.
public static void main(String[] args) {
MyState myState = new MyState();
myState.setup();
ExecutableNormalizedOperation executableNormalizedOperation = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(myState.schema, myState.document, null, Collections.emptyMap());
// System.out.println(printTree(normalizedQuery));
ImmutableListMultimap<Field, ExecutableNormalizedField> fieldToNormalizedField = executableNormalizedOperation.getFieldToNormalizedField();
System.out.println(fieldToNormalizedField.size());
// for (Field field : fieldToNormalizedField.keySet()) {
// System.out.println("field" + field);
// System.out.println("nf count:" + fieldToNormalizedField.get(field).size());
// if (field.getName().equals("field49")) {
// ImmutableList<NormalizedField> normalizedFields = fieldToNormalizedField.get(field);
// for (NormalizedField nf : normalizedFields) {
// System.out.println(nf);
// }
// }
// }
// System.out.println("fields size:" + normalizedQuery.getFieldToNormalizedField().size());
}
use of graphql.normalized.ExecutableNormalizedField in project graphql-java by graphql-java.
the class DataFetchingFieldSelectionSetImpl method traverseSubSelectedFields.
private void traverseSubSelectedFields(ExecutableNormalizedField currentNormalisedField, ImmutableList.Builder<SelectedField> immediateFieldsBuilder, String qualifiedFieldPrefix, String simpleFieldPrefix, boolean firstLevel) {
List<ExecutableNormalizedField> children = currentNormalisedField.getChildren();
for (ExecutableNormalizedField normalizedSubSelectedField : children) {
String typeQualifiedName = mkTypeQualifiedName(normalizedSubSelectedField);
String simpleName = normalizedSubSelectedField.getName();
String globQualifiedName = mkFieldGlobName(qualifiedFieldPrefix, typeQualifiedName);
String globSimpleName = mkFieldGlobName(simpleFieldPrefix, simpleName);
flattenedFieldsForGlobSearching.add(globQualifiedName);
// put in entries for the simple names - eg `Invoice.payments/Payment.amount` becomes `payments/amount`
flattenedFieldsForGlobSearching.add(globSimpleName);
SelectedFieldImpl selectedField = new SelectedFieldImpl(globSimpleName, globQualifiedName, normalizedSubSelectedField, schema);
if (firstLevel) {
immediateFieldsBuilder.add(selectedField);
}
normalisedSelectionSetFields.computeIfAbsent(globQualifiedName, newList()).add(selectedField);
normalisedSelectionSetFields.computeIfAbsent(globSimpleName, newList()).add(selectedField);
if (normalizedSubSelectedField.hasChildren()) {
traverseSubSelectedFields(normalizedSubSelectedField, immediateFieldsBuilder, globQualifiedName, globSimpleName, false);
}
}
}
Aggregations