Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Commit a6511f2

Browse files
authored
Merge pull request #105 from marceloverdijk/instrumentation-autoconfiguration
Added instrumentation auto configuration
2 parents cb60d22 + 09ff5cc commit a6511f2

6 files changed

Lines changed: 193 additions & 4 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.oembedler.moon.graphql.boot;
2+
3+
import graphql.analysis.MaxQueryComplexityInstrumentation;
4+
import graphql.analysis.MaxQueryDepthInstrumentation;
5+
import graphql.execution.instrumentation.tracing.TracingInstrumentation;
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
8+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
9+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
10+
import org.springframework.context.annotation.Bean;
11+
import org.springframework.context.annotation.Configuration;
12+
13+
/**
14+
* @author Marcel Overdijk
15+
*/
16+
@Configuration
17+
@ConditionalOnProperty(value = "graphql.servlet.enabled", havingValue = "true", matchIfMissing = true)
18+
@EnableConfigurationProperties({GraphQLServletProperties.class})
19+
public class GraphQLInstrumentationAutoConfiguration {
20+
21+
@Value("${graphql.servlet.maxQueryComplexity:#{null}}")
22+
private Integer maxQueryComplexity;
23+
24+
@Value("${graphql.servlet.maxQueryDepth:#{null}}")
25+
private Integer maxQueryDepth;
26+
27+
@Bean
28+
@ConditionalOnMissingBean
29+
@ConditionalOnProperty(value = "graphql.servlet.tracing-enabled", havingValue = "true")
30+
public TracingInstrumentation tracingInstrumentation() {
31+
return new TracingInstrumentation();
32+
}
33+
34+
@Bean
35+
@ConditionalOnMissingBean
36+
@ConditionalOnProperty(value = "graphql.servlet.max-query-complexity")
37+
public MaxQueryComplexityInstrumentation maxQueryComplexityInstrumentation() {
38+
return new MaxQueryComplexityInstrumentation(maxQueryComplexity);
39+
}
40+
41+
@Bean
42+
@ConditionalOnMissingBean
43+
@ConditionalOnProperty(value = "graphql.servlet.max-query-depth")
44+
public MaxQueryDepthInstrumentation maxQueryDepthInstrumentation() {
45+
return new MaxQueryDepthInstrumentation(maxQueryDepth);
46+
}
47+
}

