1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package eu.ehri.project.graphql;
21
22 import com.fasterxml.jackson.core.JsonGenerator;
23 import graphql.ExecutionInput;
24 import graphql.execution.Execution;
25 import graphql.execution.ExecutionContext;
26 import graphql.execution.ExecutionContextBuilder;
27 import graphql.execution.ExecutionId;
28 import graphql.execution.ExecutionPath;
29 import graphql.execution.ExecutionStrategy;
30 import graphql.execution.ExecutionStrategyParameters;
31 import graphql.execution.ExecutionTypeInfo;
32 import graphql.execution.FieldCollector;
33 import graphql.execution.FieldCollectorParameters;
34 import graphql.execution.NonNullableFieldValidator;
35 import graphql.execution.instrumentation.Instrumentation;
36 import graphql.language.Document;
37 import graphql.language.Field;
38 import graphql.language.NodeUtil;
39 import graphql.language.OperationDefinition;
40 import graphql.schema.GraphQLObjectType;
41 import graphql.schema.GraphQLSchema;
42
43 import java.io.IOException;
44 import java.util.List;
45 import java.util.Map;
46
47 import static graphql.Assert.assertShouldNeverHappen;
48 import static graphql.execution.ExecutionTypeInfo.newTypeInfo;
49 import static graphql.execution.FieldCollectorParameters.newParameters;
50 import static graphql.language.OperationDefinition.Operation.MUTATION;
51 import static graphql.language.OperationDefinition.Operation.QUERY;
52 import static graphql.language.OperationDefinition.Operation.SUBSCRIPTION;
53
54
55 public class StreamingExecution extends Execution {
56
57 private final FieldCollector fieldCollector = new FieldCollector();
58 private final ExecutionStrategy queryStrategy;
59 private final ExecutionStrategy mutationStrategy;
60 private final ExecutionStrategy subscriptionStrategy;
61 private final Instrumentation instrumentation;
62
63 public StreamingExecution(ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, Instrumentation instrumentation) {
64 super(queryStrategy, mutationStrategy, subscriptionStrategy, instrumentation);
65 this.queryStrategy = queryStrategy;
66 this.mutationStrategy = mutationStrategy;
67 this.subscriptionStrategy = subscriptionStrategy;
68 this.instrumentation = instrumentation;
69 }
70
71 private GraphQLObjectType getOperationRootType(GraphQLSchema graphQLSchema, OperationDefinition.Operation operation) {
72 if (operation == MUTATION) {
73 return graphQLSchema.getMutationType();
74 } else if (operation == QUERY) {
75 return graphQLSchema.getQueryType();
76 } else if (operation == SUBSCRIPTION) {
77 return graphQLSchema.getSubscriptionType();
78 } else {
79 return assertShouldNeverHappen("Unhandled case. An extra operation enum has been added without code support");
80 }
81 }
82 private void executeOperation(
83 JsonGenerator generator,
84 ExecutionContext executionContext,
85 Object root,
86 OperationDefinition operationDefinition) throws IOException {
87 GraphQLObjectType operationRootType = getOperationRootType(executionContext.getGraphQLSchema(),
88 operationDefinition.getOperation());
89
90 FieldCollectorParameters collectorParameters = newParameters()
91 .schema(executionContext.getGraphQLSchema())
92 .objectType(operationRootType)
93 .fragments(executionContext.getFragmentsByName())
94 .variables(executionContext.getVariables())
95 .build();
96
97 Map<String, List<Field>> fields = fieldCollector.collectFields(collectorParameters, operationDefinition.getSelectionSet());
98
99 ExecutionTypeInfo typeInfo = newTypeInfo().type(operationRootType).build();
100 NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo);
101
102 ExecutionStrategyParameters parameters = ExecutionStrategyParameters.newParameters()
103 .typeInfo(typeInfo)
104 .source(root)
105 .fields(fields)
106 .nonNullFieldValidator(nonNullableFieldValidator)
107 .path(ExecutionPath.rootPath())
108 .build();
109
110 new StreamingExecutionStrategy().execute(generator, executionContext, parameters);
111 }
112
113 public void execute(JsonGenerator generator, GraphQLSchema graphQLSchema, Document document, ExecutionId executionId, ExecutionInput executionInput) throws IOException {
114 NodeUtil.GetOperationResult operationResult = NodeUtil.getOperation(document, executionInput.getOperationName());
115 ExecutionContext executionContext = new ExecutionContextBuilder()
116 .instrumentation(instrumentation)
117 .executionId(executionId)
118 .graphQLSchema(graphQLSchema)
119 .queryStrategy(queryStrategy)
120 .mutationStrategy(mutationStrategy)
121 .subscriptionStrategy(subscriptionStrategy)
122 .operationDefinition(operationResult.operationDefinition)
123 .context(executionInput.getContext())
124 .fragmentsByName(operationResult.fragmentsByName)
125 .root(executionInput.getRoot())
126 .document(document)
127 .variables(executionInput.getVariables())
128 .build();
129
130 executeOperation(generator, executionContext, executionInput.getRoot(), executionContext.getOperationDefinition());
131 }
132 }