From a3ebd663bd05435db6945ff8d31ef56332331b4c Mon Sep 17 00:00:00 2001 From: Geofrey Flores Date: Wed, 7 Feb 2024 14:04:56 -0500 Subject: [PATCH 1/2] Add new GraphQLDirectiveProvider for building/verifying custom directive defs in schema --- .../servlet/OsgiGraphQLHttpServlet.java | 18 +++++++++ .../kickstart/servlet/OsgiSchemaBuilder.java | 19 ++++++++++ .../osgi/GraphQLDirectiveProvider.java | 12 ++++++ .../servlet/OsgiGraphQLHttpServletSpec.groovy | 37 +++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java diff --git a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiGraphQLHttpServlet.java b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiGraphQLHttpServlet.java index 435075ed..748b979d 100644 --- a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiGraphQLHttpServlet.java +++ b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiGraphQLHttpServlet.java @@ -15,6 +15,7 @@ import graphql.kickstart.servlet.core.GraphQLServletListener; import graphql.kickstart.servlet.core.GraphQLServletRootObjectBuilder; import graphql.kickstart.servlet.osgi.GraphQLCodeRegistryProvider; +import graphql.kickstart.servlet.osgi.GraphQLDirectiveProvider; import graphql.kickstart.servlet.osgi.GraphQLMutationProvider; import graphql.kickstart.servlet.osgi.GraphQLProvider; import graphql.kickstart.servlet.osgi.GraphQLQueryProvider; @@ -75,6 +76,9 @@ public void bindProvider(GraphQLProvider provider) { if (provider instanceof GraphQLTypesProvider) { schemaBuilder.add((GraphQLTypesProvider) provider); } + if (provider instanceof GraphQLDirectiveProvider) { + schemaBuilder.add((GraphQLDirectiveProvider) provider); + } if (provider instanceof GraphQLCodeRegistryProvider) { schemaBuilder.setCodeRegistryProvider((GraphQLCodeRegistryProvider) provider); } @@ -94,6 +98,9 @@ public void unbindProvider(GraphQLProvider provider) { if (provider instanceof GraphQLTypesProvider) { schemaBuilder.remove((GraphQLTypesProvider) provider); } + if (provider instanceof GraphQLDirectiveProvider) { + schemaBuilder.remove((GraphQLDirectiveProvider) provider); + } if (provider instanceof GraphQLCodeRegistryProvider) { schemaBuilder.setCodeRegistryProvider(() -> GraphQLCodeRegistry.newCodeRegistry().build()); } @@ -144,6 +151,17 @@ public void unbindTypesProvider(GraphQLTypesProvider typesProvider) { updateSchema(); } + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) + public void bindDirectivesProvider(GraphQLDirectiveProvider directiveProvider) { + schemaBuilder.add(directiveProvider); + updateSchema(); + } + + public void unbindDirectivesProvider(GraphQLDirectiveProvider directiveProvider) { + schemaBuilder.remove(directiveProvider); + updateSchema(); + } + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) public void bindServletListener(GraphQLServletListener listener) { schemaBuilder.add(listener); diff --git a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiSchemaBuilder.java b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiSchemaBuilder.java index 880a77a3..ff93a8aa 100644 --- a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiSchemaBuilder.java +++ b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiSchemaBuilder.java @@ -25,11 +25,13 @@ import graphql.kickstart.servlet.input.GraphQLInvocationInputFactory; import graphql.kickstart.servlet.osgi.GraphQLCodeRegistryProvider; import graphql.kickstart.servlet.osgi.GraphQLFieldProvider; +import graphql.kickstart.servlet.osgi.GraphQLDirectiveProvider; import graphql.kickstart.servlet.osgi.GraphQLMutationProvider; import graphql.kickstart.servlet.osgi.GraphQLQueryProvider; import graphql.kickstart.servlet.osgi.GraphQLSubscriptionProvider; import graphql.kickstart.servlet.osgi.GraphQLTypesProvider; import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLType; @@ -50,6 +52,7 @@ class OsgiSchemaBuilder { private final List mutationProviders = new ArrayList<>(); private final List subscriptionProviders = new ArrayList<>(); private final List typesProviders = new ArrayList<>(); + private final List directiveProviders = new ArrayList<>(); private final List listeners = new ArrayList<>(); private GraphQLServletContextBuilder contextBuilder = new DefaultGraphQLServletContextBuilder(); @@ -103,6 +106,7 @@ private void doUpdateSchema() { .mutation(buildMutationType()) .subscription(buildSubscriptionType()) .additionalTypes(buildTypes()) + .additionalDirectives(buildDirectives()) .codeRegistry(codeRegistryProvider.getCodeRegistry()) .build()); } @@ -159,6 +163,13 @@ private GraphQLObjectType buildObjectType(String name, List buildDirectives() { + return directiveProviders.stream() + .map(GraphQLDirectiveProvider::getDirectives) + .flatMap(Collection::stream) + .collect(toSet()); + } + void add(GraphQLQueryProvider provider) { queryProviders.add(provider); } @@ -175,6 +186,10 @@ void add(GraphQLTypesProvider provider) { typesProviders.add(provider); } + void add(GraphQLDirectiveProvider provider) { + directiveProviders.add(provider); + } + void remove(GraphQLQueryProvider provider) { queryProviders.remove(provider); } @@ -191,6 +206,10 @@ void remove(GraphQLTypesProvider provider) { typesProviders.remove(provider); } + void remove(GraphQLDirectiveProvider provider) { + directiveProviders.remove(provider); + } + GraphQLSchemaServletProvider getSchemaProvider() { return schemaProvider; } diff --git a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java new file mode 100644 index 00000000..cc438ed7 --- /dev/null +++ b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java @@ -0,0 +1,12 @@ +package graphql.kickstart.servlet.osgi; + +import graphql.schema.GraphQLDirective; +import java.util.Set; + + +public interface GraphQLDirectiveProvider extends GraphQLProvider { + + /** @return A collection of directive definitions that will be added to the schema. */ + Set getDirectives(); + +} diff --git a/graphql-java-servlet/src/test/groovy/graphql/kickstart/servlet/OsgiGraphQLHttpServletSpec.groovy b/graphql-java-servlet/src/test/groovy/graphql/kickstart/servlet/OsgiGraphQLHttpServletSpec.groovy index ea4ed23d..0cab0577 100644 --- a/graphql-java-servlet/src/test/groovy/graphql/kickstart/servlet/OsgiGraphQLHttpServletSpec.groovy +++ b/graphql-java-servlet/src/test/groovy/graphql/kickstart/servlet/OsgiGraphQLHttpServletSpec.groovy @@ -265,6 +265,43 @@ class OsgiGraphQLHttpServletSpec extends Specification { null == servlet.configuration.invocationInputFactory.schemaProvider.schema.getType("Upload") } + static class TestDirectiveProvider implements GraphQLDirectiveProvider { + @Override + Set getDirectives() { + return new HashSet<>(Arrays.asList(GraphQLDirective.newDirective().name("myDirective").build())); + } + } + + def "directive provider adds directives"() { + setup: + OsgiGraphQLHttpServlet servlet = new OsgiGraphQLHttpServlet() + TestDirectiveProvider directiveProvider = new TestDirectiveProvider() + + when: + servlet.bindDirectivesProvider(directiveProvider) + + then: + def directive = servlet.configuration.invocationInputFactory.schemaProvider.schema.getDirective("myDirective") + directive != null + directive.name == "myDirective" + + when: + servlet.unbindDirectivesProvider(directiveProvider) + + then: + null == servlet.configuration.invocationInputFactory.schemaProvider.schema.getDirective("myDirective") + + when: + servlet.bindProvider(directiveProvider) + then: + servlet.configuration.invocationInputFactory.schemaProvider.schema.getDirective("myDirective").name == "myDirective" + + when: + servlet.unbindProvider(directiveProvider) + then: + null == servlet.configuration.invocationInputFactory.schemaProvider.schema.getType("myDirective") + } + def "servlet listener is bound and unbound"() { setup: def servlet = new OsgiGraphQLHttpServlet() From d9d2d1d22e7c2de3beeb4a2bc0da99db5d5a538b Mon Sep 17 00:00:00 2001 From: Geofrey Flores <75278792+gflores-jahia@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:20:03 -0500 Subject: [PATCH 2/2] Switch getDirectives to return Collection instead Co-authored-by: Federico Rispo --- .../kickstart/servlet/osgi/GraphQLDirectiveProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java index cc438ed7..b67eb30c 100644 --- a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java +++ b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java @@ -1,12 +1,12 @@ package graphql.kickstart.servlet.osgi; import graphql.schema.GraphQLDirective; -import java.util.Set; +import java.util.Collection; public interface GraphQLDirectiveProvider extends GraphQLProvider { /** @return A collection of directive definitions that will be added to the schema. */ - Set getDirectives(); + Collection getDirectives(); }