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>