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 ed77ae5  SLING-9655 - Caching support for the GraphQL core
ed77ae5 is described below

commit ed77ae5f8289bd3e705c81fc3748e21634540f82
Author: Radu Cotescu <[email protected]>
AuthorDate: Tue Aug 18 17:15:59 2020 +0200

    SLING-9655 - Caching support for the GraphQL core
    
    * started implementing support for persisted queries based on jcache
    (WIP)
---
 pom.xml                                            |  72 +++++++++----
 .../graphql/core/cache/GraphQLCacheProvider.java   | 116 +++++++++++++++++++++
 .../sling/graphql/core/servlet/GraphQLServlet.java |  95 +++++++++++++++--
 .../sling/graphql/core/servlet/QueryParser.java    | 108 +++++++++++++++++++
 .../sling/graphql/core/servlet/RequestParser.java  |  77 --------------
 .../core/cache/GraphQLCacheProviderTest.java       |  32 ++++++
 .../graphql/core/it/GraphQLCoreTestSupport.java    |  17 ++-
 7 files changed, 404 insertions(+), 113 deletions(-)

diff --git a/pom.xml b/pom.xml
index 3c4c165..291c558 100644
--- a/pom.xml
+++ b/pom.xml
@@ -101,28 +101,35 @@
 
   <dependencies>
     <dependency>
-      <groupId>javax.inject</groupId>
-      <artifactId>javax.inject</artifactId>
-      <scope>test</scope>
+      <groupId>org.osgi</groupId>
+      <artifactId>osgi.core</artifactId>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
-      <artifactId>osgi.cmpn</artifactId>
-      <scope>test</scope>
+      <artifactId>org.osgi.service.component.annotations</artifactId>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
-      <artifactId>osgi.core</artifactId>
+      <artifactId>org.osgi.service.metatype.annotations</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.service.component.annotations</artifactId>
+      <artifactId>org.osgi.annotation.versioning</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.service.metatype.annotations</artifactId>
+      <groupId>javax.cache</groupId>
+      <artifactId>cache-api</artifactId>
+      <version>1.1.1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <version>3.9</version>
       <scope>provided</scope>
     </dependency>
     <dependency>
@@ -208,6 +215,13 @@
       <scope>provided</scope>
     </dependency>
     <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.servlet-helpers</artifactId>
+      <version>1.4.2</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
@@ -225,10 +239,14 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.sling</groupId>
-      <artifactId>org.apache.sling.servlet-helpers</artifactId>
-      <version>1.4.2</version>
-      <scope>provided</scope>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>osgi.cmpn</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.ops4j.pax.exam</groupId>
@@ -261,16 +279,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>biz.aQute.bnd</groupId>
-      <artifactId>biz.aQute.bndlib</artifactId>
-      <version>5.0.0</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.annotation.versioning</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.ops4j.pax.url</groupId>
       <artifactId>pax-url-wrap</artifactId>
       <version>2.3.0</version>
@@ -294,6 +302,24 @@
       <version>1.3_1</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.github.ben-manes.caffeine</groupId>
