This is an automated email from the ASF dual-hosted git repository.

radu pushed a commit to branch feature/SLING-9655
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-graphql-core.git


The following commit(s) were added to refs/heads/feature/SLING-9655 by this 
push:
     new 1cb7350  SLING-9655 - Caching support for the GraphQL core
1cb7350 is described below

commit 1cb7350b2e0e7f843dd2256f241958057cd48157
Author: Radu Cotescu <[email protected]>
AuthorDate: Fri Aug 21 20:29:13 2020 +0200

    SLING-9655 - Caching support for the GraphQL core
    
    * added basic support for the Cache-Control header
    for persisted queries
---
 .../sling/graphql/core/servlet/GraphQLServlet.java | 30 ++++++++++++++++++++--
 .../graphql/core/it/GraphQLCoreTestSupport.java    | 17 +++++++++---
 .../sling/graphql/core/it/GraphQLServletIT.java    | 25 +++++++++++++++---
 3 files changed, 63 insertions(+), 9 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java 
b/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
index 25f7928..a54b0e4 100644
--- a/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
+++ b/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
@@ -41,6 +41,7 @@ import org.apache.sling.graphql.core.json.JsonSerializer;
 import org.apache.sling.graphql.core.scalars.SlingScalarsProvider;
 import org.apache.sling.graphql.core.schema.RankedSchemaProviders;
 import org.jetbrains.annotations.NotNull;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.ConfigurationPolicy;
 import org.osgi.service.component.annotations.Reference;
@@ -48,6 +49,7 @@ import 
org.osgi.service.component.annotations.ReferenceCardinality;
 import org.osgi.service.component.annotations.ReferencePolicy;
 import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.AttributeType;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 
@@ -104,6 +106,15 @@ public class GraphQLServlet extends SlingAllMethodsServlet 
{
             name = "Extensions",
             description="Standard Sling servlet property")
         String[] sling_servlet_extensions() default "gql";
+
+        @AttributeDefinition(
+                name = "Persisted Queries Cache-Control max-age",
+                description = "The maximum amount of time a persisted query 
resource is considered fresh (in seconds). A negative value " +
+                        "will be interpreted as 0.",
+                min = "0",
+                type = AttributeType.INTEGER
+        )
+        int cache$_$control_max$_$age() default 60;
     }
 
     @Reference
@@ -122,8 +133,17 @@ public class GraphQLServlet extends SlingAllMethodsServlet 
{
     )
     private GraphQLCacheProvider cacheProvider;
 
+    private final Config config;
+    private final int cacheControlMaxAge;
+
     private final JsonSerializer jsonSerializer = new JsonSerializer();
 
