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

Commit 96b4efb

Browse files
committed
Use refactored websocket subscriptions
1 parent f4180a9 commit 96b4efb

File tree

4 files changed

+104
-73
lines changed

4 files changed

+104
-73
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,51 @@
11
package graphql.servlet.examples.dataloader.requestscope;
22

3-
import graphql.servlet.context.DefaultGraphQLContext;
3+
import graphql.kickstart.execution.context.DefaultGraphQLContext;
4+
import graphql.kickstart.execution.context.GraphQLContext;
45
import graphql.servlet.context.DefaultGraphQLServletContext;
56
import graphql.servlet.context.DefaultGraphQLWebSocketContext;
6-
import graphql.servlet.context.GraphQLContext;
7-
import graphql.servlet.context.GraphQLContextBuilder;
8-
import org.dataloader.DataLoader;
9-
import org.dataloader.DataLoaderRegistry;
10-
import org.springframework.stereotype.Component;
11-
7+
import graphql.servlet.context.GraphQLServletContextBuilder;
8+
import java.util.concurrent.CompletableFuture;
129
import javax.servlet.http.HttpServletRequest;
1310
import javax.servlet.http.HttpServletResponse;
1411
import javax.websocket.Session;
1512
import javax.websocket.server.HandshakeRequest;
16-
import java.util.concurrent.CompletableFuture;
13+
import org.dataloader.DataLoader;
14+
import org.dataloader.DataLoaderRegistry;
15+
import org.springframework.stereotype.Component;
1716

