You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by sh...@apache.org on 2019/05/13 09:59:43 UTC

[unomi] branch UNOMI-180-CXS-GRAPHQLAPI updated: UNOMI-180 CDP Specification implementation - Implement GET and POST basic support - Add support for schema retrieval - Add extended scalars (some scalars are not implemented yet such as GeoPoint)

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

shuber pushed a commit to branch UNOMI-180-CXS-GRAPHQLAPI
in repository https://gitbox.apache.org/repos/asf/unomi.git


The following commit(s) were added to refs/heads/UNOMI-180-CXS-GRAPHQLAPI by this push:
     new 4885248  UNOMI-180 CDP Specification implementation - Implement GET and POST basic support - Add support for schema retrieval - Add extended scalars (some scalars are not implemented yet such as GeoPoint)
4885248 is described below

commit 488524801546265006a1d22628e732289fc3b429
Author: sergehuber <sh...@jahia.com>
AuthorDate: Mon May 13 11:59:36 2019 +0200

    UNOMI-180 CDP Specification implementation
    - Implement GET and POST basic support
    - Add support for schema retrieval
    - Add extended scalars (some scalars are not implemented yet such as GeoPoint)
---
 graphql/cxs-impl/pom.xml                           |   6 +
 .../unomi/graphql/internal/CDPSDLServletImpl.java  | 146 ++++++++++++++++++++-
 .../src/main/resources/cdp-schema.graphqls         |   6 +-
 graphql/karaf-feature/pom.xml                      |   5 +
 graphql/pom.xml                                    |   1 +
 5 files changed, 155 insertions(+), 9 deletions(-)

