Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added directive filtration #1878

Merged
merged 1 commit into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private Schema generateSchema() {
Annotations annotations = Annotations.getAnnotationsForClass(graphQLApiAnnotation.target().asClass());
schema.getDirectiveInstances()
.addAll(directivesHelper
.buildDirectiveInstances(annotations)
.buildDirectiveInstances(annotations, "SCHEMA")
.stream()
.map(directiveInstance -> {
String directiveClassName = directiveInstance.getType().getClassName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public ArgumentCreator(ReferenceCreator referenceCreator) {
deprecatedHelper = new DeprecatedDirectivesHelper();
}

@Override
public String getDirectiveLocation() {
return "ARGUMENT_DEFINITION";
}

/**
* Create an argument model. Arguments exist on Operations as input parameters
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ public DirectiveTypeCreator(ReferenceCreator referenceCreator) {
super(referenceCreator);
}

@Override
public String getDirectiveLocation() {
throw new IllegalArgumentException(
"This method should never be called since 'DirectiveType' cannot have another directives");
}

private static DotName NON_NULL = DotName.createSimple("org.eclipse.microprofile.graphql.NonNull");

public DirectiveType create(ClassInfo classInfo) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public FieldCreator(ReferenceCreator referenceCreator) {
deprecatedHelper = new DeprecatedDirectivesHelper();
}

@Override
public String getDirectiveLocation() {
return "FIELD_DEFINITION";
}

/**
* Creates a field from a method only.This is used in the case of an interface
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public TypeAutoNameStrategy getTypeAutoNameStrategy() {
}

/**
* The the return type.This is usually the method return type, but can also be adapted to something else
* The return type.This is usually the method return type, but can also be adapted to something else
*
* @param methodInfo method
* @return the return type
Expand All @@ -60,6 +60,8 @@ protected static Type getReturnType(FieldInfo fieldInfo) {

}

public abstract String getDirectiveLocation();

protected void populateField(Direction direction, Field field, Type type, Annotations annotations) {
// Wrapper
field.setWrapper(WrapperCreator.createWrapper(type).orElse(null));
Expand Down Expand Up @@ -97,7 +99,15 @@ private void doPopulateField(Direction direction, Field field, Type type, Annota

// Directives
if (directives != null) { // this happens while scanning for the directive types
field.addDirectiveInstances(directives.buildDirectiveInstances(annotations));
field.addDirectiveInstances(directives.buildDirectiveInstances(annotations, getDirectiveLocation(direction)));
}
}

private String getDirectiveLocation(Direction direction) {
String directiveLocation = getDirectiveLocation();
if (direction.equals(Direction.IN) && directiveLocation.equals("FIELD_DEFINITION")) {
return "INPUT_FIELD_DEFINITION";
}
return directiveLocation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,9 @@ private void addDirectivesForRolesAllowed(Annotations annotationsForPojo, Annota
operation.addDirectiveInstance(rolesAllowedDirectives);
}
}

@Override
public String getDirectiveLocation() {
return "FIELD_DEFINITION";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,14 @@ public Type create(ClassInfo classInfo, Reference reference) {
addOperations(type, classInfo);

// Directives
addDirectives(type, annotations);

addDirectives(type, annotations, getDirectiveLocation());
return type;
}

protected abstract void addFields(Type type, ClassInfo classInfo, Reference reference);

private void addDirectives(Type type, Annotations annotations) {
type.setDirectiveInstances(directives.buildDirectiveInstances(annotations));
private void addDirectives(Type type, Annotations annotations, String directiveLocation) {
type.setDirectiveInstances(directives.buildDirectiveInstances(annotations, directiveLocation));
}

private void addPolymorphicTypes(Type type, ClassInfo classInfo, Reference reference) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@
public interface Creator<T> {

T create(ClassInfo classInfo, Reference reference);

String getDirectiveLocation();
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,13 @@ public EnumType create(ClassInfo classInfo, Reference reference) {
return enumType;
}

@Override
public String getDirectiveLocation() {
return "ENUM";
}

private List<DirectiveInstance> getDirectiveInstances(Annotations annotations) {
return directives.buildDirectiveInstances(annotations);
return directives.buildDirectiveInstances(annotations, getDirectiveLocation());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
*/
public class InputTypeCreator implements Creator<InputType> {
private static final Logger LOG = Logger.getLogger(InputTypeCreator.class.getName());

private final FieldCreator fieldCreator;
private Directives directives;

Expand Down Expand Up @@ -78,6 +77,11 @@ public InputType create(ClassInfo classInfo, Reference reference) {
return inputType;
}

@Override
public String getDirectiveLocation() {
return "INPUT_OBJECT";
}

public boolean hasUseableConstructor(ClassInfo classInfo) {
MethodInfo constructor = findCreator(classInfo);
return constructor != null;
Expand Down Expand Up @@ -138,7 +142,7 @@ public void setDirectives(Directives directives) {
}

private List<DirectiveInstance> getDirectiveInstances(Annotations annotations) {
return directives.buildDirectiveInstances(annotations);
return directives.buildDirectiveInstances(annotations, getDirectiveLocation());
}

private void addFields(InputType inputType, ClassInfo classInfo, Reference reference) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ protected void addFields(Type interfaceType, ClassInfo classInfo, Reference refe
}
}

@Override
public String getDirectiveLocation() {
return "INTERFACE";
}

private static final String JAVA_DOT = "java.";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,8 @@ private boolean isNotGenericType(MethodInfo method) {
type.kind() != org.jboss.jandex.Type.Kind.PARAMETERIZED_TYPE);
}

@Override
public String getDirectiveLocation() {
return "OBJECT";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,11 @@ public UnionType create(ClassInfo classInfo, Reference reference) {

return new UnionType(classInfo.name().toString(), name, maybeDescription.orElse(null));
}

// TODO: create feature that allows adding UNION directives (graphql.schema)
@Override
public String getDirectiveLocation() {
return "UNION";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ public Directives(List<DirectiveType> directiveTypes) {
}
}

public List<DirectiveInstance> buildDirectiveInstances(Annotations annotations) {
public List<DirectiveInstance> buildDirectiveInstances(Annotations annotations, String directiveLocation) {
// only build directive instances from `@Directive` annotations here (that means the `directiveTypes` map),
// because `directiveTypesOther` directives get their instances added on-the-go by classes that extend `ModelCreator`
return directiveTypes.keySet().stream()
.flatMap(annotations::resolve)
.map(this::toDirectiveInstance)
.filter(directiveInstance -> directiveInstance.getType().getLocations().contains(directiveLocation))
.collect(toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public void testSchemaWithDirectives() throws IOException {
assertEquals("someDirective", someDirective.getName());
assertEquals(SomeDirective.class.getName(), someDirective.getClassName());
assertEquals(singleton("value"), someDirective.argumentNames());
assertEquals(new HashSet<>(asList("INTERFACE", "FIELD", "OBJECT")), someDirective.getLocations());
assertEquals(new HashSet<>(asList("INTERFACE", "FIELD_DEFINITION", "OBJECT")), someDirective.getLocations());

// check directive instances on type
Type movie = schema.getTypes().get("Movie");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.smallrye.graphql.index.app;

import static io.smallrye.graphql.api.DirectiveLocation.FIELD;
import static io.smallrye.graphql.api.DirectiveLocation.FIELD_DEFINITION;
import static io.smallrye.graphql.api.DirectiveLocation.INTERFACE;
import static io.smallrye.graphql.api.DirectiveLocation.OBJECT;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
Expand All @@ -9,7 +9,7 @@

import io.smallrye.graphql.api.Directive;

@Directive(on = { OBJECT, INTERFACE, FIELD })
@Directive(on = { OBJECT, INTERFACE, FIELD_DEFINITION })
@Retention(RUNTIME)
public @interface SomeDirective {
String[] value();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public enum DirectiveLocation {
INLINE_FRAGMENT,
VARIABLE_DEFINITION,

// TypeSystemDirectiveLocation
// TypeSystemDirectiveLocation:
SCHEMA,
SCALAR,
OBJECT,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.smallrye.graphql.api.federation;

import static io.smallrye.graphql.api.DirectiveLocation.*;
import static io.smallrye.graphql.api.DirectiveLocation.OBJECT;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.smallrye.graphql.schema;

import static io.smallrye.graphql.api.DirectiveLocation.FIELD;
import static io.smallrye.graphql.api.DirectiveLocation.FIELD_DEFINITION;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;

import io.smallrye.graphql.api.Directive;

@Retention(RUNTIME)
@Directive(on = FIELD)
@Directive(on = FIELD_DEFINITION)
public @interface FieldDirective {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Query;

import io.smallrye.graphql.schema.schemadirectives.OutputDirective;

@GraphQLApi
public class InputTestApi {

Expand All @@ -11,6 +13,11 @@ public int query(InputWithDirectives input) {
return 0;
}

@Query
public int someQuery(SomeObject someObject) {
return 1;
}

@InputDirective
public static class InputWithDirectives {
@InputDirective
Expand All @@ -21,4 +28,13 @@ public void setBar(int bar) {
}
}

@OutputDirective
public static class SomeObject {
int boo;

public void setBoo(int boo) {
this.boo = boo;
}
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.smallrye.graphql.schema;

import static io.smallrye.graphql.api.DirectiveLocation.*;
import static io.smallrye.graphql.api.DirectiveLocation.FIELD_DEFINITION;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;

import io.smallrye.graphql.api.Directive;

@Retention(RUNTIME)
@Directive(on = { QUERY, MUTATION, SUBSCRIPTION })
@Directive(on = { FIELD_DEFINITION })
public @interface OperationDirective {
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import io.smallrye.graphql.schema.rolesallowedschemas.RolesSchema2;
import io.smallrye.graphql.schema.rolesallowedschemas.RolesSchema3;
import io.smallrye.graphql.schema.schemadirectives.NonRepeatableSchemaDirective;
import io.smallrye.graphql.schema.schemadirectives.OutputDirective;
import io.smallrye.graphql.schema.schemadirectives.RepeatableSchemaDirective;
import io.smallrye.graphql.schema.schemadirectives.Schema1;
import io.smallrye.graphql.schema.schemadirectives.Schema2;
Expand Down Expand Up @@ -125,8 +126,8 @@ void schemaWithEnumDirectives() {

@Test
void schemaWithInputDirectives() {
GraphQLSchema graphQLSchema = createGraphQLSchema(InputDirective.class, InputTestApi.class,
InputTestApi.InputWithDirectives.class);
GraphQLSchema graphQLSchema = createGraphQLSchema(InputDirective.class, OutputDirective.class, InputTestApi.class,
InputTestApi.InputWithDirectives.class, InputTestApi.SomeObject.class);

GraphQLInputObjectType inputWithDirectives = graphQLSchema.getTypeAs("InputWithDirectivesInput");
assertNotNull(inputWithDirectives.getDirective("inputDirective"),
Expand All @@ -135,6 +136,10 @@ void schemaWithInputDirectives() {
"Input type field InputWithDirectivesInput.foo should have directive @inputDirective");
assertNotNull(inputWithDirectives.getField("bar").getDirective("inputDirective"),
"Input type field InputWithDirectivesInput.bar should have directive @inputDirective");

GraphQLInputObjectType outputAsInputWithDirectives = graphQLSchema.getTypeAs("SomeObjectInput");
assertNull(outputAsInputWithDirectives.getDirective("outputDirective"),
"Input type SomeObject should not have directive @outputDirective");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.smallrye.graphql.schema.schemadirectives;

import static io.smallrye.graphql.api.DirectiveLocation.OBJECT;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;

import io.smallrye.graphql.api.Directive;

@Retention(RUNTIME)
@Directive(on = { OBJECT })
public @interface OutputDirective {
}
4 changes: 2 additions & 2 deletions server/implementation/src/test/resources/schemaTest.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ directive @deprecated(
reason: String = "No longer supported"
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION

directive @fieldDirective on FIELD
directive @fieldDirective on FIELD_DEFINITION

"Directs the executor to include this field or fragment only when the `if` argument is true"
directive @include(
Expand All @@ -20,7 +20,7 @@ directive @include(
"test-description"
directive @intArrayTestDirective(value: [Int]) on OBJECT | INTERFACE

directive @operationDirective on QUERY | MUTATION | SUBSCRIPTION
directive @operationDirective on FIELD_DEFINITION

"Used to specify the role required to execute a given field or operation."
directive @rolesAllowed(value: String) on FIELD_DEFINITION
Expand Down