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

Commit f834807

Browse files
authored
Merge pull request #497 from graphql-java-kickstart/sonar-fixes
Sonar fixes
2 parents e208f75 + 8328525 commit f834807

File tree

12 files changed

+107
-194
lines changed

12 files changed

+107
-194
lines changed

.github/workflows/pull-request.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
name: "Pull request"
22
on:
3-
push:
4-
branches-ignore:
5-
- master
63
pull_request:
74
types: [ opened, synchronize, reopened ]
85

example-spring-common/src/main/java/graphql/kickstart/spring/web/boot/sample/SimpleListConnection.java

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,46 @@
33
import com.oembedler.moon.graphql.engine.relay.ConnectionObjectType;
44
import com.oembedler.moon.graphql.engine.relay.EdgeObjectType;
55
import com.oembedler.moon.graphql.engine.relay.PageInfoObjectType;
6-
import graphql.relay.ConnectionCursor;
7-
import graphql.relay.DefaultConnectionCursor;
86
import graphql.schema.DataFetchingEnvironment;
97
import java.nio.charset.StandardCharsets;
108
import java.util.ArrayList;
119
import java.util.Base64;
1210
import java.util.List;
11+
import lombok.AccessLevel;
12+
import lombok.RequiredArgsConstructor;
1313

1414
/**
1515
* @author <a href="mailto:[email protected]">oEmbedler Inc.</a>
1616
*/
17-
public class SimpleListConnection {
17+
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
18+
public abstract class SimpleListConnection<T> {
1819

1920
private static final String DUMMY_CURSOR_PREFIX = "simple-cursor";
20-
private final List<?> data;
21+
private final List<T> data;
2122

22-
public SimpleListConnection(List<?> data) {
23-
this.data = data;
24-
}
25-
26-
public <E extends EdgeObjectType> E createEdgeObject() {
27-
return (E) new EdgeObjectType();
28-
}
23+
public abstract <E extends EdgeObjectType<T>> E createEdgeObject();
2924

30-
public <E extends ConnectionObjectType> E createConnectionObject() {
31-
return (E) new ConnectionObjectType();
32-
}
25+
public abstract <C extends ConnectionObjectType<? extends EdgeObjectType<T>, ? extends PageInfoObjectType>> C createConnectionObject();
3326

34-
private List<EdgeObjectType> buildEdges() {
35-
List<EdgeObjectType> edges = new ArrayList<>();
27+
private List<EdgeObjectType<T>> buildEdges() {
28+
List<EdgeObjectType<T>> edges = new ArrayList<>();
3629
int ix = 0;
37-
for (Object object : data) {
38-
EdgeObjectType edge = createEdgeObject();
30+
for (T object : data) {
31+
EdgeObjectType<T> edge = createEdgeObject();
3932
edge.setNode(object);
4033
edge.setCursor(createCursor(ix++));
4134
edges.add(edge);
4235
}
4336
return edges;
4437
}
4538

46-
public <C extends ConnectionObjectType> C get(DataFetchingEnvironment environment) {
39+
public <C extends ConnectionObjectType<? extends EdgeObjectType<T>, ? extends PageInfoObjectType>> C get(
40+
DataFetchingEnvironment environment) {
41+
List<EdgeObjectType<T>> edges = buildEdges();
4742

48-
List<EdgeObjectType> edges = buildEdges();
49-
50-
int afterOffset = getOffsetFromCursor(environment.<String>getArgument("after"), -1);
43+
int afterOffset = getOffsetFromCursor(environment.getArgument("after"), -1);
5144
int begin = Math.max(afterOffset, -1) + 1;
52-
int beforeOffset = getOffsetFromCursor(environment.<String>getArgument("before"), edges.size());
45+
int beforeOffset = getOffsetFromCursor(environment.getArgument("before"), edges.size());
5346
int end = Math.min(beforeOffset, edges.size());
5447

5548
edges = edges.subList(begin, end);
@@ -74,34 +67,30 @@ public <C extends ConnectionObjectType> C get(DataFetchingEnvironment environmen
7467
return emptyConnection();
7568
}
7669

77-
EdgeObjectType firstEdge = edges.get(0);
78-
EdgeObjectType lastEdge = edges.get(edges.size() - 1);
70+
EdgeObjectType<T> firstEdge = edges.get(0);
71+
EdgeObjectType<T> lastEdge = edges.get(edges.size() - 1);
7972

8073
PageInfoObjectType pageInfo = new PageInfoObjectType();
8174
pageInfo.setStartCursor(firstEdge.getCursor());
8275
pageInfo.setEndCursor(lastEdge.getCursor());
8376
pageInfo.setHasPreviousPage(!firstEdge.getCursor().equals(firstPresliceCursor));
8477
pageInfo.setHasNextPage(!lastEdge.getCursor().equals(lastPresliceCursor));
8578

86-
ConnectionObjectType connection = createConnectionObject();
79+
ConnectionObjectType<EdgeObjectType<T>, PageInfoObjectType> connection = createConnectionObject();
8780
connection.setEdges(edges);
8881
connection.setPageInfo(pageInfo);
8982

83+
//noinspection unchecked
9084
return (C) connection;
9185
}
9286

93-
private <E extends ConnectionObjectType> E emptyConnection() {
94-
ConnectionObjectType connection = createConnectionObject();
87+
private <E extends ConnectionObjectType<? extends EdgeObjectType<T>, ? extends PageInfoObjectType>> E emptyConnection() {
88+
ConnectionObjectType<EdgeObjectType<T>, PageInfoObjectType> connection = createConnectionObject();
9589
connection.setPageInfo(new PageInfoObjectType());
90+
//noinspection unchecked
9691
return (E) connection;
9792
}
9893

99-
public ConnectionCursor cursorForObjectInConnection(Object object) {
100-
int index = data.indexOf(object);
101-
String cursor = createCursor(index);
102-
return new DefaultConnectionCursor(cursor);
103-
}
104-
10594
private int getOffsetFromCursor(String cursor, int defaultValue) {
10695
if (cursor == null) {
10796
return defaultValue;
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
package graphql.kickstart.spring.web.boot.sample;
22

3-
import com.oembedler.moon.graphql.engine.relay.ConnectionObjectType;
4-
import com.oembedler.moon.graphql.engine.relay.EdgeObjectType;
53
import graphql.kickstart.spring.web.boot.sample.schema.objecttype.TodoObjectType;
4+
import graphql.kickstart.spring.web.boot.sample.schema.objecttype.TodoObjectType.TodoConnectionObjectType;
5+
import graphql.kickstart.spring.web.boot.sample.schema.objecttype.TodoObjectType.TodoEdgeObjectType;
66
import java.util.List;
77

88
/**
99
* @author <a href="mailto:[email protected]">oEmbedler Inc.</a>
1010
*/
11-
public class TodoSimpleListConnection extends SimpleListConnection {
11+
@SuppressWarnings("unchecked")
12+
public class TodoSimpleListConnection extends SimpleListConnection<TodoObjectType> {
1213

13-
public TodoSimpleListConnection(List<?> data) {
14+
public TodoSimpleListConnection(List<TodoObjectType> data) {
1415
super(data);
1516
}
1617

1718
@Override
18-
public <T extends EdgeObjectType> T createEdgeObject() {
19-
return (T) new TodoObjectType.TodoEdgeObjectType();
19+
public TodoEdgeObjectType createEdgeObject() {
20+
return new TodoObjectType.TodoEdgeObjectType();
2021
}
2122

2223
@Override
23-
public <T extends ConnectionObjectType> T createConnectionObject() {
24-
return (T) new TodoObjectType.TodoConnectionObjectType();
24+
public TodoConnectionObjectType createConnectionObject() {
25+
return new TodoObjectType.TodoConnectionObjectType();
2526
}
2627

2728
}

graphql-kickstart-spring-support/src/main/java/graphql/kickstart/spring/error/ReflectiveGraphQLErrorFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ public Optional<Class<? extends Throwable>> mostConcrete(Throwable t) {
3636
@Override
3737
public Collection<GraphQLError> create(Throwable t, ErrorContext errorContext) {
3838
try {
39-
method.setAccessible(true);
4039
if (singularReturnType) {
4140
return singletonList((GraphQLError) invoke(t, errorContext));
4241
}
42+
//noinspection unchecked
4343
return (Collection<GraphQLError>) invoke(t, errorContext);
4444
} catch (IllegalAccessException | InvocationTargetException e) {
4545
log.error("Cannot create GraphQLError from throwable {}", t.getClass().getSimpleName(), e);

graphql-spring-boot-autoconfigure/src/test/java/graphql/kickstart/spring/web/boot/GraphQLErrorHandlerTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ void illegalArgumentExceptionShouldBeHandledConcretely() {
4343
TestUtils.assertGraphQLError(
4444
gql,
4545
"query { illegalArgumentException }",
46-
new ThrowableGraphQLError(new IllegalArgumentException("Illegal argument"),
47-
"Illegal argument"),
46+
new ThrowableGraphQLError(new IllegalArgumentException("Some argument"),
47+
"Custom illegal argument"),
4848
objectMapper
4949
);
5050
}
@@ -70,12 +70,12 @@ boolean illegalStateException() {
7070
}
7171

7272
@ExceptionHandler(IllegalArgumentException.class)
73-
ThrowableGraphQLError handle(IllegalArgumentException e) {
74-
return new ThrowableGraphQLError(e, "Illegal argument");
73+
public ThrowableGraphQLError handle(IllegalArgumentException e) {
74+
return new ThrowableGraphQLError(e, "Custom illegal argument");
7575
}
7676

7777
@ExceptionHandler(Throwable.class)
78-
GraphQLError handle(Throwable e) {
78+
public GraphQLError handle(Throwable e) {
7979
return new ThrowableGraphQLError(e, "Catch all handler");
8080
}
8181

graphql-spring-boot-test/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ dependencies {
2121
implementation("org.springframework.boot:spring-boot-starter-test")
2222
implementation("com.fasterxml.jackson.core:jackson-databind")
2323
implementation("com.jayway.jsonpath:json-path")
24+
implementation 'org.awaitility:awaitility:4.0.3'
2425
compileOnly("com.graphql-java:graphql-java:$LIB_GRAPHQL_JAVA_VER")
2526
compileOnly("com.graphql-java-kickstart:graphql-java-servlet:$LIB_GRAPHQL_SERVLET_VER")
2627
testImplementation("org.springframework.boot:spring-boot-starter-web")

graphql-spring-boot-test/src/main/java/com/graphql/spring/boot/test/GraphQLTestSubscription.java

Lines changed: 47 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.graphql.spring.boot.test;
22

33
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.awaitility.Awaitility.await;
45
import static org.junit.jupiter.api.Assertions.fail;
56

67
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -18,6 +19,7 @@
1819
import java.util.Map;
1920
import java.util.Optional;
2021
import java.util.Queue;
22+
import java.util.concurrent.TimeUnit;
2123
import java.util.concurrent.atomic.AtomicInteger;
2224
import java.util.function.Predicate;
2325
import javax.websocket.ClientEndpointConfig;
@@ -49,7 +51,6 @@ public class GraphQLTestSubscription {
4951

5052
private static final WebSocketContainer WEB_SOCKET_CONTAINER = ContainerProvider
5153
.getWebSocketContainer();
52-
private static final int SLEEP_INTERVAL_MS = 100;
5354
private static final int ACKNOWLEDGEMENT_AND_CONNECTION_TIMEOUT = 60000;
5455
private static final AtomicInteger ID_COUNTER = new AtomicInteger(1);
5556
private static final UriBuilderFactory URI_BUILDER_FACTORY = new DefaultUriBuilderFactory();
@@ -115,7 +116,7 @@ public GraphQLTestSubscription init(@Nullable final Object payload) {
115116
sendMessage(message);
116117
state.setInitialized(true);
117118
awaitAcknowledgement();
118-
log.debug("Subscription successfully initialized.");
119+
log.debug("Subscription successfully initialized");
119120
return this;
120121
}
121122

@@ -134,12 +135,12 @@ public GraphQLTestSubscription start(@NonNull final String graphQLResource) {
134135
/**
135136
* Sends the "start" message to the GraphQL Subscription.
136137
*
137-
* @param graphGLResource the GraphQL resource, which contains the query for the subscription
138+
* @param graphQLResource the GraphQL resource, which contains the query for the subscription
138139
* start payload.
139140
* @param variables the variables needed for the query to be evaluated.
140141
* @return self reference
141142
*/
142-
public GraphQLTestSubscription start(@NonNull final String graphGLResource,
143+
public GraphQLTestSubscription start(@NonNull final String graphQLResource,
143144
@Nullable final Object variables) {
144145
if (!isInitialized()) {
145146
init();
@@ -149,7 +150,7 @@ public GraphQLTestSubscription start(@NonNull final String graphGLResource,
149150
}
150151
state.setStarted(true);
151152
ObjectNode payload = objectMapper.createObjectNode();
152-
payload.put("query", loadQuery(graphGLResource));
153+
payload.put("query", loadQuery(graphQLResource));
153154
payload.set("variables", getFinalPayload(variables));
154155
ObjectNode message = objectMapper.createObjectNode();
155156
message.put("type", "start");
@@ -298,18 +299,11 @@ public List<GraphQLResponse> awaitAndGetNextResponses(
298299
if (isStopped()) {
299300
fail("Subscription already stopped. Forgot to call reset after test case?");
300301
}
301-
int elapsedTime = 0;
302-
while (
303-
((state.getResponses().size() < numExpectedResponses) || numExpectedResponses <= 0)
304-
&& elapsedTime < timeout
305-
) {
306-
try {
307-
Thread.sleep(SLEEP_INTERVAL_MS);
308-
elapsedTime += SLEEP_INTERVAL_MS;
309-
} catch (InterruptedException e) {
310-
fail("Test execution error - Thread.sleep failed.", e);
311-
}
312-
}
302+
303+
await()
304+
.atMost(timeout, TimeUnit.MILLISECONDS)
305+
.until(() -> state.getResponses().size() >= numExpectedResponses);
306+
313307
if (stopAfter) {
314308
stop();
315309
}
@@ -420,29 +414,21 @@ private void sendMessage(final Object message) {
420414
}
421415

422416
private void awaitAcknowledgement() {
423-
await(GraphQLTestSubscription::isAcknowledged,
424-
"Connection was not acknowledged by the GraphQL server.");
417+
awaitAcknowledgementOrConnection(GraphQLTestSubscription::isAcknowledged,
418+
"Connection was acknowledged by the GraphQL server.");
425419
}
426420

427421
private void awaitStop() {
428-
await(GraphQLTestSubscription::isStopped, "Connection was not stopped in time.");
422+
awaitAcknowledgementOrConnection(GraphQLTestSubscription::isStopped,
423+
"Connection was stopped in time.");
429424
}
430425

431-
private void await(final Predicate<GraphQLTestSubscription> condition,
426+
private void awaitAcknowledgementOrConnection(final Predicate<GraphQLTestSubscription> condition,
432427
final String timeoutDescription) {
433-
int elapsedTime = 0;
434-
while (!condition.test(this) && elapsedTime < ACKNOWLEDGEMENT_AND_CONNECTION_TIMEOUT) {
435-
try {
436-
Thread.sleep(SLEEP_INTERVAL_MS);
437-
elapsedTime += SLEEP_INTERVAL_MS;
438-
} catch (InterruptedException e) {
439-
fail("Test execution error - Thread.sleep failed.", e);
440-
}
441-
}
428+
await(timeoutDescription)
429+
.atMost(ACKNOWLEDGEMENT_AND_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
430+
.until(() -> condition.test(this));
442431

443-
if (!condition.test(this)) {
444-
fail("Timeout: " + timeoutDescription);
445-
}
446432
}
447433

448434
@RequiredArgsConstructor
@@ -460,28 +446,35 @@ public void onMessage(final String message) {
460446
assertThat(typeNode).as("GraphQL messages should have a type field.").isNotNull();
461447
assertThat(typeNode.isNull()).as("GraphQL messages type should not be null.").isFalse();
462448
final String type = typeNode.asText();
463-
if (type.equals("complete")) {
464-
state.setCompleted(true);
465-
log.debug("Subscription completed.");
466-
} else if (type.equals("connection_ack")) {
467-
state.setAcknowledged(true);
468-
log.debug("WebSocket connection acknowledged by the GraphQL Server.");
469-
} else if (type.equals("data") || type.equals("error")) {
470-
final JsonNode payload = jsonNode.get(PAYLOAD);
471-
assertThat(payload).as("Data/error messages must have a payload.").isNotNull();
472-
final String payloadString = objectMapper.writeValueAsString(payload);
473-
final GraphQLResponse graphQLResponse = new GraphQLResponse(
474-
ResponseEntity.ok(payloadString),
475-
objectMapper);
476-
if (state.isStopped() || state.isCompleted()) {
477-
log.debug(
478-
"Response discarded because subscription was stopped or completed in the meanwhile.");
479-
} else {
480-
synchronized (STATE_LOCK) {
481-
state.getResponses().add(graphQLResponse);
449+
switch (type) {
450+
case "complete":
451+
state.setCompleted(true);
452+
log.debug("Subscription completed.");
453+
break;
454+
case "connection_ack":
455+
state.setAcknowledged(true);
456+
log.debug("WebSocket connection acknowledged by the GraphQL Server.");
457+
break;
458+
case "data":
459+
case "error":
460+
final JsonNode payload = jsonNode.get(PAYLOAD);
461+
assertThat(payload).as("Data/error messages must have a payload.").isNotNull();
462+
final String payloadString = objectMapper.writeValueAsString(payload);
463+
final GraphQLResponse graphQLResponse = new GraphQLResponse(
464+
ResponseEntity.ok(payloadString),
465+
objectMapper);
466+
if (state.isStopped() || state.isCompleted()) {
467+
log.debug(
468+
"Response discarded because subscription was stopped or completed in the meanwhile.");
469+
} else {
470+
synchronized (STATE_LOCK) {
471+
state.getResponses().add(graphQLResponse);
472+
}
473+
log.debug("New response recorded.");
482474
}
483-
log.debug("New response recorded.");
484-
}
475+
break;
476+
default:
477+
break;
485478
}
486479
} catch (JsonProcessingException e) {
487480
fail("Exception while parsing server response. Response is not a valid GraphQL response.",

0 commit comments

Comments
 (0)