UNOMI-392 Integrate GraphQL v14 field visibility with always true by … (#224)
* UNOMI-392 Integrate GraphQL v14 field visibility with always true by default
* UNOMI-392 Integrate GraphQL v14 field visibility with always true by default
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/providers/GraphQLFieldVisibilityProvider.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/providers/GraphQLFieldVisibilityProvider.java
new file mode 100644
index 0000000..a835030
--- /dev/null
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/providers/GraphQLFieldVisibilityProvider.java
@@ -0,0 +1,29 @@
+/*
+ * 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.unomi.graphql.providers;
+
+import graphql.schema.visibility.GraphqlFieldVisibility;
+
+/**
+ * Provider of {@link GraphqlFieldVisibility} to limit graphql schema fields visibility
+ * More about it here https://www.graphql-java.com/documentation/v14/fieldvisibility/
+ */
+public interface GraphQLFieldVisibilityProvider extends GraphQLProvider {
+
+ GraphqlFieldVisibility getGraphQLFieldVisibility();
+
+}
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaProvider.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaProvider.java
index 31a23b6..8ea7193 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaProvider.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaProvider.java
@@ -46,6 +46,7 @@
import org.apache.unomi.graphql.providers.GraphQLAdditionalTypesProvider;
import org.apache.unomi.graphql.providers.GraphQLCodeRegistryProvider;
import org.apache.unomi.graphql.providers.GraphQLExtensionsProvider;
+import org.apache.unomi.graphql.providers.GraphQLFieldVisibilityProvider;
import org.apache.unomi.graphql.providers.GraphQLMutationProvider;
import org.apache.unomi.graphql.providers.GraphQLQueryProvider;
import org.apache.unomi.graphql.providers.GraphQLSubscriptionProvider;
@@ -99,6 +100,8 @@
private final List<GraphQLSubscriptionProvider> subscriptionProviders;
+ private final GraphQLFieldVisibilityProvider fieldVisibilityProvider;
+
private final GraphQLCodeRegistryProvider codeRegistryProvider;
private final UnomiEventPublisher eventPublisher;
@@ -118,6 +121,7 @@
this.mutationProviders = builder.mutationProviders;
this.subscriptionProviders = builder.subscriptionProviders;
this.codeRegistryProvider = builder.codeRegistryProvider;
+ this.fieldVisibilityProvider = builder.fieldVisibilityProvider;
}
public GraphQLSchema createSchema() {
@@ -139,6 +143,8 @@
transformMutations();
+ configureFieldVisibility();
+
configureCodeRegister();
final AnnotationsSchemaCreator.Builder annotationsSchema = AnnotationsSchemaCreator.newAnnotationsSchema();
@@ -672,6 +678,13 @@
}
}
+ private void configureFieldVisibility() {
+ if (fieldVisibilityProvider != null) {
+ graphQLAnnotations.getContainer().getCodeRegistryBuilder()
+ .fieldVisibility(fieldVisibilityProvider.getGraphQLFieldVisibility());
+ }
+ }
+
public GraphQLInputObjectType getInputObjectType(final Class<?> annotatedClass) {
return (GraphQLInputObjectType) graphQLAnnotations.getObjectHandler().getTypeRetriever()
.getGraphQLType(annotatedClass, graphQLAnnotations.getContainer(), true);
@@ -704,6 +717,8 @@
List<GraphQLSubscriptionProvider> subscriptionProviders;
+ GraphQLFieldVisibilityProvider fieldVisibilityProvider;
+
GraphQLCodeRegistryProvider codeRegistryProvider;
UnomiEventPublisher eventPublisher;
@@ -753,6 +768,11 @@
return this;
}
+ public Builder fieldVisibilityProvider(GraphQLFieldVisibilityProvider fieldVisibilityProvider) {
+ this.fieldVisibilityProvider = fieldVisibilityProvider;
+ return this;
+ }
+
void validate() {
Objects.requireNonNull(profileService, "Profile service can not be null");
}
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaUpdater.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaUpdater.java
index 58ac373..73a7712 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaUpdater.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/schema/GraphQLSchemaUpdater.java
@@ -26,6 +26,7 @@
import org.apache.unomi.graphql.providers.GraphQLAdditionalTypesProvider;
import org.apache.unomi.graphql.providers.GraphQLCodeRegistryProvider;
import org.apache.unomi.graphql.providers.GraphQLExtensionsProvider;
+import org.apache.unomi.graphql.providers.GraphQLFieldVisibilityProvider;
import org.apache.unomi.graphql.providers.GraphQLMutationProvider;
import org.apache.unomi.graphql.providers.GraphQLProvider;
import org.apache.unomi.graphql.providers.GraphQLQueryProvider;
@@ -72,6 +73,8 @@
private final List<GraphQLTypeFunctionProvider> typeFunctionProviders = new CopyOnWriteArrayList<>();
+ private GraphQLFieldVisibilityProvider fieldVisibilityProvider;
+
private GraphQLCodeRegistryProvider codeRegistryProvider;
private UnomiEventPublisher eventPublisher;
@@ -161,6 +164,9 @@
if (provider instanceof GraphQLAdditionalTypesProvider) {
additionalTypesProviders.add((GraphQLAdditionalTypesProvider) provider);
}
+ if (provider instanceof GraphQLFieldVisibilityProvider) {
+ fieldVisibilityProvider = (GraphQLFieldVisibilityProvider) provider;
+ }
if (provider instanceof GraphQLCodeRegistryProvider) {
codeRegistryProvider = (GraphQLCodeRegistryProvider) provider;
}
@@ -177,11 +183,11 @@
if (provider instanceof GraphQLSubscriptionProvider) {
subscriptionProviders.remove(provider);
}
- if (provider instanceof GraphQLSubscriptionProvider) {
- subscriptionProviders.add((GraphQLSubscriptionProvider) provider);
- }
if (provider instanceof GraphQLAdditionalTypesProvider) {
- additionalTypesProviders.add((GraphQLAdditionalTypesProvider) provider);
+ additionalTypesProviders.remove(provider);
+ }
+ if (provider instanceof GraphQLFieldVisibilityProvider) {
+ fieldVisibilityProvider = null;
}
if (provider instanceof GraphQLCodeRegistryProvider) {
codeRegistryProvider = GraphQLCodeRegistry::newCodeRegistry;
@@ -228,6 +234,20 @@
updateSchema();
}
+
+ @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
+ public void bindFieldVisibilityProvider(GraphQLFieldVisibilityProvider provider) {
+ fieldVisibilityProvider = provider;
+
+ updateSchema();
+ }
+
+ public void unbindFieldVisibilityProvider(GraphQLFieldVisibilityProvider provider) {
+ fieldVisibilityProvider = null;
+
+ updateSchema();
+ }
+
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
public void bindExtensionsProvider(GraphQLExtensionsProvider provider) {
extensionsProviders.add(provider);
@@ -319,6 +339,7 @@
.subscriptionProviders(subscriptionProviders)
.eventPublisher(eventPublisher)
.codeRegistryProvider(codeRegistryProvider)
+ .fieldVisibilityProvider(fieldVisibilityProvider)
.build();
final GraphQLSchema schema = schemaProvider.createSchema();
diff --git a/samples/graphql-providers/src/main/java/org/apache/unomi/graphql/providers/sample/CDPProviderSample.java b/samples/graphql-providers/src/main/java/org/apache/unomi/graphql/providers/sample/CDPProviderSample.java
index 8fd984c..8f688d4 100644
--- a/samples/graphql-providers/src/main/java/org/apache/unomi/graphql/providers/sample/CDPProviderSample.java
+++ b/samples/graphql-providers/src/main/java/org/apache/unomi/graphql/providers/sample/CDPProviderSample.java
@@ -23,9 +23,12 @@
import graphql.schema.GraphQLArgument;
import graphql.schema.GraphQLCodeRegistry;
import graphql.schema.GraphQLFieldDefinition;
+import graphql.schema.visibility.BlockedFields;
+import graphql.schema.visibility.GraphqlFieldVisibility;
import org.apache.unomi.graphql.providers.GraphQLAdditionalTypesProvider;
import org.apache.unomi.graphql.providers.GraphQLCodeRegistryProvider;
import org.apache.unomi.graphql.providers.GraphQLExtensionsProvider;
+import org.apache.unomi.graphql.providers.GraphQLFieldVisibilityProvider;
import org.apache.unomi.graphql.providers.GraphQLMutationProvider;
import org.apache.unomi.graphql.providers.GraphQLProvider;
import org.apache.unomi.graphql.providers.GraphQLQueryProvider;
@@ -43,7 +46,7 @@
@Component(immediate = true, service = GraphQLProvider.class)
public class CDPProviderSample
- implements GraphQLExtensionsProvider, GraphQLMutationProvider, GraphQLQueryProvider, GraphQLCodeRegistryProvider, GraphQLAdditionalTypesProvider {
+ implements GraphQLExtensionsProvider, GraphQLMutationProvider, GraphQLQueryProvider, GraphQLCodeRegistryProvider, GraphQLAdditionalTypesProvider, GraphQLFieldVisibilityProvider {
private boolean isActivated;
@@ -137,4 +140,12 @@
return types;
}
+ @Override
+ public GraphqlFieldVisibility getGraphQLFieldVisibility() {
+ // Blocks fields based on patterns
+ return BlockedFields.newBlock()
+ .addPattern("CDP_SegmentInput.name")
+ .addPattern(".*\\.delete.*") // regular expressions allowed
+ .build();
+ }
}