private static EventDescription CreateEvent( IExecutionContext executionContext) { IReadOnlyCollection <FieldSelection> selections = executionContext .CollectFields( executionContext.Operation.RootType, executionContext.Operation.Definition.SelectionSet, null); if (selections.Count == 1) { FieldSelection selection = selections.Single(); var arguments = new List <ArgumentNode>(); IVariableValueCollection variables = executionContext.Variables; foreach (ArgumentNode argument in selection.Selection.Arguments) { if (argument.Value is VariableNode v) { IValueNode value = variables.GetVariable <IValueNode>(v.Name.Value); arguments.Add(argument.WithValue(value)); } else { arguments.Add(argument); } } return(new EventDescription(selection.Field.Name, arguments)); } else { throw new QueryException(CoreResources.Subscriptions_SingleRootField); } }
private ResolverTask( ResolverTask parent, FieldSelection fieldSelection, Path path, IImmutableStack <object> source, IDictionary <string, object> result, Action propagateNonNullViolation) { _parent = parent; _executionContext = parent._executionContext; Source = source; ObjectType = fieldSelection.Field.DeclaringType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = path; _result = result; ScopedContextData = parent.ScopedContextData; _propagateNonNullViolation = propagateNonNullViolation; ResolverContext = new ResolverContext( parent._executionContext, this, parent._executionContext.RequestAborted); FieldDelegate = parent._executionContext.FieldHelper .CreateMiddleware(fieldSelection); }
private EventDescription CreateEvent( IExecutionContext executionContext) { IReadOnlyCollection <FieldSelection> selections = executionContext .FieldHelper.CollectFields( executionContext.Operation.RootType, executionContext.Operation.Definition.SelectionSet); if (selections.Count == 1) { FieldSelection selection = selections.Single(); Dictionary <string, ArgumentValue> argumentValues = selection .CoerceArgumentValues(executionContext.Variables); var arguments = new List <ArgumentNode>(); foreach (KeyValuePair <string, ArgumentValue> argumentValue in argumentValues) { IInputType argumentType = argumentValue.Value.Type; object value = argumentValue.Value.Value; arguments.Add(new ArgumentNode( argumentValue.Key, argumentType.ParseValue(value))); } return(new EventDescription(selection.Field.Name, arguments)); } else { // TODO : Error message throw new QueryException(); } }
private bool TryCompleteObjectValue( ExecutionContext executionContext, IResolverContext resolverContext, ImmutableStack <object> source, FieldSelection fieldSelection, IType fieldType, Path path, object fieldValue, Action <object> setValue) { ObjectType objectType = ResolveObjectType( resolverContext, fieldType, fieldValue); OrderedDictionary objectResult = new OrderedDictionary(); IReadOnlyCollection <FieldSelection> fields = executionContext .FieldResolver.CollectFields( objectType, fieldSelection.Node.SelectionSet, executionContext.Errors.Add); foreach (FieldSelection field in fields) { executionContext.NextBatch.Add(new FieldResolverTask( source.Push(fieldValue), objectType, field, path.Append(field.ResponseName), objectResult)); } setValue(objectResult); return(true); }
public void Coerce_InputObject_NonNullFieldIsNull() { // arrange DocumentNode document = Utf8GraphQLParser.Parse("{ foo(a: { a: { } }) }"); OperationDefinitionNode operation = document.Definitions .OfType <OperationDefinitionNode>().First(); ISchema schema = CreateSchema(); var fragments = new FragmentCollection( schema, document); var variables = new VariableCollection( TypeConversion.Default, new Dictionary <string, object>()); var collector = new FieldCollector(fragments, (f, s) => null); IReadOnlyCollection <FieldSelection> selections = collector.CollectFields(schema.QueryType, operation.SelectionSet, null); FieldSelection selection = selections.First(); // act Action action = () => selection.CoerceArguments(variables); // assert Assert.Throws <QueryException>(action).Errors.MatchSnapshot(); }
public static Dictionary <string, ArgumentValue> CoerceArgumentValues( this FieldSelection fieldSelection, IVariableCollection variables, Path path) { Dictionary <string, ArgumentValue> coercedArgumentValues = new Dictionary <string, ArgumentValue>(); Dictionary <string, IValueNode> argumentValues = fieldSelection.Selection.Arguments .Where(t => t.Value != null) .ToDictionary(t => t.Name.Value, t => t.Value); foreach (InputField argument in fieldSelection.Field.Arguments) { coercedArgumentValues[argument.Name] = CreateArgumentValue( argument, argumentValues, variables, message => QueryError.CreateArgumentError( message, path, fieldSelection.Nodes.First(), argument.Name)); } return(coercedArgumentValues); }
private static EventDescription CreateEvent( IExecutionContext executionContext) { IReadOnlyCollection <FieldSelection> selections = executionContext .CollectFields( executionContext.Operation.RootType, executionContext.Operation.Definition.SelectionSet, null); if (selections.Count == 1) { FieldSelection selection = selections.Single(); IReadOnlyDictionary <NameString, ArgumentValue> argumentValues = selection.CoerceArguments(executionContext.Variables); var arguments = new List <ArgumentNode>(); foreach (KeyValuePair <NameString, ArgumentValue> argValue in argumentValues) { IInputType argumentType = argValue.Value.Type; object value = argValue.Value.Value; arguments.Add(new ArgumentNode( argValue.Key, argumentType.ParseValue(value))); } return(new EventDescription(selection.Field.Name, arguments)); } else { throw new QueryException( CoreResources.Subscriptions_SingleRootField); } }
private void Initialize( IExecutionContext executionContext, FieldSelection fieldSelection, IImmutableStack <object> source, IDictionary <string, object> serializedResult) { _executionContext = executionContext; _serializedResult = serializedResult; _fieldSelection = fieldSelection; IsRoot = true; Path = Path.New(fieldSelection.ResponseName); Source = source; SourceObject = executionContext.Operation.RootValue; ScopedContextData = ImmutableDictionary <string, object> .Empty; _arguments = fieldSelection.CoerceArguments( executionContext.Variables, executionContext.Converter); string responseName = fieldSelection.ResponseName; PropagateNonNullViolation = () => { serializedResult[responseName] = null; }; }
private static void ResolveFieldSelection( ObjectType type, FieldNode fieldSelection, Action <QueryError> reportError, Dictionary <string, FieldSelection> fields) { NameString fieldName = fieldSelection.Name.Value; if (type.Fields.TryGetField(fieldName, out ObjectField field)) { string name = fieldSelection.Alias == null ? fieldSelection.Name.Value : fieldSelection.Alias.Value; if (fields.TryGetValue(name, out FieldSelection selection)) { fields[name] = selection.Merge(fieldSelection); } else { fields.Add(name, FieldSelection.Create( fieldSelection, field, name)); } } else { reportError(QueryError.CreateFieldError( "Could not resolve the specified field.", fieldSelection)); } }
public ResolverTask( IExecutionContext executionContext, ObjectType objectType, FieldSelection fieldSelection, Path path, ImmutableStack <object> source, OrderedDictionary result) { _executionContext = executionContext; Source = source; ObjectType = objectType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = path; Result = result; ResolverContext = new ResolverContext( executionContext, this, executionContext.CancellationToken); Options = executionContext.Options; ExecuteMiddleware = executionContext.GetMiddleware( objectType, fieldSelection.Selection); HasMiddleware = ExecuteMiddleware != null; }
public void Coerce_NonNullString_ToAbc() { // arrange DocumentNode document = Utf8GraphQLParser.Parse("{ bar (a: \"abc\") }"); OperationDefinitionNode operation = document.Definitions .OfType <OperationDefinitionNode>().First(); ISchema schema = CreateSchema(); var fragments = new FragmentCollection( schema, document); var variables = new VariableCollection( TypeConversion.Default, new Dictionary <string, object>()); var collector = new FieldCollector(fragments, (f, s) => null); IReadOnlyCollection <FieldSelection> selections = collector.CollectFields(schema.QueryType, operation.SelectionSet, Path.New("bar")); FieldSelection selection = selections.First(); var path = Path.New("bar"); // act IReadOnlyDictionary <NameString, ArgumentValue> arguments = selection.CoerceArguments(variables); // assert MatchSnapshot(arguments); }
private async Task ExecuteFieldResolverBatchAsync( ExecutionContext executionContext, List <FieldResolverTask> batch, CancellationToken cancellationToken) { List <(FieldResolverTask task, IResolverContext context, object resolverResult)> runningTasks = new List <(FieldResolverTask, IResolverContext, object)>(); foreach (FieldResolverTask task in batch) { IResolverContext resolverContext = new ResolverContext( executionContext, task); object resolverResult = task.FieldSelection.Field.Resolver( resolverContext, cancellationToken); runningTasks.Add((task, resolverContext, resolverResult)); } foreach (var runningTask in runningTasks) { FieldSelection fieldSelection = runningTask.task.FieldSelection; object fieldValue = await CompleteFieldValueAsync( runningTask.resolverResult); TryCompleteValue(executionContext, runningTask.context, runningTask.task.Source, fieldSelection, fieldSelection.Field.Type, runningTask.task.Path, fieldValue, runningTask.task.SetValue); cancellationToken.ThrowIfCancellationRequested(); } }
public IReadOnlyList <FieldSelection> CollectFields( ObjectType type, SelectionSetNode selectionSet, Path path) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (selectionSet == null) { throw new ArgumentNullException(nameof(selectionSet)); } var fields = new OrderedDictionary <string, FieldInfo>(); CollectFields(type, selectionSet, path, null, fields); int i = 0; var fieldSelections = new FieldSelection[fields.Count]; foreach (FieldInfo field in fields.Values) { field.Middleware = _factory(field.Field, field.Selection); fieldSelections[i++] = new FieldSelection(field); } return(fieldSelections); }
public FieldDelegate GetOrCreateMiddleware( FieldSelection fieldSelection, Func <FieldDelegate> fieldPipeline) { if (fieldSelection == null) { throw new ArgumentNullException(nameof(fieldSelection)); } if (!_cache.TryGetValue(fieldSelection, out FieldDelegate directivePipeline)) { directivePipeline = fieldPipeline.Invoke(); IReadOnlyList <IDirective> directives = CollectDirectives(fieldSelection); if (directives.Any()) { directivePipeline = Compile( directivePipeline, directives); } _cache.TryAdd(fieldSelection, directivePipeline); } return(directivePipeline); }
private bool TryCompleteScalarValue( ExecutionContext executionContext, IResolverContext resolverContext, ImmutableStack <object> source, FieldSelection fieldSelection, IType fieldType, Path path, object fieldValue, Action <object> setValue) { try { setValue(((ISerializableType)fieldType).Serialize(fieldValue)); return(true); } catch (ArgumentException ex) { executionContext.Errors.Add(new FieldError( ex.Message, fieldSelection.Node)); } catch (Exception) { executionContext.Errors.Add(new FieldError( "Undefined field serialization error.", fieldSelection.Node)); } setValue(null); return(false); }
public Dictionary <string, ArgumentValue> CoerceArgumentValues( ObjectType objectType, FieldSelection fieldSelection, VariableCollection variables) { Dictionary <string, ArgumentValue> coercedArgumentValues = new Dictionary <string, ArgumentValue>(); Dictionary <string, IValueNode> argumentValues = fieldSelection.Node.Arguments .Where(t => t.Value != null) .ToDictionary(t => t.Name.Value, t => t.Value); foreach (InputField argument in fieldSelection.Field.Arguments.Values) { string argumentName = argument.Name; IInputType argumentType = argument.Type; IValueNode defaultValue = argument.DefaultValue; object argumentValue = CoerceArgumentValue( argumentName, argumentType, defaultValue, variables, argumentValues); if (argumentType is NonNullType && argumentValue == null) { throw new QueryException(new ArgumentError( $"The argument type of '{argumentName}' is a non-null type.", argumentName, fieldSelection.Node)); } coercedArgumentValues[argumentName] = new ArgumentValue( argumentType, argumentType.NativeType, argumentValue); } return(coercedArgumentValues); }
private async Task ExecuteFieldResolverBatchSeriallyAsync( ExecutionContext executionContext, List <FieldResolverTask> batch, CancellationToken cancellationToken) { List <(FieldResolverTask task, object resolverResult)> runningTasks = new List <(FieldResolverTask, object)>(); foreach (FieldResolverTask task in batch) { // execute resolver IResolverContext resolverContext = new ResolverContext( executionContext, task); object resolverResult = task.FieldSelection.Field.Resolver( resolverContext, cancellationToken); // complete resolver value FieldSelection fieldSelection = task.FieldSelection; object fieldValue = await CompleteFieldValueAsync( resolverResult); TryCompleteValue(executionContext, resolverContext, task.Source, fieldSelection, fieldSelection.Field.Type, task.Path, fieldValue, task.SetValue); // execute sub-selection fields normally await ExecuteFieldResolversAsync(executionContext, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); } }
private static ArgumentValue CreateArgumentValue( FieldSelection fieldSelection, InputField argument, Dictionary <string, IValueNode> argumentValues, IVariableCollection variables, Path path) { object argumentValue = null; try { argumentValue = CoerceArgumentValue( argument, variables, argumentValues); } catch (ScalarSerializationException ex) { throw new QueryException(QueryError.CreateArgumentError( ex.Message, path, fieldSelection.Nodes.First(), argument.Name)); } if (argument.Type is NonNullType && argumentValue == null) { throw new QueryException(QueryError.CreateArgumentError( $"The argument type of '{argument.Name}' is a " + "non-null type.", path, fieldSelection.Nodes.First(), argument.Name)); } return(new ArgumentValue(argument.Type, argumentValue)); }
public override int GetHashCode() { unchecked { int hash = (FieldSelection?.GetHashCode() ?? 0) * 397; hash = hash ^ ((Type?.GetHashCode() ?? 0) * 7); return(hash); } }
public FieldDelegate CreateMiddleware( FieldSelection fieldSelection) { if (fieldSelection == null) { throw new ArgumentNullException(nameof(fieldSelection)); } return(_middlewareRes.Invoke(fieldSelection)); }
public FieldResolverTask(ImmutableStack <object> source, ObjectType objectType, FieldSelection fieldSelection, Path path, OrderedDictionary result) { Source = source; ObjectType = objectType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = path; Result = result; }
// TODO : refactor this private bool TryCompleteValue( ExecutionContext executionContext, IResolverContext resolverContext, ImmutableStack <object> source, FieldSelection fieldSelection, IType fieldType, Path path, object fieldValue, Action <object> setValue) { object completedValue = fieldValue; if (fieldType.IsNonNullType()) { IType innerType = fieldType.InnerType(); if (!TryCompleteValue( executionContext, resolverContext, source, fieldSelection, innerType, path, completedValue, setValue)) { executionContext.Errors.Add(new FieldError( "Cannot return null for non-nullable field.", fieldSelection.Node)); return(false); } return(true); } if (completedValue == null) { setValue(null); return(false); } if (fieldType.IsListType()) { return(TryCompleteListValue(executionContext, resolverContext, source, fieldSelection, fieldType, path, completedValue, setValue)); } if (fieldType.IsScalarType() || fieldType.IsEnumType()) { return(TryCompleteScalarValue(executionContext, resolverContext, source, fieldSelection, fieldType, path, completedValue, setValue)); } return(TryCompleteObjectValue(executionContext, resolverContext, source, fieldSelection, fieldType, path, completedValue, setValue)); }
private FieldSelection(FieldSelection field, int responseIndex) { _args = field._args; _vars = field._vars; _visibility = field._visibility; _path = field._path; _hasArgumentErrors = field._hasArgumentErrors; ResponseName = field.ResponseName; Field = field.Field; Selection = field.Selection; Middleware = field.Middleware; ResponseIndex = responseIndex; }
public static ResolverContext Rent( IExecutionContext executionContext, FieldSelection fieldSelection, IImmutableStack <object> source, IDictionary <string, object> serializedResult) { var context = new ResolverContext(); context.Initialize( executionContext, fieldSelection, source, serializedResult); return(context); }
protected static void EnsureRootValueNonNullState( IQueryResult result, IEnumerable <ResolverTask> rootResolverTasks) { foreach (ResolverTask resolverTask in rootResolverTasks) { FieldSelection selection = resolverTask.FieldSelection; if (resolverTask.FieldType.IsNonNullType() && result.Data[selection.ResponseName] == null) { result.Data.Clear(); break; } } }
private IEnumerable <IDirective> GetFieldSelectionDirectives( FieldSelection fieldSelection) { foreach (DirectiveNode directive in fieldSelection.Nodes .SelectMany(t => t.Directives)) { if (_schema.TryGetDirectiveType(directive.Name.Value, out DirectiveType directiveType) && directiveType.IsExecutable) { yield return(new Directive( directiveType, directive, fieldSelection)); } } }
public ResolverTask Branch( FieldSelection fieldSelection, Path path, IImmutableStack <object> source, IDictionary <string, object> result, Action propagateNonNullViolation) { return(new ResolverTask( this, fieldSelection, path, source, result, propagateNonNullViolation)); }
private IReadOnlyList <IDirective> CollectDirectives( FieldSelection fieldSelection) { var processed = new HashSet <string>(); var directives = new List <IDirective>(); CollectTypeSystemDirectives( processed, directives, fieldSelection.Field); CollectQueryDirectives( processed, directives, fieldSelection); return(directives.AsReadOnly()); }
public ResolverTask( IExecutionContext executionContext, ObjectType objectType, FieldSelection fieldSelection, Path path, ImmutableStack <object> source, OrderedDictionary result) { Source = source; ObjectType = objectType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = path; Result = result; ResolverContext = new ResolverContext(executionContext, this); }
private async Task <IExecutionResult> ExecuteInternalAsync( IExecutionContext executionContext) { object rootValue = executionContext.Operation.RootValue; FieldSelection fieldSelection = executionContext.CollectFields( executionContext.Schema.SubscriptionType, executionContext.Operation.Definition.SelectionSet, null) .Single(); ImmutableStack <object> source = ImmutableStack.Create(rootValue); var subscribeContext = ResolverContext.Rent( executionContext, fieldSelection, source, new FieldData(1)); SubscribeResolverDelegate subscribeResolver = fieldSelection.Field.SubscribeResolver ?? DefaultSubscribeResolverAsync; try { IAsyncEnumerable <object> sourceStream = await subscribeResolver(subscribeContext) .ConfigureAwait(false); return(new SubscriptionResult( sourceStream, message => { IExecutionContext cloned = executionContext.Clone(); cloned.ContextData[WellKnownContextData.EventMessage] = message; return cloned; }, ExecuteSubscriptionQueryAsync, executionContext.ServiceScope, executionContext.RequestAborted)); } finally { ResolverContext.Return(subscribeContext); } }