+    @Activate
+    public GraphQLServlet(Config config) {
+        this.config = config;
+        cacheControlMaxAge = config.cache$_$control_max$_$age() >= 0 ? 
config.cache$_$control_max$_$age() : 0;
+    }
+
     @Override
     public void doGet(SlingHttpServletRequest request, 
SlingHttpServletResponse response) throws IOException {
         String suffix = request.getRequestPathInfo().getSuffix();
@@ -139,6 +159,12 @@ public class GraphQLServlet extends SlingAllMethodsServlet 
{
                     String query = cacheProvider.getQuery(queryHash, 
request.getResource().getResourceType(),
                             request.getRequestPathInfo().getSelectorString());
                     if (query != null) {
+                        boolean isAuthenticated = 
request.getHeaders("Authorization").hasMoreElements();
+                        StringBuilder cacheControlValue = new 
StringBuilder("max-age=").append(cacheControlMaxAge);
+                        if (isAuthenticated) {
+                            cacheControlValue.append(",private");
+                        }
+                        response.addHeader("Cache-Control", 
cacheControlValue.toString());
                         execute(query, request, response);
                     } else {
                         response.sendError(HttpServletResponse.SC_NOT_FOUND, 
"Cannot find persisted query " + queryHash);
@@ -160,7 +186,7 @@ public class GraphQLServlet extends SlingAllMethodsServlet {
                 
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "This servlet 
does not support persisted queries.");
                 return;
             }
-            String query = IOUtils.toString(request.getInputStream(), 
StandardCharsets.UTF_8);
+            String query = IOUtils.toString(request.getReader());
             String hash = cacheProvider.cacheQuery(query, 
request.getResource().getResourceType(),
                     request.getRequestPathInfo().getSelectorString());
             response.addHeader("Location", getLocationHeaderValue(request, 
hash));
@@ -213,7 +239,7 @@ public class GraphQLServlet extends SlingAllMethodsServlet {
         StringBuilder location = new StringBuilder();
         location.append(request.getScheme()).append("://");
         location.append(request.getServerName());
-        int localPort = request.getLocalPort();
+        int localPort = request.getServerPort();
         if (localPort != 80 && localPort != 443) {
             location.append(":").append(localPort);
         }
diff --git 
a/src/test/java/org/apache/sling/graphql/core/it/GraphQLCoreTestSupport.java 
b/src/test/java/org/apache/sling/graphql/core/it/GraphQLCoreTestSupport.java
index 49a6f87..604f218 100644
--- a/src/test/java/org/apache/sling/graphql/core/it/GraphQLCoreTestSupport.java
+++ b/src/test/java/org/apache/sling/graphql/core/it/GraphQLCoreTestSupport.java
@@ -49,9 +49,7 @@ import static 
org.apache.sling.testing.paxexam.SlingOptions.slingScriptingJsp;
 import static org.ops4j.pax.exam.CoreOptions.composite;
 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.vmOptions;
 import static org.ops4j.pax.exam.CoreOptions.when;
-import static org.ops4j.pax.exam.CoreOptions.vmOption;
 import static org.ops4j.pax.exam.CoreOptions.streamBundle;
 import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.newConfiguration;
 
@@ -70,7 +68,7 @@ public abstract class GraphQLCoreTestSupport extends 
TestSupport {
     private final static int STARTUP_WAIT_SECONDS = 30;
 
     @Inject
-    private ResourceResolverFactory resourceResolverFactory;
+    protected ResourceResolverFactory resourceResolverFactory;
 
     @Inject
     protected SlingRequestProcessor requestProcessor;
@@ -211,6 +209,19 @@ public abstract class GraphQLCoreTestSupport extends 
TestSupport {
         return executeRequest("POST", path, null, "application/json", new 
StringReader(toJSON(body)), 200).getOutputAsString();
     }
 
+    protected MockSlingHttpServletResponse persistQuery(String path, String 
query, Map<String, Object> variables) throws Exception {
+        Map<String, Object> body = new HashMap<>();
+        if (query != null) {
+            String queryEncoded = query.replace("\n", "\\n");
+            body.put("query", queryEncoded);
+        }
+        if (variables != null) {
+            body.put("variables", variables);
+        }
+
+        return executeRequest("POST", path + "/persisted", null, 
"application/json", new StringReader(toJSON(body)), 201);
+    }
+
     protected String toJSON(Object source) {
         return JsonWriter.objectToJson(source, JsonSerializer.WRITER_OPTIONS);
     }
diff --git 
a/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java 
b/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
index 31cfced..9f2d45e 100644
--- a/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
+++ b/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
@@ -18,14 +18,15 @@
  */
 package org.apache.sling.graphql.core.it;
 
-import javax.inject.Inject;
+import java.io.StringReader;
 
-import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
-import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
+import javax.inject.Inject;
 
 import org.apache.sling.graphql.api.SchemaProvider;
 import org.apache.sling.graphql.core.mocks.ReplacingSchemaProvider;
 import org.apache.sling.resource.presence.ResourcePresence;
+import org.apache.sling.servlethelpers.MockSlingHttpServletResponse;
+import org.apache.sling.servlethelpers.internalrequests.SlingInternalRequest;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.Configuration;
@@ -36,8 +37,11 @@ import org.ops4j.pax.exam.spi.reactors.PerClass;
 import org.ops4j.pax.exam.util.Filter;
 import org.osgi.framework.BundleContext;
 
-import static org.junit.Assert.assertThat;
+import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
+import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
 import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
 import static 
org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;
 
 @RunWith(PaxExam.class)
@@ -96,6 +100,19 @@ public class GraphQLServletIT extends 
GraphQLCoreTestSupport {
     }
 
     @Test
+    public void testPersistedQueries() throws Exception {
+        String queryHash = 
"a16982712f6ecdeba5d950d42e3c13df0fc26d008c497f6bf012701b57e02a51";
+        MockSlingHttpServletResponse response = 
persistQuery("/graphql/two.gql", "{ currentResource { resourceType name } }", 
null);
+        assertEquals("http://localhost/graphql/two.gql/persisted/"; + 
queryHash, response.getHeader("Location"));
+
+        response = executeRequest("GET", "/graphql/two.gql/persisted/" + 
queryHash, null, "application/json", new StringReader(""),200);
+        assertEquals("max-age=60", response.getHeader("Cache-Control"));
+
+        // need another test for a request with an Authorization header
+    }
+
+
+    @Test
     public void testOtherExtAndTestingSelector() throws Exception {
         executeRequest("GET", "/graphql/two.otherExt", null, null, null, 404);
         final String json = getContent("/graphql/two.testing.otherExt", 
"query", "{ withTestingSelector { farenheit } }");

Reply via email to