1817
@Component
19-
public class CustomGraphQLContextBuilder implements GraphQLContextBuilder {
20-
21-
private final CustomerRepository customerRepository;
22-
23-
public CustomGraphQLContextBuilder(CustomerRepository customerRepository) {
24-
this.customerRepository = customerRepository;
25-
}
26-
27-
@Override
28-
public GraphQLContext build(HttpServletRequest req, HttpServletResponse response) {
29-
return DefaultGraphQLServletContext.createServletContext(buildDataLoaderRegistry(), null).with(req).with(response).build();
30-
}
31-
32-
@Override
33-
public GraphQLContext build() {
34-
return new DefaultGraphQLContext(buildDataLoaderRegistry(), null);
35-
}
36-
37-
@Override
38-
public GraphQLContext build(Session session, HandshakeRequest request) {
39-
return DefaultGraphQLWebSocketContext.createWebSocketContext(buildDataLoaderRegistry(), null).with(session).with(request).build();
40-
}
41-
42-
private DataLoaderRegistry buildDataLoaderRegistry() {
43-
DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();
44-
dataLoaderRegistry.register("customerDataLoader",
45-
new DataLoader<Integer, String>(customerIds ->
46-
CompletableFuture.supplyAsync(() ->
47-
customerRepository.getUserNamesForIds(customerIds))));
48-
return dataLoaderRegistry;
49-
}
18+
public class CustomGraphQLContextBuilder implements GraphQLServletContextBuilder {
19+
20+
private final CustomerRepository customerRepository;
21+
22+
public CustomGraphQLContextBuilder(CustomerRepository customerRepository) {
23+
this.customerRepository = customerRepository;
24+
}
25+
26+
@Override
27+
public GraphQLContext build(HttpServletRequest req, HttpServletResponse response) {
28+
return DefaultGraphQLServletContext.createServletContext(buildDataLoaderRegistry(), null).with(req).with(response)
29+
.build();
30+
}
31+
32+
@Override
33+
public GraphQLContext build() {
34+
return new DefaultGraphQLContext(buildDataLoaderRegistry(), null);
35+
}
36+
37+
@Override
38+
public GraphQLContext build(Session session, HandshakeRequest request) {
39+
return DefaultGraphQLWebSocketContext.createWebSocketContext(buildDataLoaderRegistry(), null).with(session)
40+
.with(request).build();
41+
}
42+
43+
private DataLoaderRegistry buildDataLoaderRegistry() {
44+
DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();
45+
dataLoaderRegistry.register("customerDataLoader",
46+
new DataLoader<Integer, String>(customerIds ->
47+
CompletableFuture.supplyAsync(() ->
48+
customerRepository.getUserNamesForIds(customerIds))));
49+
return dataLoaderRegistry;
50+
}
5051
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
1414
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
1515
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
16+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
1617
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
1718
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
1819
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -24,6 +25,7 @@
2425
* @author Marcel Overdijk
2526
*/
2627
@Configuration
28+
@ConditionalOnClass(MetricsAutoConfiguration.class)
2729
@AutoConfigureAfter({MetricsAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class,
2830
GraphQLWebsocketAutoConfiguration.class})
2931
@ConditionalOnProperty(value = "graphql.servlet.enabled", havingValue = "true", matchIfMissing = true)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,19 @@
2626
import com.oembedler.moon.graphql.boot.error.ErrorHandlerSupplier;
2727
import com.oembedler.moon.graphql.boot.error.GraphQLErrorStartupListener;
2828
import com.oembedler.moon.graphql.boot.metrics.MetricsInstrumentation;
29+
import graphql.GraphQL;
2930
import graphql.execution.AsyncExecutionStrategy;
3031
import graphql.execution.ExecutionStrategy;
3132
import graphql.execution.SubscriptionExecutionStrategy;
3233
import graphql.execution.instrumentation.Instrumentation;
3334
import graphql.execution.preparsed.PreparsedDocumentProvider;
35+
import graphql.kickstart.execution.GraphQLInvoker;
3436
import graphql.kickstart.execution.GraphQLObjectMapper;
3537
import graphql.kickstart.execution.GraphQLQueryInvoker;
3638
import graphql.kickstart.execution.config.DefaultExecutionStrategyProvider;
3739
import graphql.kickstart.execution.config.DefaultGraphQLSchemaProvider;
3840
import graphql.kickstart.execution.config.ExecutionStrategyProvider;
41+
import graphql.kickstart.execution.config.GraphQLBuilder;
3942
import graphql.kickstart.execution.config.GraphQLSchemaProvider;
4043
import graphql.kickstart.execution.config.ObjectMapperConfigurer;
4144
import graphql.kickstart.execution.config.ObjectMapperProvider;
Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
package com.oembedler.moon.graphql.boot;
22

3+
import graphql.GraphQL;
4+
import graphql.kickstart.execution.GraphQLInvoker;
35
import graphql.kickstart.execution.GraphQLObjectMapper;
4-
import graphql.kickstart.execution.GraphQLQueryInvoker;
5-
import graphql.kickstart.execution.subscription.SubscriptionConnectionListener;
6+
import graphql.kickstart.execution.config.GraphQLBuilder;
7+
import graphql.kickstart.execution.subscriptions.GraphQLSubscriptionInvocationInputFactory;
8+
import graphql.kickstart.execution.subscriptions.SubscriptionConnectionListener;
9+
import graphql.kickstart.execution.subscriptions.apollo.KeepAliveSubscriptionConnectionListener;
610
import graphql.kickstart.tools.boot.GraphQLJavaToolsAutoConfiguration;
11+
import graphql.schema.GraphQLSchema;
712
import graphql.servlet.GraphQLWebsocketServlet;
8-
import graphql.servlet.apollo.ApolloSubscriptionConnectionListener;
9-
import graphql.servlet.input.GraphQLInvocationInputFactory;
13+
import java.time.Duration;
14+
import java.util.Collection;
15+
import java.util.HashSet;
16+
import java.util.Optional;
17+
import java.util.Set;
18+
import javax.websocket.server.ServerContainer;
1019
import org.springframework.beans.factory.annotation.Autowired;
1120
import org.springframework.beans.factory.annotation.Value;
1221
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
13-
import org.springframework.boot.autoconfigure.condition.*;
22+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
25+
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
1426
import org.springframework.boot.context.properties.EnableConfigurationProperties;
1527
import org.springframework.context.annotation.Bean;
1628
import org.springframework.context.annotation.Conditional;
@@ -19,9 +31,6 @@
1931
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
2032
import org.springframework.web.socket.server.standard.ServerEndpointRegistration;
2133

22-
import javax.websocket.server.ServerContainer;
23-
import java.time.Duration;
24-
2534
@Configuration
2635
@ConditionalOnWebApplication
2736
@ConditionalOnClass(DispatcherServlet.class)
@@ -31,38 +40,54 @@
3140
@EnableConfigurationProperties(GraphQLSubscriptionApolloProperties.class)
3241
public class GraphQLWebsocketAutoConfiguration {
3342

34-
@Value("${graphql.servlet.subscriptions.websocket.path:/subscriptions}")
35-
private String websocketPath;
43+
@Value("${graphql.servlet.subscriptions.websocket.path:/subscriptions}")
44+
private String websocketPath;
3645

37-
@Autowired
38-
private GraphQLSubscriptionApolloProperties apolloProperties;
46+
@Autowired
47+
private GraphQLSubscriptionApolloProperties apolloProperties;
3948

40-
@Bean
41-
@ConditionalOnMissingBean
42-
public SubscriptionConnectionListener subscriptionConnectionListener() {
43-
if (!apolloProperties.isKeepAliveEnabled()) {
44-
return ApolloSubscriptionConnectionListener.createWithKeepAliveDisabled();
45-
}
46-
return ApolloSubscriptionConnectionListener.createWithKeepAliveInterval(Duration.ofSeconds(apolloProperties.getKeepAliveIntervalSeconds()));
47-
}
49+
@Bean
50+
@ConditionalOnMissingBean
51+
public GraphQLInvoker graphQLInvoker(GraphQLSchema schema) {
52+
GraphQL graphQL = new GraphQLBuilder().build(schema);
53+
return new GraphQLInvoker(graphQL);
54+
}
4855

49-
@Bean
50-
@ConditionalOnMissingBean
51-
public GraphQLWebsocketServlet graphQLWebsocketServlet(GraphQLInvocationInputFactory invocationInputFactory, GraphQLQueryInvoker queryInvoker, GraphQLObjectMapper graphQLObjectMapper, SubscriptionConnectionListener subscriptionConnectionListener) {
52-
return new GraphQLWebsocketServlet(queryInvoker, invocationInputFactory, graphQLObjectMapper, subscriptionConnectionListener);
56+
@Bean
57+
@ConditionalOnMissingBean
58+
public GraphQLWebsocketServlet graphQLWebsocketServlet(
59+
GraphQLSubscriptionInvocationInputFactory invocationInputFactory,
60+
GraphQLInvoker graphQLInvoker,
61+
GraphQLObjectMapper graphQLObjectMapper,
62+
@Autowired(required = false) Collection<SubscriptionConnectionListener> connectionListeners) {
63+
Set<SubscriptionConnectionListener> listeners = new HashSet<>();
64+
if (connectionListeners != null) {
65+
listeners.addAll(connectionListeners);
5366
}
67+
keepAliveListener().ifPresent(listeners::add);
68+
return new GraphQLWebsocketServlet(graphQLInvoker, invocationInputFactory, graphQLObjectMapper, listeners);
69+
}
5470

55-
@Bean
56-
@ConditionalOnClass(ServerContainer.class)
57-
public ServerEndpointRegistration serverEndpointRegistration(GraphQLWebsocketServlet servlet) {
58-
return new GraphQLWsServerEndpointRegistration(websocketPath, servlet);
71+
private Optional<SubscriptionConnectionListener> keepAliveListener() {
72+
if (apolloProperties.isKeepAliveEnabled()) {
73+
return Optional.of(new KeepAliveSubscriptionConnectionListener(
74+
Duration.ofSeconds(apolloProperties.getKeepAliveIntervalSeconds()))
75+
);
5976
}
77+
return Optional.empty();
78+
}
6079

61-
@Bean
62-
@ConditionalOnMissingBean
63-
@ConditionalOnClass(ServerContainer.class)
64-
public ServerEndpointExporter serverEndpointExporter() {
65-
return new ServerEndpointExporter();
66-
}
80+
@Bean
81+
@ConditionalOnClass(ServerContainer.class)
82+
public ServerEndpointRegistration serverEndpointRegistration(GraphQLWebsocketServlet servlet) {
83+
return new GraphQLWsServerEndpointRegistration(websocketPath, servlet);
84+
}
85+
86+
@Bean
87+
@ConditionalOnMissingBean
88+
@ConditionalOnClass(ServerContainer.class)
89+
public ServerEndpointExporter serverEndpointExporter() {
90+
return new ServerEndpointExporter();
91+
}
6792

6893
}

0 commit comments

Comments
 (0)