graphql-spring-boot-autoconfigure/src/main/java/com/oembedler/moon/graphql/boot/GraphQLWebAutoConfiguration.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import graphql.execution.AsyncExecutionStrategy;
2323
import graphql.execution.ExecutionStrategy;
2424
import graphql.execution.SubscriptionExecutionStrategy;
25+
import graphql.execution.instrumentation.ChainedInstrumentation;
2526
import graphql.execution.instrumentation.Instrumentation;
2627
import graphql.execution.preparsed.PreparsedDocumentProvider;
2728
import graphql.schema.GraphQLSchema;
@@ -91,7 +92,7 @@ public class GraphQLWebAutoConfiguration {
9192
private List<GraphQLServletListener> listeners;
9293

9394
@Autowired(required = false)
94-
private Instrumentation instrumentation;
95+
private List<Instrumentation> instrumentations;
9596

9697
@Autowired(required = false)
9798
private GraphQLErrorHandler errorHandler;
@@ -186,8 +187,13 @@ public GraphQLQueryInvoker queryInvoker(ExecutionStrategyProvider executionStrat
186187
GraphQLQueryInvoker.Builder builder = GraphQLQueryInvoker.newBuilder()
187188
.withExecutionStrategyProvider(executionStrategyProvider);
188189

189-
if (instrumentation != null) {
190-
builder.withInstrumentation(instrumentation);
190+
if (instrumentations != null && !instrumentations.isEmpty()) {
191+
if (instrumentations.size() == 1) {
192+
builder.withInstrumentation(instrumentations.get(0));
193+
} else {
194+
Instrumentation instrumentation = new ChainedInstrumentation(instrumentations);
195+
builder.withInstrumentation(instrumentation);
196+
}
191197
}
192198

193199
if (preparsedDocumentProvider != null) {

graphql-spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@
2424
"name": "graphql.servlet.subscriptions.websocket.path",
2525
"defaultValue": "/subscriptions",
2626
"type": "java.lang.String"
27+
},
28+
{
29+
"name": "graphql.servlet.tracingEnabled",
30+
"defaultValue": false,
31+
"type": "java.lang.Boolean"
32+
},
33+
{
34+
"name": "graphql.servlet.maxQueryComplexity",
35+
"defaultValue": null,
36+
"type": "java.lang.Integer"
37+
},
38+
{
39+
"name": "graphql.servlet.maxQueryDepth",
40+
"defaultValue": null,
41+
"type": "java.lang.Integer"
2742
}
2843
]
2944
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
22
com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration,\
3-
com.oembedler.moon.graphql.boot.GraphQLJavaToolsAutoConfiguration
3+
com.oembedler.moon.graphql.boot.GraphQLJavaToolsAutoConfiguration,\
4+
com.oembedler.moon.graphql.boot.GraphQLInstrumentationAutoConfiguration
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.oembedler.moon.graphql.boot.test.instrumentation;
2+
3+
import com.oembedler.moon.graphql.boot.GraphQLInstrumentationAutoConfiguration;
4+
import com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration;
5+
import com.oembedler.moon.graphql.boot.test.AbstractAutoConfigurationTest;
6+
import graphql.analysis.MaxQueryComplexityInstrumentation;
7+
import graphql.analysis.MaxQueryDepthInstrumentation;
8+
import graphql.execution.AsyncExecutionStrategy;
9+
import graphql.execution.ExecutionStrategy;
10+
import graphql.execution.instrumentation.Instrumentation;
11+
import graphql.execution.instrumentation.tracing.TracingInstrumentation;
12+
import graphql.schema.GraphQLObjectType;
13+
import graphql.schema.GraphQLSchema;
14+
import graphql.servlet.AbstractGraphQLHttpServlet;
15+
import org.junit.Assert;
16+
import org.junit.Test;
17+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
18+
import org.springframework.context.annotation.Bean;
19+
import org.springframework.context.annotation.Configuration;
20+
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
21+
22+
/**
23+
* @author Marcel Overdijk
24+
*/
25+
public class GraphQLInstrumentationAutoConfigurationTest extends AbstractAutoConfigurationTest {
26+
27+
public GraphQLInstrumentationAutoConfigurationTest() {
28+
super(AnnotationConfigWebApplicationContext.class, GraphQLInstrumentationAutoConfiguration.class);
29+
}
30+
31+
@Configuration
32+
static class DefaultConfiguration {
33+
34+
@Bean
35+
GraphQLSchema schema() {
36+
return GraphQLSchema.newSchema().query(GraphQLObjectType.newObject().name("Query").build()).build();
37+
}
38+
39+
}
40+
41+
@Test(expected = NoSuchBeanDefinitionException.class)
42+
public void noDefaultInstrumentations() {
43+
load(DefaultConfiguration.class);
44+
45+
this.getContext().getBean(Instrumentation.class);
46+
}
47+
48+
@Test(expected = NoSuchBeanDefinitionException.class)
49+
public void tracingInstrumentationDisabled() {
50+
load(DefaultConfiguration.class, "graphql.servlet.tracingEnabled=false");
51+
52+
this.getContext().getBean(TracingInstrumentation.class);
53+
}
54+
55+
@Test
56+
public void tracingInstrumentationEnabled() {
57+
load(DefaultConfiguration.class, "graphql.servlet.tracingEnabled=true");
58+
59+
Assert.assertNotNull(this.getContext().getBean(TracingInstrumentation.class));
60+
}
61+
62+
@Test
63+
public void maxQueryComplexityEnabled() {
64+
load(DefaultConfiguration.class, "graphql.servlet.maxQueryComplexity=10");
65+
66+
Assert.assertNotNull(this.getContext().getBean(MaxQueryComplexityInstrumentation.class));
67+
}
68+
69+
@Test
70+
public void maxQueryDepthEnabled() {
71+
load(DefaultConfiguration.class, "graphql.servlet.maxQueryDepth=10");
72+
73+
Assert.assertNotNull(this.getContext().getBean(MaxQueryDepthInstrumentation.class));
74+
}
75+
}

graphql-spring-boot-autoconfigure/src/test/java/com/oembedler/moon/graphql/boot/test/web/GraphQLWebAutoConfigurationTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
import com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration;
44
import com.oembedler.moon.graphql.boot.test.AbstractAutoConfigurationTest;
5+
import graphql.analysis.MaxQueryComplexityInstrumentation;
6+
import graphql.analysis.MaxQueryDepthInstrumentation;
57
import graphql.execution.AsyncExecutionStrategy;
68
import graphql.execution.ExecutionStrategy;
9+
import graphql.execution.instrumentation.tracing.TracingInstrumentation;
710
import graphql.schema.GraphQLObjectType;
811
import graphql.schema.GraphQLSchema;
912
import graphql.servlet.AbstractGraphQLHttpServlet;
@@ -98,4 +101,46 @@ public void appContextLoadsWithThreeExecutionStrategies() {
98101

99102
Assert.assertNotNull(this.getContext().getBean(AbstractGraphQLHttpServlet.class));
100103
}
104+
105+
@Configuration
106+
static class OneInstrumentationConfiguration extends SimpleConfiguration {
107+
@Bean
108+
public TracingInstrumentation tracingInstrumentation() {
109+
return new TracingInstrumentation();
110+
}
111+
}
112+
113+
@Configuration
114+
static class MultipleInstrumentationsConfiguration extends OneInstrumentationConfiguration {
115+
@Bean
116+
public MaxQueryComplexityInstrumentation maxQueryComplexityInstrumentation() {
117+
return new MaxQueryComplexityInstrumentation(10);
118+
}
119+
120+
@Bean
121+
public MaxQueryDepthInstrumentation maxQueryDepthInstrumentation() {
122+
return new MaxQueryDepthInstrumentation(10);
123+
}
124+
}
125+
126+
@Test
127+
public void appContextLoadsWithNoInstrumentation() {
128+
load(SimpleConfiguration.class);
129+
130+
Assert.assertNotNull(this.getContext().getBean(AbstractGraphQLHttpServlet.class));
131+
}
132+
133+
@Test
134+
public void appContextLoadsWithOneInstrumentation() {
135+
load(OneInstrumentationConfiguration.class);
136+
137+
Assert.assertNotNull(this.getContext().getBean(AbstractGraphQLHttpServlet.class));
138+
}
139+
140+
@Test
141+
public void appContextLoadsWithMultipleInstrumentations() {
142+
load(MultipleInstrumentationsConfiguration.class);
143+
144+
Assert.assertNotNull(this.getContext().getBean(AbstractGraphQLHttpServlet.class));
145+
}
101146
}

0 commit comments

Comments
 (0)