2626import graphql .execution .AsyncExecutionStrategy ;
2727import graphql .execution .ExecutionStrategy ;
2828import graphql .execution .SubscriptionExecutionStrategy ;
29+ import graphql .execution .instrumentation .ChainedInstrumentation ;
2930import graphql .execution .instrumentation .Instrumentation ;
31+ import graphql .execution .instrumentation .dataloader .DataLoaderDispatcherInstrumentationOptions ;
3032import graphql .execution .preparsed .PreparsedDocumentProvider ;
33+ import graphql .kickstart .execution .BatchedDataLoaderGraphQLBuilder ;
34+ import graphql .kickstart .execution .GraphQLInvoker ;
3135import graphql .kickstart .execution .GraphQLObjectMapper ;
32- import graphql .kickstart .execution .GraphQLQueryInvoker ;
3336import graphql .kickstart .execution .config .DefaultExecutionStrategyProvider ;
3437import graphql .kickstart .execution .config .ExecutionStrategyProvider ;
38+ import graphql .kickstart .execution .config .GraphQLBuilder ;
39+ import graphql .kickstart .execution .config .GraphQLBuilderConfigurer ;
3540import graphql .kickstart .execution .config .GraphQLServletObjectMapperConfigurer ;
3641import graphql .kickstart .execution .config .ObjectMapperProvider ;
3742import graphql .kickstart .execution .error .GraphQLErrorHandler ;
5560import java .util .List ;
5661import java .util .Map ;
5762import java .util .Map .Entry ;
58- import java .util .Optional ;
59- import javax .annotation .PostConstruct ;
63+ import java .util .function .Supplier ;
6064import javax .servlet .MultipartConfigElement ;
65+ import lombok .RequiredArgsConstructor ;
6166import lombok .extern .slf4j .Slf4j ;
6267import org .springframework .beans .factory .ObjectProvider ;
6368import org .springframework .beans .factory .annotation .Autowired ;
8489 */
8590@ Slf4j
8691@ Configuration
92+ @ RequiredArgsConstructor
8793@ ConditionalOnWebApplication
8894@ ConditionalOnClass (DispatcherServlet .class )
8995@ Conditional (OnSchemaOrSchemaProviderBean .class )
96+ @ SuppressWarnings ("SpringJavaInjectionPointsAutowiringInspection" )
9097@ ConditionalOnProperty (value = "graphql.servlet.enabled" , havingValue = "true" , matchIfMissing = true )
9198@ AutoConfigureAfter ({GraphQLJavaToolsAutoConfiguration .class , JacksonAutoConfiguration .class })
9299@ EnableConfigurationProperties ({GraphQLServletProperties .class })
93100public class GraphQLWebAutoConfiguration {
94101
95-
96102 public static final String QUERY_EXECUTION_STRATEGY = "queryExecutionStrategy" ;
97103 public static final String MUTATION_EXECUTION_STRATEGY = "mutationExecutionStrategy" ;
98104 public static final String SUBSCRIPTION_EXECUTION_STRATEGY = "subscriptionExecutionStrategy" ;
99105
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 ;
122107
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 ());
143113 }
144114
145- @ Bean
146- public GraphQLErrorStartupListener graphQLErrorStartupListener () {
147- return new GraphQLErrorStartupListener (errorHandlerSupplier , graphQLServletProperties .isExceptionHandlersEnabled ());
115+ private ErrorHandlerSupplier toErrorHandlerSupplier (GraphQLErrorHandler errorHandler ) {
116+ return new ErrorHandlerSupplier (errorHandler );
148117 }
149118
150119 @ Bean
@@ -176,7 +145,9 @@ public GraphQLSchemaServletProvider graphQLSchemaProvider(GraphQLSchema schema)
176145
177146 @ Bean
178147 @ ConditionalOnMissingBean
179- public ExecutionStrategyProvider executionStrategyProvider () {
148+ public ExecutionStrategyProvider executionStrategyProvider (
149+ @ Autowired (required = false ) Map <String , ExecutionStrategy > executionStrategies
150+ ) {
180151 if (executionStrategies == null || executionStrategies .isEmpty ()) {
181152 return new DefaultExecutionStrategyProvider (new AsyncExecutionStrategy (), null ,
182153 new SubscriptionExecutionStrategy ());
@@ -193,13 +164,15 @@ public ExecutionStrategyProvider executionStrategyProvider() {
193164 throwIncorrectExecutionStrategyNameException ();
194165 }
195166
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 ))) {
198170 throwIncorrectExecutionStrategyNameException ();
199171 }
200172
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 ))) {
203176 throwIncorrectExecutionStrategyNameException ();
204177 }
205178
@@ -214,13 +187,18 @@ public ExecutionStrategyProvider executionStrategyProvider() {
214187 private void throwIncorrectExecutionStrategyNameException () {
215188 throw new IllegalStateException (String
216189 .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 ));
218192 }
219193
220194 @ Bean
221195 @ 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 );
224202
225203 if (graphQLRootObjectBuilder != null ) {
226204 builder .withGraphQLRootObjectBuilder (graphQLRootObjectBuilder );
@@ -235,30 +213,59 @@ public GraphQLInvocationInputFactory invocationInputFactory(GraphQLSchemaServlet
235213
236214 @ Bean
237215 @ 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+ }
246232 }
247233
248234 if (preparsedDocumentProvider != null ) {
249- builder . withPreparsedDocumentProvider ( preparsedDocumentProvider );
235+ graphQLBuilder . preparsedDocumentProvider (() -> preparsedDocumentProvider );
250236 }
251237
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 );
253258 }
254259
255260 @ Bean
256261 @ ConditionalOnMissingBean
257262 public GraphQLObjectMapper graphQLObjectMapper (
258- ObjectProvider <ObjectMapperProvider > objectMapperProviderObjectProvider ) {
263+ ObjectProvider <ObjectMapperProvider > objectMapperProviderObjectProvider ,
264+ @ Autowired (required = false ) GraphQLServletObjectMapperConfigurer objectMapperConfigurer ,
265+ @ Autowired (required = false ) GraphQLErrorHandler errorHandler ) {
259266 GraphQLObjectMapper .Builder builder = newBuilder ();
260267
261- builder .withGraphQLErrorHandler (errorHandlerSupplier );
268+ builder .withGraphQLErrorHandler (toErrorHandlerSupplier ( errorHandler ) );
262269
263270 ObjectMapperProvider objectMapperProvider = objectMapperProviderObjectProvider .getIfAvailable ();
264271
@@ -284,10 +291,15 @@ public ObjectMapperProvider objectMapperProvider(ObjectMapper objectMapper) {
284291
285292 @ Bean
286293 @ 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 ) {
289301 return GraphQLConfiguration .with (invocationInputFactory )
290- .with (queryInvoker )
302+ .with (graphQLInvoker )
291303 .with (graphQLObjectMapper )
292304 .with (listeners )
293305 .with (graphQLServletProperties .getSubscriptionTimeout ())
@@ -306,14 +318,16 @@ public GraphQLHttpServlet graphQLHttpServlet(GraphQLConfiguration graphQLConfigu
306318
307319 @ Bean
308320 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+ }
313330 return registration ;
314331 }
315332
316- private MultipartConfigElement multipartConfigElement () {
317- return Optional .ofNullable (multipartConfigElement ).orElse (new MultipartConfigElement ("" ));
318- }
319333}
0 commit comments