diff --git a/graphql/cxs-impl/pom.xml b/graphql/cxs-impl/pom.xml
index 79cd629..e4e093e 100644
--- a/graphql/cxs-impl/pom.xml
+++ b/graphql/cxs-impl/pom.xml
@@ -50,6 +50,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>com.graphql-java</groupId>
+            <artifactId>graphql-java-extended-scalars</artifactId>
+            <version>${graphql.java.extended.scalars.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>osgi.enterprise</artifactId>
             <version>6.0.0</version>
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/internal/CDPSDLServletImpl.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/internal/CDPSDLServletImpl.java
index 8cafa15..df69692 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/internal/CDPSDLServletImpl.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/internal/CDPSDLServletImpl.java
@@ -16,8 +16,17 @@
  */
 package org.apache.unomi.graphql.internal;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
 import com.google.common.base.Charsets;
-import graphql.schema.GraphQLSchema;
+import graphql.ExecutionInput;
+import graphql.ExecutionResult;
+import graphql.GraphQL;
+import graphql.TypeResolutionEnvironment;
+import graphql.introspection.IntrospectionQuery;
+import graphql.scalars.ExtendedScalars;
+import graphql.schema.*;
 import graphql.schema.idl.RuntimeWiring;
 import graphql.schema.idl.SchemaGenerator;
 import graphql.schema.idl.SchemaParser;
@@ -29,9 +38,11 @@ import org.osgi.service.component.annotations.Component;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
 
 @Component(
         service={javax.servlet.http.HttpServlet.class,javax.servlet.Servlet.class},
@@ -40,6 +51,9 @@ import java.io.Reader;
 public class CDPSDLServletImpl extends HttpServlet {
 
     private BundleContext bundleContext;
+    private ObjectMapper objectMapper;
+    private GraphQL graphQL;
+
 
     @Activate
     void activate(BundleContext bundleContext) {
@@ -47,7 +61,77 @@ public class CDPSDLServletImpl extends HttpServlet {
     }
 
     RuntimeWiring buildRuntimeWiring() {
+
+        GraphQLScalarType emptyTypeWorkAroundScalarType = GraphQLScalarType.newScalar()
+                .name("EmptyTypeWorkAround")
+                .description("A marker type to get around the limitation of GraphQL that doesn't allow empty types. It should be always ignored.")
+                .coercing(new Coercing() {
+                    @Override
+                    public Object serialize(Object dataFetcherResult) throws CoercingSerializeException {
+                        return null;
+                    }
+
+                    @Override
+                    public Object parseValue(Object input) throws CoercingParseValueException {
+                        return input;
+                    }
+
+                    @Override
+                    public Object parseLiteral(Object input) throws CoercingParseLiteralException {
+                        return input;
+                    }
+                })
+                .build();
+
+        GraphQLScalarType geopointScalarType = GraphQLScalarType.newScalar()
+                .name("GeoPoint")
+                .description("A type that represents a geographical location")
+                .coercing(new Coercing() {
+                    @Override
+                    public Object serialize(Object dataFetcherResult) throws CoercingSerializeException {
+                        return null;
+                    }
+
+                    @Override
+                    public Object parseValue(Object input) throws CoercingParseValueException {
+                        return input;
+                    }
+
+                    @Override
+                    public Object parseLiteral(Object input) throws CoercingParseLiteralException {
+                        return input;
+                    }
+                })
+                .build();
+
         return RuntimeWiring.newRuntimeWiring()
+                .scalar(ExtendedScalars.DateTime)
+                .scalar(ExtendedScalars.Date)
+                .scalar(ExtendedScalars.Json)
+                .scalar(ExtendedScalars.Time)
+                .scalar(emptyTypeWorkAroundScalarType)
+                .scalar(geopointScalarType)
+                .type("CDP_EventInterface", typeWiring -> typeWiring
+                        .typeResolver(new TypeResolver() {
+                            @Override
+                            public GraphQLObjectType getType(TypeResolutionEnvironment env) {
+                                return null;
+                            }
+                        }))
+                .type("CDP_ProfileInterface", typeWiring -> typeWiring
+                        .typeResolver(new TypeResolver() {
+                            @Override
+                            public GraphQLObjectType getType(TypeResolutionEnvironment env) {
+                                return null;
+                            }
+                        }))
+                .type("CDP_PropertyInterface", typeWiring -> typeWiring
+                        .typeResolver(new TypeResolver() {
+                            @Override
+                            public GraphQLObjectType getType(TypeResolutionEnvironment env) {
+                                return null;
+                            }
+                        }))
                 // .scalar(CustomScalar)
                 // this uses builder function lambda syntax
                 /*
@@ -93,6 +177,60 @@ public class CDPSDLServletImpl extends HttpServlet {
 
         RuntimeWiring wiring = buildRuntimeWiring();
         GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, wiring);
+        graphQL = GraphQL.newGraphQL(graphQLSchema)
+                .build();
+
+        objectMapper = new ObjectMapper();
+        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        String query = req.getParameter("query");
+        if ("/schema.json".equals(req.getPathInfo())) {
+            query = IntrospectionQuery.INTROSPECTION_QUERY;
+        }
+        String operationName = req.getParameter("operationName");
+        String variableStr = req.getParameter("variables");
+        Map<String, Object> variables = new HashMap<>();
+        if ((variableStr != null) && (variableStr.trim().length() > 0)) {
+            TypeReference<Map<String, Object>> typeRef = new TypeReference<Map<String, Object>>() {
+            };
+            variables = objectMapper.readValue(variableStr, typeRef);
+        }
+
+        executeGraphQLRequest(resp, query, operationName, variables);
+    }
+
+    private void executeGraphQLRequest(HttpServletResponse resp, String query, String operationName, Map<String, Object> variables) throws IOException {
+        ExecutionInput executionInput = ExecutionInput.newExecutionInput()
+                .query(query)
+                .variables(variables)
+                .operationName(operationName)
+                .build();
+
+        ExecutionResult executionResult = graphQL.execute(executionInput);
+
+        Map<String, Object> toSpecificationResult = executionResult.toSpecification();
+
+        PrintWriter out = resp.getWriter();
+        objectMapper.writeValue(out, toSpecificationResult);
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        InputStream bodyStream = req.getInputStream();
+        TypeReference<Map<String, Object>> typeRef = new TypeReference<Map<String, Object>>() {
+        };
+        Map<String, Object> body = objectMapper.readValue(bodyStream, typeRef);
+        String query = (String) body.get("query");
+        String operationName = (String) body.get("operationName");
+        Map<String, Object> variables = (Map<String, Object>) body.get("variables");
+        if (variables == null) {
+            variables = new HashMap<>();
+        }
+
+        executeGraphQLRequest(resp, query, operationName, variables);
     }
 
     private Reader getSchemaReader(String resourceUrl) {
diff --git a/graphql/cxs-impl/src/main/resources/cdp-schema.graphqls b/graphql/cxs-impl/src/main/resources/cdp-schema.graphqls
index 7a924ca..6e178a6 100644
--- a/graphql/cxs-impl/src/main/resources/cdp-schema.graphqls
+++ b/graphql/cxs-impl/src/main/resources/cdp-schema.graphqls
@@ -971,8 +971,4 @@ Uses RFC-3339 representation, for example 16:39:57-08:00, see
 https://github.com/graphql-java/graphql-java-extended-scalars for example
 implementation 
 """
-scalar Time
-
-"""The `Upload` scalar type represents a file upload."""
-scalar Upload
-
+scalar Time
\ No newline at end of file
diff --git a/graphql/karaf-feature/pom.xml b/graphql/karaf-feature/pom.xml
index b813872..ae56dd4 100644
--- a/graphql/karaf-feature/pom.xml
+++ b/graphql/karaf-feature/pom.xml
@@ -115,6 +115,11 @@
             <version>${graphql.java.annotations.version}</version>
         </dependency>
         <dependency>
+            <groupId>com.graphql-java</groupId>
+            <artifactId>graphql-java-extended-scalars</artifactId>
+            <version>${graphql.java.extended.scalars.version}</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.unomi</groupId>
                 <artifactId>cdp-graphql-api-impl</artifactId>
             <version>1.4.0-SNAPSHOT</version>
diff --git a/graphql/pom.xml b/graphql/pom.xml
index 260f787..26f1644 100644
--- a/graphql/pom.xml
+++ b/graphql/pom.xml
@@ -34,6 +34,7 @@
         <graphql.java.servlet.version>7.4.1</graphql.java.servlet.version>
         <graphql.java.version>12.0</graphql.java.version>
         <graphql.java.annotations.version>7.0</graphql.java.annotations.version>
+        <graphql.java.extended.scalars.version>1.0</graphql.java.extended.scalars.version>
         <jackson.version>2.9.7</jackson.version>
     </properties>