Skip to content

Commit 7b58f88

Browse files
authored
Merge pull request #290 from graphql-java-kickstart/bugfix/response-from-cache
Bugfix/response from cache
2 parents a29cf45 + 5a226d0 commit 7b58f88

File tree

14 files changed

+213
-63
lines changed

14 files changed

+213
-63
lines changed

.github/workflows/pull-request.yml

-3
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
jobs:

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ build/
33
*.iml
44
*.ipr
55
*.iws
6-
.idea/
6+
**/.idea/
77
target/
88
/out/
99
.classpath
1010
.project
1111
.settings
1212
bin
1313
.DS_Store
14+
/**/out/

examples/osgi/apache-karaf-feature/pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
</configuration>
1515
<extensions>true</extensions>
1616
<groupId>org.apache.karaf.tooling</groupId>
17-
<version>4.0.8</version>
17+
<version>4.2.10</version>
1818
</plugin>
1919

2020
<plugin>
@@ -108,7 +108,7 @@
108108
<parent>
109109
<artifactId>graphql-java-servlet-osgi-examples</artifactId>
110110
<groupId>com.graphql-java-kickstart</groupId>
111-
<version>7.3.4-SNAPSHOT</version>
111+
<version>10.1.0</version>
112112
</parent>
113113

114114
<properties>

examples/osgi/apache-karaf-feature/src/main/feature/feature.xml

+1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
name="graphql-java-servlet-osgi-examples-karaf-feature">
66
<feature dependency="false" prerequisite="true">scr</feature>
77
<feature dependency="false" prerequisite="true">war</feature>
8+
<feature dependency="false" prerequisite="true">http</feature>
89
</feature>
910
</features>

examples/osgi/apache-karaf-package/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,6 @@
110110
<parent>
111111
<artifactId>graphql-java-servlet-osgi-examples</artifactId>
112112
<groupId>com.graphql-java-kickstart</groupId>
113-
<version>7.3.4-SNAPSHOT</version>
113+
<version>10.1.0</version>
114114
</parent>
115115
</project>

examples/osgi/buildAndRun.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env bash
22
mvn clean install
3-
pushd apache-karaf-package/target
4-
tar zxvf graphql-java-servlet-osgi-examples-apache-karaf-package-7.3.4-SNAPSHOT.tar.gz
5-
cd graphql-java-servlet-osgi-examples-apache-karaf-package-7.3.4-SNAPSHOT/bin
3+
pushd apache-karaf-package/target || exit 1
4+
tar zxvf graphql-java-servlet-osgi-examples-apache-karaf-package-10.1.0.tar.gz
5+
cd graphql-java-servlet-osgi-examples-apache-karaf-package-10.1.0/bin || exit 1
66
./karaf debug
7-
popd
7+
popd || exit 1

examples/osgi/pom.xml

+6-4
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
<packaging>pom</packaging>
1515

1616
<properties>
17-
<graphql.java.servlet.version>7.3.4-SNAPSHOT</graphql.java.servlet.version>
18-
<graphql.java.version>11.0</graphql.java.version>
19-
<karaf.version>4.2.4</karaf.version>
17+
<graphql.java.servlet.version>11.0.0-SNAPSHOT</graphql.java.servlet.version>
18+
<graphql.java.version>16.1</graphql.java.version>
19+
<karaf.version>4.2.10</karaf.version>
20+
<maven.compiler.source>1.8</maven.compiler.source>
21+
<maven.compiler.target>1.8</maven.compiler.target>
2022
</properties>
2123

22-
<version>7.3.4-SNAPSHOT</version>
24+
<version>10.1.0</version>
2325

2426
</project>

examples/osgi/providers/pom.xml

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
<plugin>
99
<artifactId>maven-bundle-plugin</artifactId>
1010
<configuration>
11-
<instructions>
12-
</instructions>
1311
</configuration>
1412
<extensions>true</extensions>
1513
<groupId>org.apache.felix</groupId>
@@ -51,7 +49,7 @@
5149
<parent>
5250
<artifactId>graphql-java-servlet-osgi-examples</artifactId>
5351
<groupId>com.graphql-java-kickstart</groupId>
54-
<version>7.3.4-SNAPSHOT</version>
52+
<version>10.1.0</version>
5553
</parent>
5654

5755
</project>

examples/osgi/providers/src/main/java/graphql/servlet/examples/osgi/ExampleGraphQLProvider.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
package graphql.kickstart.servlet.examples.osgi;
1+
package graphql.servlet.examples.osgi;
22

