You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2020/03/30 16:27:00 UTC

[sling-whiteboard] branch master updated: Use default DataFetcher for Resource + output JSON

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

bdelacretaz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new ba3eed0  Use default DataFetcher for Resource + output JSON
ba3eed0 is described below

commit ba3eed0c2b353497b9fff730623fdd5362b9718b
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Mon Mar 30 18:26:42 2020 +0200

    Use default DataFetcher for Resource + output JSON
---
 graphql-scripting/pom.xml                              | 10 +++++++++-
 .../scripting/gql/internal/GraphQLResourceQuery.java   |  7 ++-----
 .../scripting/gql/internal/GraphQLScriptEngine.java    | 18 ++++++++++++++----
 .../gql/internal/GraphQLResourceQueryTest.java         |  7 +++++--
 .../sling/scripting/graphql/it/BasicContentIT.java     | 11 +++++------
 .../graphql/it/GraphQLScriptingTestSupport.java        |  3 +--
 .../initial-content/apps/graphql/test/one/json.gql     |  2 +-
 7 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/graphql-scripting/pom.xml b/graphql-scripting/pom.xml
index c6ef7cb..2040804 100644
--- a/graphql-scripting/pom.xml
+++ b/graphql-scripting/pom.xml
@@ -37,7 +37,9 @@
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <sling.java.version>8</sling.java.version>
+
+    <!-- GSON requires Java 11 - we might use something else later -->
+    <sling.java.version>11</sling.java.version>
     <org.ops4j.pax.exam.version>4.13.1</org.ops4j.pax.exam.version>
 
     <!-- To debug the pax process, override this with -D -->
@@ -165,6 +167,12 @@
       <scope>provided</scope>
     </dependency>
     <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>2.8.6</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>javax.servlet-api</artifactId>
       <scope>test</scope>
