Skip to content

Commit fdc2ded

Browse files
committed
fix(#298): move listener callbacks into new invoker
1 parent ac3b0ca commit fdc2ded

18 files changed

+2444
-2254
lines changed

.idea/codeStyles/Project.xml

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AbstractGraphQLHttpServlet.java

-37
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@
88
import graphql.kickstart.servlet.core.GraphQLMBean;
99
import graphql.kickstart.servlet.core.GraphQLServletListener;
1010
import graphql.schema.GraphQLFieldDefinition;
11-
import java.util.List;
12-
import java.util.Objects;
13-
import java.util.function.Consumer;
14-
import java.util.function.Function;
15-
import java.util.stream.Collectors;
1611
import javax.servlet.Servlet;
1712
import javax.servlet.http.HttpServlet;
1813
import javax.servlet.http.HttpServletRequest;
@@ -85,43 +80,11 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
8580
}
8681

8782
private void doRequest(HttpServletRequest request, HttpServletResponse response) {
88-
List<GraphQLServletListener.RequestCallback> requestCallbacks =
89-
runListeners(l -> l.onRequest(request, response));
90-
9183
try {
9284
getConfiguration().getHttpRequestHandler().handle(request, response);
93-
runCallbacks(requestCallbacks, c -> c.onSuccess(request, response));
9485
} catch (Exception t) {
9586
log.error("Error executing GraphQL request!", t);
96-
runCallbacks(requestCallbacks, c -> c.onError(request, response, t));
97-
} finally {
98-
runCallbacks(requestCallbacks, c -> c.onFinally(request, response));
9987
}
10088
}
10189

102-
private <R> List<R> runListeners(Function<? super GraphQLServletListener, R> action) {
103-
return getConfiguration().getListeners().stream()
104-
.map(
105-
listener -> {
106-
try {
107-
return action.apply(listener);
108-
} catch (Exception t) {
109-
log.error("Error running listener: {}", listener, t);
110-
return null;
111-
}
112-
})
113-
.filter(Objects::nonNull)
114-
.collect(Collectors.toList());
115-
}
116-
117-
private <T> void runCallbacks(List<T> callbacks, Consumer<T> action) {
118-
callbacks.forEach(
119-
callback -> {
120-
try {
121-
action.accept(callback);
122-
} catch (Exception t) {
123-
log.error("Error running callback: {}", callback, t);
124-
}
125-
});
126-
}
12790
}

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/HttpRequestInvokerImpl.java

+24-15
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,41 @@ public void execute(
3232
HttpServletRequest request,
3333
HttpServletResponse response) {
3434
if (request.isAsyncSupported()) {
35-
AsyncContext asyncContext =
36-
request.isAsyncStarted()
37-
? request.getAsyncContext()
38-
: request.startAsync(request, response);
35+
AsyncContext asyncContext = request.isAsyncStarted()
36+
? request.getAsyncContext()
37+
: request.startAsync(request, response);
3938
asyncContext.setTimeout(configuration.getAsyncTimeout());
40-
invoke(invocationInput, request, response)
41-
.thenAccept(result -> writeResultResponse(invocationInput, result, request, response))
42-
.exceptionally(t -> writeErrorResponse(t, response))
39+
invokeAndHandle(invocationInput, request, response)
4340
.thenAccept(aVoid -> asyncContext.complete());
4441
} else {
45-
try {
46-
GraphQLQueryResult result = invoke(invocationInput, request, response).join();
47-
writeResultResponse(invocationInput, result, request, response);
48-
} catch (Exception t) {
49-
writeErrorResponse(t, response);
50-
}
42+
invokeAndHandle(invocationInput, request, response).join();
5143
}
5244
}
5345

