26
26
import graphql .execution .AsyncExecutionStrategy ;
27
27
import graphql .execution .ExecutionStrategy ;
28
28
import graphql .execution .SubscriptionExecutionStrategy ;
29
+ import graphql .execution .instrumentation .ChainedInstrumentation ;
29
30
import graphql .execution .instrumentation .Instrumentation ;
31
+ import graphql .execution .instrumentation .dataloader .DataLoaderDispatcherInstrumentationOptions ;
30
32
import graphql .execution .preparsed .PreparsedDocumentProvider ;
33
+ import graphql .kickstart .execution .BatchedDataLoaderGraphQLBuilder ;
34
+ import graphql .kickstart .execution .GraphQLInvoker ;
31
35
import graphql .kickstart .execution .GraphQLObjectMapper ;
32
- import graphql .kickstart .execution .GraphQLQueryInvoker ;
33
36
import graphql .kickstart .execution .config .DefaultExecutionStrategyProvider ;
34
37
import graphql .kickstart .execution .config .ExecutionStrategyProvider ;
38
+ import graphql .kickstart .execution .config .GraphQLBuilder ;
39
+ import graphql .kickstart .execution .config .GraphQLBuilderConfigurer ;
35
40
import graphql .kickstart .execution .config .GraphQLServletObjectMapperConfigurer ;
36
41
import graphql .kickstart .execution .config .ObjectMapperProvider ;
37
42
import graphql .kickstart .execution .error .GraphQLErrorHandler ;
55
60
import java .util .List ;
56
61
import java .util .Map ;
57
62
import java .util .Map .Entry ;
58
- import java .util .Optional ;
59
- import javax .annotation .PostConstruct ;
63
+ import java .util .function .Supplier ;
60
64
import javax .servlet .MultipartConfigElement ;
65
+ import lombok .RequiredArgsConstructor ;
61
66
import lombok .extern .slf4j .Slf4j ;
62
67
import org .springframework .beans .factory .ObjectProvider ;
63
68
import org .springframework .beans .factory .annotation .Autowired ;
84
89
*/
85
90
@ Slf4j
86
91
@ Configuration
92
+ @ RequiredArgsConstructor
87
93
@ ConditionalOnWebApplication
88
94
@ ConditionalOnClass (DispatcherServlet .class )
89
95
@ Conditional (OnSchemaOrSchemaProviderBean .class )
96
+ @ SuppressWarnings ("SpringJavaInjectionPointsAutowiringInspection" )
90
97
@ ConditionalOnProperty (value = "graphql.servlet.enabled" , havingValue = "true" , matchIfMissing = true )
91
98
@ AutoConfigureAfter ({GraphQLJavaToolsAutoConfiguration .class , JacksonAutoConfiguration .class })
92
99
@ EnableConfigurationProperties ({GraphQLServletProperties .class })
93
100
public class GraphQLWebAutoConfiguration {
94
101
95
-
96
102
public static final String QUERY_EXECUTION_STRATEGY = "queryExecutionStrategy" ;
97
103
public static final String MUTATION_EXECUTION_STRATEGY = "mutationExecutionStrategy" ;
98
104
public static final String SUBSCRIPTION_EXECUTION_STRATEGY = "subscriptionExecutionStrategy" ;
99
105
100
- @ Autowired
101
- private GraphQLServletProperties graphQLServletProperties ;
102
-
103
- @ Autowired (required = false )
104
- private List <GraphQLServletListener > listeners ;
105
-
106
- @ Autowired (required = false )
107
- private List <Instrumentation > instrumentations ;
108
-
109
- @ Autowired (required = false )
110
- private GraphQLErrorHandler errorHandler ;
111
-
112
- private ErrorHandlerSupplier errorHandlerSupplier = new ErrorHandlerSupplier (null );
113
-
114
- @ Autowired (required = false )
115
- private Map <String , ExecutionStrategy > executionStrategies ;
116
-
117
- @ Autowired (required = false )
118
- private GraphQLServletContextBuilder contextBuilder ;
119
-
120
- @ Autowired (required = false )
121
- private GraphQLServletRootObjectBuilder graphQLRootObjectBuilder ;
106
+ private final GraphQLServletProperties graphQLServletProperties ;
122
107
123
- @ Autowired (required = false )
124
- private GraphQLServletObjectMapperConfigurer objectMapperConfigurer ;
125
-
126
- @ Autowired (required = false )
127
- private PreparsedDocumentProvider preparsedDocumentProvider ;
128
-
129
- @ Autowired (required = false )
130
- private MultipartConfigElement multipartConfigElement ;
131
-
132
- @ Autowired (required = false )
133
- private BatchInputPreProcessor batchInputPreProcessor ;
134
-
135
- @ Autowired (required = false )
136
- private GraphQLResponseCacheManager responseCacheManager ;
137
-
138
- @ PostConstruct
139
- void postConstruct () {
140
- if (errorHandler != null ) {
141
- errorHandlerSupplier .setErrorHandler (errorHandler );
142
- }
108
+ @ Bean
109
+ public GraphQLErrorStartupListener graphQLErrorStartupListener (
110
+ @ Autowired (required = false ) GraphQLErrorHandler errorHandler ) {
111
+ return new GraphQLErrorStartupListener (toErrorHandlerSupplier (errorHandler ),
112
+ graphQLServletProperties .isExceptionHandlersEnabled ());
143
113
}
144
114
145
- @ Bean
146
- public GraphQLErrorStartupListener graphQLErrorStartupListener () {
147
- return new GraphQLErrorStartupListener (errorHandlerSupplier , graphQLServletProperties .isExceptionHandlersEnabled ());
115
+ private ErrorHandlerSupplier toErrorHandlerSupplier (GraphQLErrorHandler errorHandler ) {
116
+ return new ErrorHandlerSupplier (errorHandler );
148
117
}
149
118
150
119
@ Bean
@@ -176,7 +145,9 @@ public GraphQLSchemaServletProvider graphQLSchemaProvider(GraphQLSchema schema)
176
145
177
146
@ Bean
178
147
@ ConditionalOnMissingBean
179
- public ExecutionStrategyProvider executionStrategyProvider () {
148
+ public ExecutionStrategyProvider executionStrategyProvider (
149
+ @ Autowired (required = false ) Map <String , ExecutionStrategy > executionStrategies
150
+ ) {
180
151
if (executionStrategies == null || executionStrategies .isEmpty ()) {
181
152
return new DefaultExecutionStrategyProvider (new AsyncExecutionStrategy (), null ,
182
153
new SubscriptionExecutionStrategy ());
@@ -193,13 +164,15 @@ public ExecutionStrategyProvider executionStrategyProvider() {
193
164
throwIncorrectExecutionStrategyNameException ();
194
165
}
195
166
196
- if (executionStrategies .size () == 2 && !(executionStrategies .containsKey (MUTATION_EXECUTION_STRATEGY )
197
- || executionStrategies .containsKey (SUBSCRIPTION_EXECUTION_STRATEGY ))) {
167
+ if (executionStrategies .size () == 2 && !(
168
+ executionStrategies .containsKey (MUTATION_EXECUTION_STRATEGY )
169
+ || executionStrategies .containsKey (SUBSCRIPTION_EXECUTION_STRATEGY ))) {
198
170
throwIncorrectExecutionStrategyNameException ();
199
171
}
200
172
201
- if (executionStrategies .size () >= 3 && !(executionStrategies .containsKey (MUTATION_EXECUTION_STRATEGY )
202
- && executionStrategies .containsKey (SUBSCRIPTION_EXECUTION_STRATEGY ))) {
173
+ if (executionStrategies .size () >= 3 && !(
174
+ executionStrategies .containsKey (MUTATION_EXECUTION_STRATEGY )
175
+ && executionStrategies .containsKey (SUBSCRIPTION_EXECUTION_STRATEGY ))) {
203
176
throwIncorrectExecutionStrategyNameException ();
204
177
}
205
178
@@ -214,13 +187,18 @@ public ExecutionStrategyProvider executionStrategyProvider() {
214
187
private void throwIncorrectExecutionStrategyNameException () {
215
188
throw new IllegalStateException (String
216
189
.format ("When defining more than one execution strategy, they must be named %s, %s, or %s" ,
217
- QUERY_EXECUTION_STRATEGY , MUTATION_EXECUTION_STRATEGY , SUBSCRIPTION_EXECUTION_STRATEGY ));
190
+ QUERY_EXECUTION_STRATEGY , MUTATION_EXECUTION_STRATEGY ,
191
+ SUBSCRIPTION_EXECUTION_STRATEGY ));
218
192
}
219
193
220
194
@ Bean
221
195
@ ConditionalOnMissingBean
222
- public GraphQLInvocationInputFactory invocationInputFactory (GraphQLSchemaServletProvider schemaProvider ) {
223
- GraphQLInvocationInputFactory .Builder builder = GraphQLInvocationInputFactory .newBuilder (schemaProvider );
196
+ public GraphQLInvocationInputFactory invocationInputFactory (
197
+ GraphQLSchemaServletProvider schemaProvider ,
198
+ @ Autowired (required = false ) GraphQLServletContextBuilder contextBuilder ,
199
+ @ Autowired (required = false ) GraphQLServletRootObjectBuilder graphQLRootObjectBuilder ) {
200
+ GraphQLInvocationInputFactory .Builder builder = GraphQLInvocationInputFactory
201
+ .newBuilder (schemaProvider );
224
202
225
203
if (graphQLRootObjectBuilder != null ) {
226
204
builder .withGraphQLRootObjectBuilder (graphQLRootObjectBuilder );
@@ -235,30 +213,59 @@ public GraphQLInvocationInputFactory invocationInputFactory(GraphQLSchemaServlet
235
213
236
214
@ Bean
237
215
@ ConditionalOnMissingBean
238
- public GraphQLQueryInvoker queryInvoker (ExecutionStrategyProvider executionStrategyProvider ) {
239
- GraphQLQueryInvoker .Builder builder = GraphQLQueryInvoker .newBuilder ()
240
- .withExecutionStrategyProvider (executionStrategyProvider );
241
-
242
- if (instrumentations != null ) {
243
- // Metrics instrumentation should be the last to run (we need that from TracingInstrumentation)
244
- instrumentations .sort ((a , b ) -> a instanceof MetricsInstrumentation ? 1 : 0 );
245
- builder .with (instrumentations );
216
+ public GraphQLBuilder graphQLBuilder (
217
+ ExecutionStrategyProvider executionStrategyProvider ,
218
+ @ Autowired (required = false ) List <Instrumentation > instrumentations ,
219
+ @ Autowired (required = false ) PreparsedDocumentProvider preparsedDocumentProvider ,
220
+ @ Autowired (required = false ) GraphQLBuilderConfigurer graphQLBuilderConfigurer ) {
221
+ GraphQLBuilder graphQLBuilder = new GraphQLBuilder ();
222
+ graphQLBuilder .executionStrategyProvider (() -> executionStrategyProvider );
223
+
224
+ if (instrumentations != null && !instrumentations .isEmpty ()) {
225
+ if (instrumentations .size () == 1 ) {
226
+ graphQLBuilder .instrumentation (() -> instrumentations .get (0 ));
227
+ } else {
228
+ // Metrics instrumentation should be the last to run (we need that from TracingInstrumentation)
229
+ instrumentations .sort ((a , b ) -> a instanceof MetricsInstrumentation ? 1 : 0 );
230
+ graphQLBuilder .instrumentation (() -> new ChainedInstrumentation (instrumentations ));
231
+ }
246
232
}
247
233
248
234
if (preparsedDocumentProvider != null ) {
249
- builder . withPreparsedDocumentProvider ( preparsedDocumentProvider );
235
+ graphQLBuilder . preparsedDocumentProvider (() -> preparsedDocumentProvider );
250
236
}
251
237
252
- return builder .build ();
238
+ if (graphQLBuilderConfigurer != null ) {
239
+ graphQLBuilder .graphQLBuilderConfigurer (() -> graphQLBuilderConfigurer );
240
+ }
241
+
242
+ return graphQLBuilder ;
243
+ }
244
+
245
+ @ Bean
246
+ @ ConditionalOnMissingBean
247
+ public BatchedDataLoaderGraphQLBuilder batchedDataLoaderGraphQLBuilder (
248
+ @ Autowired (required = false ) Supplier <DataLoaderDispatcherInstrumentationOptions > optionsSupplier
249
+ ) {
250
+ return new BatchedDataLoaderGraphQLBuilder (optionsSupplier );
251
+ }
252
+
253
+ @ Bean
254
+ @ ConditionalOnMissingBean
255
+ public GraphQLInvoker graphQLInvoker (GraphQLBuilder graphQLBuilder ,
256
+ BatchedDataLoaderGraphQLBuilder batchedDataLoaderGraphQLBuilder ) {
257
+ return new GraphQLInvoker (graphQLBuilder , batchedDataLoaderGraphQLBuilder );
253
258
}
254
259
255
260
@ Bean
256
261
@ ConditionalOnMissingBean
257
262
public GraphQLObjectMapper graphQLObjectMapper (
258
- ObjectProvider <ObjectMapperProvider > objectMapperProviderObjectProvider ) {
263
+ ObjectProvider <ObjectMapperProvider > objectMapperProviderObjectProvider ,
264
+ @ Autowired (required = false ) GraphQLServletObjectMapperConfigurer objectMapperConfigurer ,
265
+ @ Autowired (required = false ) GraphQLErrorHandler errorHandler ) {
259
266
GraphQLObjectMapper .Builder builder = newBuilder ();
260
267
261
- builder .withGraphQLErrorHandler (errorHandlerSupplier );
268
+ builder .withGraphQLErrorHandler (toErrorHandlerSupplier ( errorHandler ) );
262
269
263
270
ObjectMapperProvider objectMapperProvider = objectMapperProviderObjectProvider .getIfAvailable ();
264
271
@@ -284,10 +291,15 @@ public ObjectMapperProvider objectMapperProvider(ObjectMapper objectMapper) {
284
291
285
292
@ Bean
286
293
@ ConditionalOnMissingBean
287
- public GraphQLConfiguration graphQLServletConfiguration (GraphQLInvocationInputFactory invocationInputFactory ,
288
- GraphQLQueryInvoker queryInvoker , GraphQLObjectMapper graphQLObjectMapper ) {
294
+ public GraphQLConfiguration graphQLServletConfiguration (
295
+ GraphQLInvocationInputFactory invocationInputFactory ,
296
+ GraphQLInvoker graphQLInvoker ,
297
+ GraphQLObjectMapper graphQLObjectMapper ,
298
+ @ Autowired (required = false ) List <GraphQLServletListener > listeners ,
299
+ @ Autowired (required = false ) BatchInputPreProcessor batchInputPreProcessor ,
300
+ @ Autowired (required = false ) GraphQLResponseCacheManager responseCacheManager ) {
289
301
return GraphQLConfiguration .with (invocationInputFactory )
290
- .with (queryInvoker )
302
+ .with (graphQLInvoker )
291
303
.with (graphQLObjectMapper )
292
304
.with (listeners )
293
305
.with (graphQLServletProperties .getSubscriptionTimeout ())
@@ -306,14 +318,16 @@ public GraphQLHttpServlet graphQLHttpServlet(GraphQLConfiguration graphQLConfigu
306
318
307
319
@ Bean
308
320
public ServletRegistrationBean <AbstractGraphQLHttpServlet > graphQLServletRegistrationBean (
309
- AbstractGraphQLHttpServlet servlet ) {
310
- ServletRegistrationBean <AbstractGraphQLHttpServlet > registration = new ServletRegistrationBean <>(servlet ,
311
- graphQLServletProperties .getServletMapping ());
312
- registration .setMultipartConfig (multipartConfigElement ());
321
+ AbstractGraphQLHttpServlet servlet ,
322
+ @ Autowired (required = false ) MultipartConfigElement multipartConfigElement ) {
323
+ ServletRegistrationBean <AbstractGraphQLHttpServlet > registration =
324
+ new ServletRegistrationBean <>(servlet , graphQLServletProperties .getServletMapping ());
325
+ if (multipartConfigElement != null ) {
326
+ registration .setMultipartConfig (multipartConfigElement );
327
+ } else {
328
+ registration .setMultipartConfig (new MultipartConfigElement ("" ));
329
+ }
313
330
return registration ;
314
331
}
315
332
316
- private MultipartConfigElement multipartConfigElement () {
317
- return Optional .ofNullable (multipartConfigElement ).orElse (new MultipartConfigElement ("" ));
318
- }
319
333
}
0 commit comments