33
import graphql.schema.GraphQLFieldDefinition;
44
import graphql.schema.GraphQLType;
5-
import graphql.servlet.GraphQLMutationProvider;
6-
import graphql.servlet.GraphQLQueryProvider;
7-
import graphql.servlet.GraphQLTypesProvider;
5+
import graphql.kickstart.servlet.osgi.GraphQLMutationProvider;
6+
import graphql.kickstart.servlet.osgi.GraphQLQueryProvider;
7+
import graphql.kickstart.servlet.osgi.GraphQLTypesProvider;
88
import org.osgi.service.component.annotations.Component;
99

1010
import java.util.ArrayList;
@@ -38,8 +38,6 @@ public Collection<GraphQLFieldDefinition> getMutations() {
3838
}
3939

4040
public Collection<GraphQLType> getTypes() {
41-
42-
List<GraphQLType> types = new ArrayList<GraphQLType>();
43-
return types;
41+
return new ArrayList<GraphQLType>();
4442
}
4543
}

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

+7-12
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,7 @@ protected void updateSchema() {
131131
updateFuture.cancel(true);
132132
}
133133

134-
updateFuture = executor.schedule(new Runnable() {
135-
@Override
136-
public void run() {
137-
doUpdateSchema();
138-
}
139-
}, schemaUpdateDelay, TimeUnit.MILLISECONDS);
134+
updateFuture = executor.schedule(this::doUpdateSchema, schemaUpdateDelay, TimeUnit.MILLISECONDS);
140135
}
141136
}
142137

@@ -147,17 +142,17 @@ private void doUpdateSchema() {
147142
if (!queryProviders.isEmpty()) {
148143
for (GraphQLQueryProvider provider : queryProviders) {
149144
if (provider.getQueries() != null && !provider.getQueries().isEmpty()) {
150-
provider.getQueries().forEach(queryTypeBuilder::field);
145+
provider.getQueries().forEach(queryTypeBuilder::field);
151146
}
152147
}
153148
} else {
154149
// graphql-java enforces Query type to be there with at least some field.
155150
queryTypeBuilder.field(
156-
GraphQLFieldDefinition
157-
.newFieldDefinition()
158-
.name("_empty")
159-
.type(Scalars.GraphQLBoolean)
160-
.build());
151+
GraphQLFieldDefinition
152+
.newFieldDefinition()
153+
.name("_empty")
154+
.type(Scalars.GraphQLBoolean)
155+
.build());
161156
}
162157

163158
final Set<GraphQLType> types = new HashSet<>();

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/cache/CacheReader.java

+8-13
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99
import lombok.extern.slf4j.Slf4j;
1010

