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 com.google.common.collect.Lists;
24 import eu.ehri.extension.errors.ExecutionError;
25 import graphql.ExecutionInput;
26 import graphql.GraphQLError;
27 import graphql.InvalidSyntaxError;
28 import graphql.execution.AsyncExecutionStrategy;
29 import graphql.execution.ExecutionId;
30 import graphql.execution.ValuesResolver;
31 import graphql.execution.instrumentation.NoOpInstrumentation;
32 import graphql.language.Document;
33 import graphql.language.NodeUtil;
34 import graphql.language.OperationDefinition;
35 import graphql.language.SourceLocation;
36 import graphql.language.VariableDefinition;
37 import graphql.parser.Parser;
38 import graphql.schema.GraphQLSchema;
39 import graphql.validation.ValidationError;
40 import graphql.validation.Validator;
41 import org.antlr.v4.runtime.RecognitionException;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import java.io.IOException;
46 import java.util.Collections;
47 import java.util.List;
48 import java.util.Map;
49
50 import static graphql.Assert.assertNotNull;
51
52
53 public class StreamingGraphQL {
54
55 private static final Logger log = LoggerFactory.getLogger(StreamingGraphQL.class);
56
57 private final GraphQLSchema graphQLSchema;
58
59 public StreamingGraphQL(GraphQLSchema schema) {
60 this.graphQLSchema = schema;
61 }
62
63
64 public void execute(JsonGenerator generator, String requestString, Document document, String operationName, Object context, Map<String, Object>
65 arguments) throws IOException {
66 assertNotNull(arguments, "arguments can't be null");
67 log.trace("Executing request. operation name: {}. Request: {} ", operationName, document);
68 StreamingExecution execution = new StreamingExecution(new StreamingExecutionStrategy(), new AsyncExecutionStrategy(),
69 new AsyncExecutionStrategy(), NoOpInstrumentation.INSTANCE);
70 ExecutionInput input = ExecutionInput.newExecutionInput()
71 .context(context)
72 .variables(arguments)
73 .query(requestString)
74 .operationName(operationName)
75 .build();
76 execution.execute(generator, graphQLSchema, document, ExecutionId.from("test"), input);
77 }
78
79 public void execute(JsonGenerator generator, String requestString, String operationName, Object context, Map<String, Object> arguments) throws IOException {
80 assertNotNull(arguments, "arguments can't be null");
81 log.trace("Executing request. operation name: {}. Request: {} ", operationName, requestString);
82 Document document = parseAndValidate(requestString, operationName, arguments);
83 execute(generator, requestString, document, operationName, context, arguments);
84 }
85
86 public Document parseAndValidate(String query, String operationName, Map<String, Object> variables) {
87 Parser parser = new Parser();
88 Document document;
89 try {
90 document = parser.parseDocument(query);
91 } catch (Exception e) {
92 RecognitionException recognitionException = (RecognitionException) e.getCause();
93 SourceLocation sourceLocation = new SourceLocation(recognitionException.getOffendingToken().getLine(),
94 recognitionException.getOffendingToken().getCharPositionInLine());
95 InvalidSyntaxError invalidSyntaxError = new InvalidSyntaxError(sourceLocation, "Invalid syntax");
96 throw new ExecutionError(Collections.singletonList(invalidSyntaxError));
97 }
98
99 Validator validator = new Validator();
100 List<ValidationError> validationErrors = validator.validateDocument(graphQLSchema, document);
101 if (validationErrors.size() > 0) {
102 throw new ExecutionError(validationErrors);
103 }
104
105 NodeUtil.GetOperationResult operationResult = NodeUtil.getOperation(document, operationName);
106 OperationDefinition operationDefinition = operationResult.operationDefinition;
107
108 ValuesResolver valuesResolver = new ValuesResolver();
109 List<VariableDefinition> variableDefinitions = operationDefinition.getVariableDefinitions();
110
111 try {
112 valuesResolver.coerceArgumentValues(graphQLSchema, variableDefinitions, variables);
113 } catch (RuntimeException rte) {
114 if (rte instanceof GraphQLError) {
115 throw new ExecutionError(Lists.newArrayList((GraphQLError)rte));
116 }
117 throw rte;
118 }
119
120 return document;
121 }
122 }