diff --git a/graphql-scripting/src/main/java/org/apache/sling/scripting/gql/internal/GraphQLResourceQuery.java b/graphql-scripting/src/main/java/org/apache/sling/scripting/gql/internal/GraphQLResourceQuery.java
index 37217c3..4e49101 100644
--- a/graphql-scripting/src/main/java/org/apache/sling/scripting/gql/internal/GraphQLResourceQuery.java
+++ b/graphql-scripting/src/main/java/org/apache/sling/scripting/gql/internal/GraphQLResourceQuery.java
@@ -53,7 +53,7 @@ class GraphQLResourceQuery {
     ExecutionResult executeQuery(Resource r, String query) {
         final String schemaDef = 
             "type Query { currentResource : SlingResource }\n"
-            + "type SlingResource { path: String }\n"
+            + "type SlingResource { path: String resourceType: String }\n"
         ;
 
         final GraphQLSchema schema = buildSchema(schemaDef, r);
@@ -70,11 +70,8 @@ class GraphQLResourceQuery {
     }
 
     private RuntimeWiring buildWiring(Resource r) {
-        // TODO data should pass via the DataFetchingEnvironment...
-        final String path = r == null ? "NO_PATH" : r.getPath();
         return RuntimeWiring.newRuntimeWiring()
-            .type(TypeRuntimeWiring.newTypeWiring("Query").dataFetcher("currentResource", new EchoDataFetcher("DummyCurrentResourceResult")).build())
-            .type(TypeRuntimeWiring.newTypeWiring("SlingResource").dataFetcher("path", new EchoDataFetcher(path)).build())
+            .type(TypeRuntimeWiring.newTypeWiring("Query").dataFetcher("currentResource", new EchoDataFetcher(r)).build())
             .build()
         ;
     }
diff --git a/graphql-scripting/src/main/java/org/apache/sling/scripting/gql/internal/GraphQLScriptEngine.java b/graphql-scripting/src/main/java/org/apache/sling/scripting/gql/internal/GraphQLScriptEngine.java
index 4d4c43b..1aba565 100644
--- a/graphql-scripting/src/main/java/org/apache/sling/scripting/gql/internal/GraphQLScriptEngine.java
+++ b/graphql-scripting/src/main/java/org/apache/sling/scripting/gql/internal/GraphQLScriptEngine.java
@@ -21,6 +21,7 @@
 package org.apache.sling.scripting.gql.internal;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.Reader;
 import java.io.StringReader;
 
@@ -30,6 +31,9 @@ import javax.script.ScriptContext;
 import javax.script.ScriptEngineFactory;
 import javax.script.ScriptException;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.scripting.SlingBindings;
@@ -39,6 +43,10 @@ import graphql.ExecutionResult;
 public class GraphQLScriptEngine extends AbstractScriptEngine {
 
     private final GraphQLScriptEngineFactory factory;
+    public static final int JSON_INDENT_SPACES = 2;
+
+    // As per GraphQL spec, nulls must be present in the JSON output
+    private static final Gson GSON = new GsonBuilder().serializeNulls().create();
 
     public GraphQLScriptEngine(GraphQLScriptEngineFactory factory) {
         this.factory = factory;
@@ -54,16 +62,18 @@ public class GraphQLScriptEngine extends AbstractScriptEngine {
         try {
             final GraphQLResourceQuery q = new GraphQLResourceQuery();
 
-            final Resource resource = (Resource) context.getBindings(ScriptContext.ENGINE_SCOPE).get(SlingBindings.RESOURCE);
+            final Resource resource = (Resource) context.getBindings(ScriptContext.ENGINE_SCOPE)
+                    .get(SlingBindings.RESOURCE);
             final ExecutionResult result = q.executeQuery(resource, IOUtils.toString(reader));
-            if(!result.getErrors().isEmpty()) {
+            if (!result.getErrors().isEmpty()) {
                 throw new ScriptException(("GraphQL query failed:" + result.getErrors()));
             }
             final Object data = result.getData();
-            if(data == null) {
+            if (data == null) {
                 throw new ScriptException("No data");
             }
-            IOUtils.copy(new StringReader(data.toString()), context.getWriter());
+            final PrintWriter out = (PrintWriter) context.getBindings(ScriptContext.ENGINE_SCOPE).get(SlingBindings.OUT);
+            GSON.toJson(data, out);
         } catch(IOException e) {
             throw new ScriptException(e);
         }
diff --git a/graphql-scripting/src/test/java/org/apache/sling/scripting/gql/internal/GraphQLResourceQueryTest.java b/graphql-scripting/src/test/java/org/apache/sling/scripting/gql/internal/GraphQLResourceQueryTest.java
index 9218b37..37944ba 100644
--- a/graphql-scripting/src/test/java/org/apache/sling/scripting/gql/internal/GraphQLResourceQueryTest.java
+++ b/graphql-scripting/src/test/java/org/apache/sling/scripting/gql/internal/GraphQLResourceQueryTest.java
@@ -32,17 +32,20 @@ import graphql.ExecutionResult;
 public class GraphQLResourceQueryTest {
    @Test
     public void basicTest() throws Exception {
+        final String resourceType = "RT-" + UUID.randomUUID();
         final String path = "/some/path/" + UUID.randomUUID();
         final Resource r = Mockito.mock(Resource.class);
         Mockito.when(r.getPath()).thenReturn(path);
+        Mockito.when(r.getResourceType()).thenReturn(resourceType);
 
         final GraphQLResourceQuery q = new GraphQLResourceQuery();
-        final ExecutionResult result = q.executeQuery(r, "{ currentResource { path } }");
+        final ExecutionResult result = q.executeQuery(r, "{ currentResource { path resourceType } }");
 
         if(!result.getErrors().isEmpty()) {
             fail("Errors:" + result.getErrors());
         }
-        final String expected = "{currentResource={path=" + path + "}}";
+        // TODO brittle test...
+        final String expected = "{currentResource={path=" + path + ", resourceType=" + resourceType + "}}";
         assertEquals(expected, result.getData().toString());
     }
 }
diff --git a/graphql-scripting/src/test/java/org/apache/sling/scripting/graphql/it/BasicContentIT.java b/graphql-scripting/src/test/java/org/apache/sling/scripting/graphql/it/BasicContentIT.java
index 750dd67..fd7777c 100644
--- a/graphql-scripting/src/test/java/org/apache/sling/scripting/graphql/it/BasicContentIT.java
+++ b/graphql-scripting/src/test/java/org/apache/sling/scripting/graphql/it/BasicContentIT.java
@@ -31,7 +31,6 @@ import org.ops4j.pax.exam.spi.reactors.PerClass;
 import org.ops4j.pax.exam.util.Filter;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;
 
 @RunWith(PaxExam.class)
@@ -54,10 +53,10 @@ public class BasicContentIT extends GraphQLScriptingTestSupport {
 
     @Test
     public void testJsonContent() throws Exception {
-        final String expected = "{currentResource={path=/content/graphql/one}}";
-        final String actual = getContent("/graphql/one.json");
-        assertNotNull(actual);
-        assertEquals(expected, actual.trim());
+        final String path = "/graphql/one";
+        final String json = getContent(path + ".json");
+        // TODO we should really parse this..or run detailed tests in unit tests, and just the basics here
+        final String expected = "{\"currentResource\":{\"path\":\"/content/graphql/one\",\"resourceType\":\"graphql/test/one\"}}";
+        assertEquals(expected, json);
     }
-
 }
diff --git a/graphql-scripting/src/test/java/org/apache/sling/scripting/graphql/it/GraphQLScriptingTestSupport.java b/graphql-scripting/src/test/java/org/apache/sling/scripting/graphql/it/GraphQLScriptingTestSupport.java
index 6f22cc9..322dffa 100644
--- a/graphql-scripting/src/test/java/org/apache/sling/scripting/graphql/it/GraphQLScriptingTestSupport.java
+++ b/graphql-scripting/src/test/java/org/apache/sling/scripting/graphql/it/GraphQLScriptingTestSupport.java
@@ -81,6 +81,7 @@ public abstract class GraphQLScriptingTestSupport extends TestSupport {
                 .put("whitelist.bundles.regexp", "^PAXEXAM.*$")
                 .asOption(),
             mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.servlet-helpers").versionAsInProject(),
+            mavenBundle().groupId("com.google.code.gson").artifactId("gson").versionAsInProject(),
             slingResourcePresence(),
             junitBundles()
         );
@@ -157,6 +158,4 @@ public abstract class GraphQLScriptingTestSupport extends TestSupport {
     protected String getContent(String path) throws Exception {
         return executeRequest("GET", path, 200).getOutputAsString();
     }
-
-
 }
diff --git a/graphql-scripting/src/test/resources/initial-content/apps/graphql/test/one/json.gql b/graphql-scripting/src/test/resources/initial-content/apps/graphql/test/one/json.gql
index 16bd6e4..1dde25b 100644
--- a/graphql-scripting/src/test/resources/initial-content/apps/graphql/test/one/json.gql
+++ b/graphql-scripting/src/test/resources/initial-content/apps/graphql/test/one/json.gql
@@ -15,4 +15,4 @@
 # * specific language governing permissions and limitations
 # * under the License.
 
-{ currentResource { path } }
\ No newline at end of file
+{ currentResource { path resourceType } }
\ No newline at end of file