1111
@Slf4j
12-
public final class CacheReader {
13-
14-
private CacheReader() {
15-
}
12+
public class CacheReader {
1613

1714
/**
1815
* Response from cache if possible, if nothing in cache will not produce any response
@@ -21,26 +18,24 @@ private CacheReader() {
2118
* found or an error occurred while reading value from cache
2219
* @throws IOException if can not read value from the cache
2320
*/
24-
public static boolean responseFromCache(GraphQLInvocationInput invocationInput,
21+
public boolean responseFromCache(GraphQLInvocationInput invocationInput,
2522
HttpServletRequest request,
2623
HttpServletResponse response,
2724
GraphQLResponseCacheManager cacheManager) throws IOException {
28-
CachedResponse cachedResponse = null;
2925
try {
30-
cachedResponse = cacheManager.get(request, invocationInput);
26+
CachedResponse cachedResponse = cacheManager.get(request, invocationInput);
27+
if (cachedResponse != null) {
28+
write(response, cachedResponse);
29+
return true;
30+
}
3131
} catch (Exception t) {
3232
log.warn("Ignore read from cache, unexpected error happened", t);
3333
}
3434

35-
if (cachedResponse != null) {
36-
write(response, cachedResponse);
37-
return true;
38-
}
39-
4035
return false;
4136
}
4237

43-
private static void write(HttpServletResponse response, CachedResponse cachedResponse)
38+
private void write(HttpServletResponse response, CachedResponse cachedResponse)
4439
throws IOException {
4540
if (cachedResponse.isError()) {
4641
response.sendError(cachedResponse.getErrorStatusCode(), cachedResponse.getErrorMessage());

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/cache/CachingHttpRequestInvoker.java

+13-13
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,38 @@
99
import java.io.IOException;
1010
import javax.servlet.http.HttpServletRequest;
1111
import javax.servlet.http.HttpServletResponse;
12+
import lombok.AccessLevel;
13+
import lombok.RequiredArgsConstructor;
1214
import lombok.extern.slf4j.Slf4j;
1315

1416
@Slf4j
17+
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
1518
public class CachingHttpRequestInvoker implements HttpRequestInvoker {
1619

1720
private final GraphQLConfiguration configuration;
1821
private final HttpRequestInvoker requestInvoker;
22+
private final CacheReader cacheReader;
1923

2024
public CachingHttpRequestInvoker(GraphQLConfiguration configuration) {
21-
this.configuration = configuration;
22-
requestInvoker = new HttpRequestInvokerImpl(configuration, configuration.getGraphQLInvoker(),
23-
new CachingQueryResponseWriterFactory());
25+
this(configuration, new HttpRequestInvokerImpl(configuration, configuration.getGraphQLInvoker(),
26+
new CachingQueryResponseWriterFactory()), new CacheReader());
2427
}
2528

29+
/**
30+
* Try to return value from cache if cache exists, otherwise process the query normally
31+
*/
2632
@Override
2733
public void execute(GraphQLInvocationInput invocationInput, HttpServletRequest request,
2834
HttpServletResponse response) {
29-
// try to return value from cache if cache exists, otherwise processed the query
30-
boolean returnedFromCache;
31-
3235
try {
33-
returnedFromCache = !CacheReader.responseFromCache(
36+
if (!cacheReader.responseFromCache(
3437
invocationInput, request, response, configuration.getResponseCacheManager()
35-
);
38+
)) {
39+
requestInvoker.execute(invocationInput, request, response);
40+
}
3641
} catch (IOException e) {
3742
response.setStatus(STATUS_BAD_REQUEST);
3843
log.warn("Unexpected error happened during response from cache", e);
39-
return;
40-
}
41-
42-
if (!returnedFromCache) {
43-
requestInvoker.execute(invocationInput, request, response);
4444
}
4545
}
4646

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package graphql.kickstart.servlet.cache
2+
3+
import graphql.kickstart.execution.input.GraphQLInvocationInput
4+
import spock.lang.Specification
5+
6+
import javax.servlet.ServletOutputStream
7+
import javax.servlet.http.HttpServletRequest
8+
import javax.servlet.http.HttpServletResponse
9+
10+
class CacheReaderTest extends Specification {
11+
12+
def cacheManager
13+
def invocationInput
14+
def request
15+
def response
16+
def cacheReader
17+
def cachedResponse
18+
19+
def setup() {
20+
cacheManager = Mock(GraphQLResponseCacheManager)
21+
invocationInput = Mock(GraphQLInvocationInput)
22+
request = Mock(HttpServletRequest)
23+
response = Mock(HttpServletResponse)
24+
cacheReader = new CacheReader()
25+
cachedResponse = Mock(CachedResponse)
26+
}
27+
28+
def "should return false if no cached response"() {
29+
given:
30+
cacheManager.get(request, invocationInput) >> null
31+
32+
when:
33+
def result = cacheReader.responseFromCache(invocationInput, request, response, cacheManager)
34+
35+
then:
36+
!result
37+
}
38+
39+
def "should send error response if cached response is error"() {
40+
given:
41+
cachedResponse.isError() >> true
42+
cachedResponse.getErrorStatusCode() >> 10
43+
cachedResponse.getErrorMessage() >> "some error"
44+
cacheManager.get(request, invocationInput) >> cachedResponse
45+
46+
when:
47+
def result = cacheReader.responseFromCache(invocationInput, request, response, cacheManager)
48+
49+
then:
50+
result
51+
1 * response.sendError(10, "some error")
52+
}
53+
54+
def "should send success response if cached response is ok"() {
55+
given:
56+
def outputStream = Mock(ServletOutputStream)
57+
cachedResponse.isError() >> false
58+
cachedResponse.getContentBytes() >> [ 00, 01, 02 ]
59+
response.getOutputStream() >> outputStream
60+
cacheManager.get(request, invocationInput) >> cachedResponse
61+
62+
when:
63+
def result = cacheReader.responseFromCache(invocationInput, request, response, cacheManager)
64+
65+
then:
66+
result
67+
1 * response.setContentType("application/json;charset=UTF-8")
68+
1 * response.setStatus(200)
69+
1 * response.setCharacterEncoding("UTF-8")
70+
1 * response.setContentLength(3)
71+
1 * outputStream.write([ 00, 01, 02 ])
72+
}
73+
74+
def "should return false if exception is thrown"() {
75+
given:
76+
cacheManager.get(request, invocationInput) >> {throw new RuntimeException()}
77+
78+
when:
79+
def result = cacheReader.responseFromCache(invocationInput, request, response, cacheManager)
80+
81+
then:
82+
!result
83+
}
84+
}

0 commit comments

Comments
 (0)