1
1
package graphql.servlet
2
2
3
3
import com.fasterxml.jackson.databind.ObjectMapper
4
+ import graphql.ExecutionInput
5
+ import graphql.execution.instrumentation.ChainedInstrumentation
6
+ import graphql.execution.instrumentation.Instrumentation
7
+ import graphql.execution.instrumentation.SimpleInstrumentation
8
+ import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentationOptions
4
9
import graphql.schema.DataFetcher
5
10
import graphql.schema.DataFetchingEnvironment
6
11
import graphql.servlet.context.DefaultGraphQLContext
7
12
import graphql.servlet.context.GraphQLContext
8
13
import graphql.servlet.context.GraphQLContextBuilder
9
14
import graphql.servlet.context.ContextSetting
15
+ import graphql.servlet.instrumentation.ConfigurableDispatchInstrumentation
10
16
import org.dataloader.BatchLoader
11
17
import org.dataloader.DataLoader
12
18
import org.dataloader.DataLoaderRegistry
@@ -111,6 +117,15 @@ class DataLoaderDispatchingSpec extends Specification {
111
117
loadCounterB. set(0 )
112
118
}
113
119
120
+ List<Map<String , Object > > getBatchedResponseContent () {
121
+ mapper. readValue(response. getContentAsByteArray(), List )
122
+ }
123
+
124
+ Instrumentation simpleInstrumentation = new SimpleInstrumentation ()
125
+ ChainedInstrumentation chainedInstrumentation = new ChainedInstrumentation (Collections . singletonList(simpleInstrumentation))
126
+ def simpleSupplier = {simpleInstrumentation}
127
+ def chainedSupplier = {chainedInstrumentation}
128
+
114
129
def " batched query with per query context does not batch loads together" () {
115
130
setup :
116
131
configureServlet(ContextSetting . PER_QUERY_WITH_INSTRUMENTATION )
@@ -161,7 +176,77 @@ class DataLoaderDispatchingSpec extends Specification {
161
176
loadCounterC. get() == 2
162
177
}
163
178
164
- List<Map<String , Object > > getBatchedResponseContent () {
165
- mapper. readValue(response. getContentAsByteArray(), List )
179
+ def unwrapChainedInstrumentations (Instrumentation instrumentation ) {
180
+ if (! instrumentation instanceof ChainedInstrumentation ) {
181
+ return Collections . singletonList(instrumentation)
182
+ } else {
183
+ List<Instrumentation > instrumentations = new ArrayList<> ()
184
+ for (Instrumentation current : ((ChainedInstrumentation )instrumentation). getInstrumentations()) {
185
+ if (current instanceof ChainedInstrumentation ) {
186
+ instrumentations. addAll(unwrapChainedInstrumentations(current))
187
+ } else {
188
+ instrumentations. add(current)
189
+ }
190
+ }
191
+ return instrumentations
192
+ }
193
+ }
194
+
195
+ def " PER_QUERY_WITHOUT_INSTRUMENTATION does not add instrumentation" () {
196
+ when :
197
+ def chainedFromContext = ContextSetting . PER_QUERY_WITHOUT_INSTRUMENTATION
198
+ .configureInstrumentationForContext(chainedSupplier, Collections . emptyList(), DataLoaderDispatcherInstrumentationOptions . newOptions())
199
+ def simpleFromContext = ContextSetting . PER_QUERY_WITHOUT_INSTRUMENTATION
200
+ .configureInstrumentationForContext(simpleSupplier, Collections . emptyList(), DataLoaderDispatcherInstrumentationOptions . newOptions())
201
+ then :
202
+ simpleInstrumentation == simpleFromContext. get()
203
+ chainedInstrumentation == chainedFromContext. get()
204
+ }
205
+
206
+ def " PER_REQUEST_WITHOUT_INSTRUMENTATION does not add instrumentation" () {
207
+ when :
208
+ def chainedFromContext = ContextSetting . PER_REQUEST_WITHOUT_INSTRUMENTATION
209
+ .configureInstrumentationForContext(chainedSupplier, Collections . emptyList(), DataLoaderDispatcherInstrumentationOptions . newOptions())
210
+ def simpleFromContext = ContextSetting . PER_REQUEST_WITHOUT_INSTRUMENTATION
211
+ .configureInstrumentationForContext(simpleSupplier, Collections . emptyList(), DataLoaderDispatcherInstrumentationOptions . newOptions())
212
+ then :
213
+ simpleInstrumentation == simpleFromContext. get()
214
+ chainedInstrumentation == chainedFromContext. get()
215
+ }
216
+
217
+ def " PER_QUERY_WITH_INSTRUMENTATION adds instrumentation" () {
218
+ when :
219
+ def chainedFromContext = ContextSetting . PER_QUERY_WITH_INSTRUMENTATION
220
+ .configureInstrumentationForContext(chainedSupplier, Collections . emptyList(), DataLoaderDispatcherInstrumentationOptions . newOptions())
221
+ def simpleFromContext = ContextSetting . PER_QUERY_WITH_INSTRUMENTATION
222
+ .configureInstrumentationForContext(simpleSupplier, Collections . emptyList(), DataLoaderDispatcherInstrumentationOptions . newOptions())
223
+ def fromSimple = unwrapChainedInstrumentations(simpleFromContext. get())
224
+ def fromChained = unwrapChainedInstrumentations(chainedFromContext. get())
225
+ then :
226
+ fromSimple. size() == 2
227
+ fromSimple. contains(simpleInstrumentation)
228
+ fromSimple. stream(). anyMatch({inst -> inst instanceof ConfigurableDispatchInstrumentation })
229
+ fromChained. size() == 2
230
+ fromChained. contains(simpleInstrumentation)
231
+ fromChained. stream(). anyMatch({inst -> inst instanceof ConfigurableDispatchInstrumentation })
232
+ }
233
+
234
+ def " PER_REQUEST_WITH_INSTRUMENTATION adds instrumentation" () {
235
+ setup :
236
+ ExecutionInput mockInput = ExecutionInput . newExecutionInput(). dataLoaderRegistry(new DataLoaderRegistry ()). build()
237
+ when :
238
+ def chainedFromContext = ContextSetting . PER_REQUEST_WITH_INSTRUMENTATION
239
+ .configureInstrumentationForContext(chainedSupplier, Collections . singletonList(mockInput), DataLoaderDispatcherInstrumentationOptions . newOptions())
240
+ def simpleFromContext = ContextSetting . PER_REQUEST_WITH_INSTRUMENTATION
241
+ .configureInstrumentationForContext(simpleSupplier, Collections . singletonList(mockInput), DataLoaderDispatcherInstrumentationOptions . newOptions())
242
+ def fromSimple = unwrapChainedInstrumentations(simpleFromContext. get())
243
+ def fromChained = unwrapChainedInstrumentations(chainedFromContext. get())
244
+ then :
245
+ fromSimple. size() == 2
246
+ fromSimple. contains(simpleInstrumentation)
247
+ fromSimple. stream(). anyMatch({inst -> inst instanceof ConfigurableDispatchInstrumentation })
248
+ fromChained. size() == 2
249
+ fromChained. contains(simpleInstrumentation)
250
+ fromChained. stream(). anyMatch({inst -> inst instanceof ConfigurableDispatchInstrumentation })
166
251
}
167
- }
252
+ }
0 commit comments