46+
private CompletableFuture<Void> invokeAndHandle(
47+
GraphQLInvocationInput invocationInput,
48+
HttpServletRequest request,
49+
HttpServletResponse response
50+
) {
51+
ListenerHandler listenerHandler = ListenerHandler
52+
.start(request, response, configuration.getListeners());
53+
return invoke(invocationInput, request, response)
54+
.thenAccept(result ->
55+
writeResultResponse(invocationInput, result, request, response, listenerHandler))
56+
.exceptionally(t -> writeErrorResponse(t, response, listenerHandler))
57+
.thenAccept(aVoid -> listenerHandler.onFinally());
58+
}
59+
5460
private void writeResultResponse(
5561
GraphQLInvocationInput invocationInput,
5662
GraphQLQueryResult queryResult,
5763
HttpServletRequest request,
58-
HttpServletResponse response) {
64+
HttpServletResponse response,
65+
ListenerHandler listenerHandler) {
5966
QueryResponseWriter queryResponseWriter = createWriter(invocationInput, queryResult);
6067
try {
6168
queryResponseWriter.write(request, response);
69+
listenerHandler.onSuccess();
6270
} catch (IOException e) {
6371
throw new UncheckedIOException(e);
6472
}
@@ -69,10 +77,11 @@ protected QueryResponseWriter createWriter(
6977
return queryResponseWriterFactory.createWriter(invocationInput, queryResult, configuration);
7078
}
7179

72-
private Void writeErrorResponse(Throwable t, HttpServletResponse response) {
80+
private Void writeErrorResponse(Throwable t, HttpServletResponse response, ListenerHandler listenerHandler) {
7381
response.setStatus(STATUS_BAD_REQUEST);
7482
log.info(
7583
"Bad request: path was not \"/schema.json\" or no query variable named \"query\" given", t);
84+
listenerHandler.onError(t);
7685
return null;
7786
}
7887

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package graphql.kickstart.servlet;
2+
3+
import static java.util.Collections.emptyList;
4+
5+
import graphql.kickstart.servlet.core.GraphQLServletListener;
6+
import graphql.kickstart.servlet.core.GraphQLServletListener.RequestCallback;
7+
import java.util.List;
8+
import java.util.Objects;
9+
import java.util.function.Consumer;
10+
import java.util.function.Function;
11+
import java.util.stream.Collectors;
12+
import javax.servlet.http.HttpServletRequest;
13+
import javax.servlet.http.HttpServletResponse;
14+
import lombok.RequiredArgsConstructor;
15+
import lombok.extern.slf4j.Slf4j;
16+
17+
@Slf4j
18+
@RequiredArgsConstructor
19+
class ListenerHandler {
20+
21+
private final List<RequestCallback> callbacks;
22+
private final HttpServletRequest request;
23+
private final HttpServletResponse response;
24+
25+
static ListenerHandler start(HttpServletRequest request, HttpServletResponse response,
26+
List<GraphQLServletListener> listeners) {
27+
if (listeners != null) {
28+
return new ListenerHandler(runListeners(listeners, it -> it.onRequest(request, response)),
29+
request, response);
30+
}
31+
return new ListenerHandler(emptyList(), request, response);
32+
}
33+
34+
private static <R> List<R> runListeners(List<GraphQLServletListener> listeners,
35+
Function<? super GraphQLServletListener, R> action) {
36+
return listeners.stream()
37+
.map(
38+
listener -> {
39+
try {
40+
return action.apply(listener);
41+
} catch (Exception t) {
42+
log.error("Error running listener: {}", listener, t);
43+
return null;
44+
}
45+
})
46+
.filter(Objects::nonNull)
47+
.collect(Collectors.toList());
48+
}
49+
50+
<T> void runCallbacks(List<T> callbacks, Consumer<T> action) {
51+
callbacks.forEach(
52+
callback -> {
53+
try {
54+
action.accept(callback);
55+
} catch (Exception t) {
56+
log.error("Error running callback: {}", callback, t);
57+
}
58+
});
59+
}
60+
61+
void onSuccess() {
62+
callbacks.forEach(it -> it.onSuccess(request, response));
63+
}
64+
65+
void onError(Throwable throwable) {
66+
callbacks.forEach(it -> it.onError(request, response, throwable));
67+
}
68+
69+
void onFinally() {
70+
callbacks.forEach(it -> it.onFinally(request, response));
71+
}
72+
}

0 commit comments

Comments
 (0)