+      <artifactId>caffeine</artifactId>
+      <version>2.8.6-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.ben-manes.caffeine</groupId>
+      <artifactId>jcache</artifactId>
+      <version>2.8.6-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.typesafe</groupId>
+      <artifactId>config</artifactId>
+      <version>1.4.0</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <reporting>
diff --git 
a/src/main/java/org/apache/sling/graphql/core/cache/GraphQLCacheProvider.java 
b/src/main/java/org/apache/sling/graphql/core/cache/GraphQLCacheProvider.java
new file mode 100644
index 0000000..20afddf
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/graphql/core/cache/GraphQLCacheProvider.java
@@ -0,0 +1,116 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License.  You may obtain a copy of the License at
+ ~
+ ~   http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied.  See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.graphql.core.cache;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Hashtable;
+
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.spi.CachingProvider;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(
+        immediate = true
+)
+public class GraphQLCacheProvider {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(GraphQLCacheProvider.class);
+
+    @Reference
+    private CachingProvider cachingProvider;
+
+    private Cache<String, String> persistedQueriesCache;
+
+    private ServiceRegistration<GraphQLCacheProvider> registration;
+
+    @Nullable
+    public String getQuery(@NotNull String hash, @NotNull String resourceType, 
@Nullable String selectorString) {
+        return persistedQueriesCache.get(getCacheKey(hash, resourceType, 
selectorString));
+    }
+
+    public void cacheQuery(@NotNull String query, @NotNull String 
resourceType, @Nullable String selectorString) {
+        String key = getCacheKey("123", resourceType, selectorString);
+        persistedQueriesCache.put(key, query);
+    }
+
+
+    @Activate
+    public void activate(BundleContext bundleContext) {
+        if (cachingProvider != null) {
+            try {
+                CacheManager cacheManager = cachingProvider.getCacheManager();
+                persistedQueriesCache = cacheManager
+                        
.createCache(bundleContext.getBundle().getSymbolicName() + "_persistedQueries", 
new MutableConfiguration<>());
+                registration = 
bundleContext.registerService(GraphQLCacheProvider.class, this, new 
Hashtable<>());
+            } catch (Exception e) {
+                LOGGER.error("Unable to configure a cache for persisted 
queries.", e);
+            }
+        } else {
+            LOGGER.error("Cannot activate the " + 
GraphQLCacheProvider.class.getName() + " without a cachingProvider.");
+        }
+    }
+
+    @Deactivate
+    public void deactivate(BundleContext bundleContext) {
+        if (registration != null) {
+            registration.unregister();
+        }
+        cachingProvider.close();
+    }
+
+    @NotNull
+    private String getCacheKey(@NotNull String hash, @NotNull String 
resourceType, @Nullable String selectorString) {
+        StringBuilder key = new StringBuilder(resourceType);
+        if (StringUtils.isNotEmpty(selectorString)) {
+            key.append("_").append(selectorString);
+        }
+        key.append("_").append(hash);
+        return key.toString();
+    }
+
+    @NotNull String getHash(@NotNull String query) throws 
NoSuchAlgorithmException {
+        MessageDigest digest = MessageDigest.getInstance("SHA-256");
+        byte[] hash = digest.digest(query.getBytes(StandardCharsets.UTF_8));
+        StringBuilder buffer = new StringBuilder();
+        for (int i = 0; i < hash.length; i++) {
+            String hex = Integer.toHexString(0xff & hash[i]);
+            if (hex.length() == 1) {
+                buffer.append('0');
+            }
+            buffer.append(hex);
+        }
+        return buffer.toString();
+    }
+
+}
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 cc424b2..0daf0ef 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
@@ -21,22 +21,32 @@
 package org.apache.sling.graphql.core.servlet;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.servlet.Servlet;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.servlets.SlingAllMethodsServlet;
+import org.apache.sling.graphql.core.cache.GraphQLCacheProvider;
 import org.apache.sling.graphql.core.engine.GraphQLResourceQuery;
+import org.apache.sling.graphql.core.engine.SlingDataFetcherSelector;
 import org.apache.sling.graphql.core.json.JsonSerializer;
 import org.apache.sling.graphql.core.scalars.SlingScalarsProvider;
-import org.apache.sling.graphql.core.engine.SlingDataFetcherSelector;
 import org.apache.sling.graphql.core.schema.RankedSchemaProviders;
+import org.jetbrains.annotations.NotNull;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.ConfigurationPolicy;
 import org.osgi.service.component.annotations.Reference;
+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.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -68,6 +78,11 @@ public class GraphQLServlet extends SlingAllMethodsServlet {
 
     public static final String P_QUERY = "query";
 
+    private static final String SUFFIX_PERSISTED = "/persisted";
+    private static final Pattern PATTERN_GET_PERSISTED_QUERY = 
Pattern.compile("^" + SUFFIX_PERSISTED + "/([a-f0-9]{64})$");
+
+    private Config config;
+
     @ObjectClassDefinition(
         name = "Apache Sling GraphQL Servlet",
         description = "Servlet that implements GraphQL endpoints")
@@ -102,34 +117,94 @@ public class GraphQLServlet extends 
SlingAllMethodsServlet {
     @Reference
     private SlingScalarsProvider scalarsProvider;
 
+    @Reference(
+            cardinality = ReferenceCardinality.OPTIONAL,
+            policy = ReferencePolicy.STATIC,
+            policyOption = ReferencePolicyOption.GREEDY
+    )
+    private GraphQLCacheProvider cacheProvider;
+
     private final JsonSerializer jsonSerializer = new JsonSerializer();
 
     @Override
     public void doGet(SlingHttpServletRequest request, 
SlingHttpServletResponse response) throws IOException {
-        execute(request.getResource(), request, response);
+        String suffix = request.getRequestPathInfo().getSuffix();
+        if (suffix != null && suffix.startsWith(SUFFIX_PERSISTED)) {
+            if (cacheProvider == null) {
+                
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "This servlet 
does not support persisted queries.");
+                return;
+            }
+            Matcher matcher = PATTERN_GET_PERSISTED_QUERY.matcher(suffix);
+            if (matcher.matches()) {
+                String queryHash = matcher.group(1);
+                if (StringUtils.isNotEmpty(queryHash)) {
+                    String query = cacheProvider.getQuery(queryHash, 
request.getResource().getResourceType(),
+                            request.getRequestPathInfo().getSelectorString());
+                    if (query != null) {
+                        execute(query, request, response);
+                    } else {
+                        response.sendError(HttpServletResponse.SC_NOT_FOUND, 
"Cannot find persisted query " + queryHash);
+                    }
+                    return;
+                }
+            } else {
+                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+                return;
+            }
+        } else {
+            execute(request.getResource(), request, response);
+        }
     }
 
     @Override
     public void doPost(SlingHttpServletRequest request, 
SlingHttpServletResponse response) throws IOException {
-        execute(request.getResource(), request, response);
+        String suffix = request.getRequestPathInfo().getSuffix();
+        if (suffix != null && suffix.equals(SUFFIX_PERSISTED)) {
+            if (cacheProvider == null) {
+                
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "This servlet 
does not support persisted queries.");
+                return;
+            }
+            String query = IOUtils.toString(request.getInputStream(), 
StandardCharsets.UTF_8);
+            cacheProvider.cacheQuery(query, 
request.getResource().getResourceType(), 
request.getRequestPathInfo().getSelectorString());
+            response.setStatus(HttpServletResponse.SC_CREATED);
+        } else {
+            execute(request.getResource(), request, response);
+        }
     }
 
     private void execute(Resource resource, SlingHttpServletRequest request, 
SlingHttpServletResponse response) throws IOException {
         response.setContentType("application/json");
         response.setCharacterEncoding("UTF-8");
-
-        final RequestParser parser = new RequestParser(request);
-        final String query = parser.getQuery();
-        if (query == null || query.trim().length() == 0) {
+        final QueryParser.Result result = QueryParser.fromRequest(request);
+        if (result == null) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+        final String query = result.getQuery();
+        if (query.trim().length() == 0) {
             response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing 
request parameter:" + P_QUERY);
             return;
         }
 
         try {
             final GraphQLResourceQuery q = new GraphQLResourceQuery();
-            final ExecutionResult result = q.executeQuery(schemaProviders, 
dataFetcherSelector, scalarsProvider,
-                resource, request.getRequestPathInfo().getSelectors(), query, 
parser.getVariables());
-            jsonSerializer.sendJSON(response.getWriter(), result);
+            final ExecutionResult executionResult = 
q.executeQuery(schemaProviders, dataFetcherSelector, scalarsProvider,
+                resource, request.getRequestPathInfo().getSelectors(), query, 
result.getVariables());
+            jsonSerializer.sendJSON(response.getWriter(), executionResult);
+        } catch(Exception ex) {
+            throw new IOException(ex);
+        }
+    }
+
+    private void execute(@NotNull String persistedQuery, 
SlingHttpServletRequest request, SlingHttpServletResponse response) throws 
IOException {
+        response.setContentType("application/json");
+        response.setCharacterEncoding("UTF-8");
+        try {
+            final QueryParser.Result result = 
QueryParser.fromJSON(persistedQuery);
+            final GraphQLResourceQuery q = new GraphQLResourceQuery();
+            final ExecutionResult executionResult = 
q.executeQuery(schemaProviders, dataFetcherSelector, scalarsProvider,
+                    request.getResource(), 
request.getRequestPathInfo().getSelectors(), result.getQuery(), 
result.getVariables());
+            jsonSerializer.sendJSON(response.getWriter(), executionResult);
         } catch(Exception ex) {
             throw new IOException(ex);
         }
diff --git 
a/src/main/java/org/apache/sling/graphql/core/servlet/QueryParser.java 
b/src/main/java/org/apache/sling/graphql/core/servlet/QueryParser.java
new file mode 100644
index 0000000..d6b868e
--- /dev/null
+++ b/src/main/java/org/apache/sling/graphql/core/servlet/QueryParser.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.graphql.core.servlet;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.ReaderInputStream;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.graphql.core.json.JsonSerializer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class QueryParser {
+
+    private QueryParser() {}
+
+    static class Result {
+
+        private final String query;
+        private final Map<String, Object> variables;
+
+        Result(String query, Map<String, Object> variables) {
+            this.query = query;
+            this.variables = variables;
+        }
+
+        @NotNull
+        public String getQuery() {
+            return query;
+        }
+
+        @NotNull
+        public Map<String, Object> getVariables() {
+            return variables;
+        }
+    }
+
+    private static final String MIME_TYPE_JSON = "application/json";
+    private static final JsonSerializer jsonSerializer = new JsonSerializer();
+    private static final String JSON_KEY_QUERY = "query";
+    private static final String JSON_KEY_VARIABLES = "variables";
+
+    @Nullable
+    public static Result fromRequest(@NotNull SlingHttpServletRequest request) 
throws IOException {
+        String query = null;
+        Map<String, Object> variables = null;
+        if (request.getMethod().equalsIgnoreCase("POST") && 
MIME_TYPE_JSON.equals(request.getContentType())) {
+            Map<String, Object> requestJson = getInputJson(request);
+            query = (String) requestJson.get(JSON_KEY_QUERY);
+            if (query != null) {
+                query = query.replace("\\n", "\n");
+            }
+            variables = (Map<String, Object>) 
requestJson.get(JSON_KEY_VARIABLES);
+        }
+
+        if (query == null) {
+            query = request.getParameter(JSON_KEY_QUERY);
+        }
+
+        if (variables == null) {
+            variables = Collections.emptyMap();
+        }
+        if (query != null) {
+            return new Result(query, variables);
+        }
+        return null;
+    }
+
+    public static Result fromJSON(String json) throws IOException {
+        Map<String, Object> jsonMap = 
jsonSerializer.JSONtoMaps(IOUtils.toInputStream(json, StandardCharsets.UTF_8));
+        String query = (String) jsonMap.get(JSON_KEY_QUERY);
+        if (query != null) {
+            Map<String, Object> variables = (Map<String, Object>) 
jsonMap.get(JSON_KEY_VARIABLES);
+            if (variables == null) {
+                variables = Collections.emptyMap();
+            }
+            return new Result(query, variables);
+        }
+        throw new IOException("The provided JSON structure does not contain a 
query.");
+
+    }
+
+    private static Map<String, Object> getInputJson(SlingHttpServletRequest 
req) throws IOException {
+        return jsonSerializer.JSONtoMaps(new 
ReaderInputStream(req.getReader()));
+    }
+
+}
diff --git 
a/src/main/java/org/apache/sling/graphql/core/servlet/RequestParser.java 
b/src/main/java/org/apache/sling/graphql/core/servlet/RequestParser.java
deleted file mode 100644
index 724ceaf..0000000
--- a/src/main/java/org/apache/sling/graphql/core/servlet/RequestParser.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sling.graphql.core.servlet;
-
-import org.apache.commons.io.input.ReaderInputStream;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.graphql.core.json.JsonSerializer;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-
-public class RequestParser {
-
-    private static final String MIME_TYPE_JSON = "application/json";
-
-    private String query;
-
-    private Map<String, Object> variables;
-    private final JsonSerializer jsonSerializer = new JsonSerializer();
-
-    RequestParser(SlingHttpServletRequest request) throws IOException {
-        parse(request);
-    }
-
-    private Map<String, Object> getInputJson(SlingHttpServletRequest req) 
throws IOException {
-        return jsonSerializer.JSONtoMaps(new 
ReaderInputStream(req.getReader()));
-    }
-
-    @SuppressWarnings("unchecked")
-    private void parse(SlingHttpServletRequest request) throws IOException {
-        if (request.getMethod().equalsIgnoreCase("POST")) {
-            if (MIME_TYPE_JSON.equals(request.getContentType())) {
-                Map<String, Object> requestJson = getInputJson(request);
-                query = (String) requestJson.get("query");
-                if (query != null) {
-                    query = query.replace("\\n", "\n");
-                }
-                variables = (Map<String, Object>) requestJson.get("variables");
-            }
-        }
-
-        if (query == null) {
-            query = request.getParameter("query");
-        }
-
-        if (variables == null) {
-            variables = Collections.emptyMap();
-        }
-    }
-
-    public String getQuery() {
-        return query;
-    }
-
-    public Map<String, Object> getVariables() {
-        return variables;
-    }
-
-}
diff --git 
a/src/test/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderTest.java
 
b/src/test/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderTest.java
new file mode 100644
index 0000000..66184b6
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderTest.java
@@ -0,0 +1,32 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License.  You may obtain a copy of the License at
+ ~
+ ~   http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied.  See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.graphql.core.cache;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class GraphQLCacheProviderTest {
+
+    @Test
+    public void getHash() throws Exception {
+        GraphQLCacheProvider provider = new GraphQLCacheProvider();
+        
assertEquals("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
 provider.getHash("hello world"));
+    }
+}
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 078c5c6..49a6f87 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
@@ -23,6 +23,7 @@ import javax.inject.Inject;
 import com.cedarsoftware.util.io.JsonWriter;
 
 import org.apache.commons.io.output.WriterOutputStream;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.graphql.core.json.JsonSerializer;
@@ -35,6 +36,7 @@ import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.ProbeBuilder;
 import org.ops4j.pax.exam.TestProbeBuilder;
 import org.ops4j.pax.exam.options.ModifiableCompositeOption;
+import org.ops4j.pax.exam.options.extra.VMOption;
 import org.ops4j.pax.tinybundles.core.TinyBundle;
 import org.osgi.framework.Constants;
 import org.apache.sling.engine.SlingRequestProcessor;
@@ -47,6 +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;
@@ -74,10 +77,14 @@ public abstract class GraphQLCoreTestSupport extends 
TestSupport {
 
     public ModifiableCompositeOption baseConfiguration() {
         final String vmOpt = System.getProperty("pax.vm.options");
+        VMOption vmOption = null;
+        if (StringUtils.isNotEmpty(vmOpt)) {
+            vmOption = new VMOption(vmOpt);
+        }
 
         return composite(
-            when(vmOpt != null).useOptions(
-                vmOption(vmOpt)
+            when(vmOption != null).useOptions(
+                vmOption
             ),
             super.baseConfiguration(),
             slingQuickstart(),
@@ -89,6 +96,10 @@ public abstract class GraphQLCoreTestSupport extends 
TestSupport {
                 .asOption(),
             
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.servlet-helpers").versionAsInProject(),
             
mavenBundle().groupId("com.cedarsoftware").artifactId("json-io").versionAsInProject(),
+            
mavenBundle().groupId("javax.cache").artifactId("cache-api").versionAsInProject(),
+            
mavenBundle().groupId("com.typesafe").artifactId("config").versionAsInProject(),
+            
mavenBundle().groupId("com.github.ben-manes.caffeine").artifactId("caffeine").versionAsInProject(),
+            
mavenBundle().groupId("com.github.ben-manes.caffeine").artifactId("jcache").versionAsInProject(),
             slingResourcePresence(),
             jsonPath(),
             junitBundles()
@@ -229,4 +240,4 @@ public abstract class GraphQLCoreTestSupport extends 
TestSupport {
         bundle.set(Constants.EXPORT_PACKAGE, exports.toString());
         return streamBundle(bundle.build()).start();
     }
-}
\ No newline at end of file
+}

Reply via email to