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

Fix gradle plugin for correct generation federated schema #2204

Merged
merged 1 commit into from
Oct 11, 2024
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
@@ -0,0 +1,44 @@
package io.smallrye.graphql.gradle.tasks;

import io.smallrye.graphql.api.federation.Authenticated;
import io.smallrye.graphql.api.federation.ComposeDirective;
import io.smallrye.graphql.api.federation.Extends;
import io.smallrye.graphql.api.federation.External;
import io.smallrye.graphql.api.federation.Inaccessible;
import io.smallrye.graphql.api.federation.InterfaceObject;
import io.smallrye.graphql.api.federation.Key;
import io.smallrye.graphql.api.federation.Override;
import io.smallrye.graphql.api.federation.Provides;
import io.smallrye.graphql.api.federation.Requires;
import io.smallrye.graphql.api.federation.Shareable;
import io.smallrye.graphql.api.federation.Tag;
import io.smallrye.graphql.api.federation.link.Link;
import io.smallrye.graphql.api.federation.policy.Policy;
import io.smallrye.graphql.api.federation.requiresscopes.RequiresScopes;
import org.jboss.jandex.DotName;

import java.util.ArrayList;
import java.util.List;

public final class FederationDotNames {
public static final List<DotName> FEDERATION_DIRECTIVES_NAMES;

static {
FEDERATION_DIRECTIVES_NAMES = new ArrayList<>();
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Authenticated.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(ComposeDirective.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Extends.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(External.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Inaccessible.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(InterfaceObject.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Key.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Override.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Provides.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Requires.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Shareable.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Tag.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Link.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(Policy.class));
FEDERATION_DIRECTIVES_NAMES.add(DotName.createSimple(RequiresScopes.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Repeatable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
Expand All @@ -13,6 +14,7 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

Expand All @@ -36,11 +38,37 @@
import org.jboss.jandex.Result;

import graphql.schema.GraphQLSchema;
import io.smallrye.graphql.api.Deprecated;
import io.smallrye.graphql.api.Entry;
import io.smallrye.graphql.api.OneOf;
import io.smallrye.graphql.api.federation.Authenticated;
import io.smallrye.graphql.api.federation.ComposeDirective;
import io.smallrye.graphql.api.federation.Extends;
import io.smallrye.graphql.api.federation.External;
import io.smallrye.graphql.api.federation.FieldSet;
import io.smallrye.graphql.api.federation.Inaccessible;
import io.smallrye.graphql.api.federation.InterfaceObject;
import io.smallrye.graphql.api.federation.Key;
import io.smallrye.graphql.api.federation.Override;
import io.smallrye.graphql.api.federation.Provides;
import io.smallrye.graphql.api.federation.Requires;
import io.smallrye.graphql.api.federation.Shareable;
import io.smallrye.graphql.api.federation.Tag;
import io.smallrye.graphql.api.federation.link.Import;
import io.smallrye.graphql.api.federation.link.Link;
import io.smallrye.graphql.api.federation.link.Purpose;
import io.smallrye.graphql.api.federation.policy.Policy;
import io.smallrye.graphql.api.federation.policy.PolicyGroup;
import io.smallrye.graphql.api.federation.policy.PolicyItem;
import io.smallrye.graphql.api.federation.requiresscopes.RequiresScopes;
import io.smallrye.graphql.api.federation.requiresscopes.ScopeGroup;
import io.smallrye.graphql.api.federation.requiresscopes.ScopeItem;
import io.smallrye.graphql.bootstrap.Bootstrap;
import io.smallrye.graphql.execution.SchemaPrinter;
import io.smallrye.graphql.schema.SchemaBuilder;
import io.smallrye.graphql.schema.model.Schema;
import io.smallrye.graphql.spi.config.Config;

import static io.smallrye.graphql.gradle.tasks.FederationDotNames.FEDERATION_DIRECTIVES_NAMES;

/**
* Generate schema task.
Expand Down Expand Up @@ -178,10 +206,17 @@ public static GradleConfig getConfig() {

@TaskAction
public void generateSchema() throws Exception {
this.config = new GradleConfig(includeScalars, includeDirectives, includeSchemaDefinition, includeIntrospectionTypes);
config = new GradleConfig(includeScalars, includeDirectives, includeSchemaDefinition, includeIntrospectionTypes);
ClassLoader classLoader = getClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
IndexView index = createIndex();

if (hasFederationDirectives(index)) {
config.setFederationEnabled(true);
System.setProperty("smallrye.graphql.federation.enabled", "true");
index = CompositeIndex.create(index, createFederationApiIndex());
}

String schema = generateSchema(index);
if (schema != null) {
write(schema);
Expand All @@ -190,6 +225,13 @@ public void generateSchema() throws Exception {
}
}

private static boolean hasFederationDirectives(IndexView index) {
return index.getKnownClasses().stream()
.anyMatch(classInfo -> FEDERATION_DIRECTIVES_NAMES.stream()
.anyMatch(classInfo::hasAnnotation)
);
}

private IndexView createIndex() {
IndexView moduleIndex;
try {
Expand Down Expand Up @@ -227,6 +269,45 @@ private IndexView createIndex() {
}
}

private IndexView createFederationApiIndex() throws IOException {
Indexer indexer = new Indexer();
indexer.indexClass(Map.class);
indexer.indexClass(Entry.class);
indexer.indexClass(Repeatable.class);

indexer.indexClass(Deprecated.class);
indexer.indexClass(OneOf.class);

// directives from the API module
indexer.indexClass(Authenticated.class);
indexer.indexClass(ComposeDirective.class);
indexer.indexClass(Extends.class);
indexer.indexClass(External.class);
indexer.indexClass(FieldSet.class);
indexer.indexClass(Inaccessible.class);
indexer.indexClass(InterfaceObject.class);
indexer.indexClass(Key.class);
indexer.indexClass(Override.class);
indexer.indexClass(Provides.class);
indexer.indexClass(Requires.class);
indexer.indexClass(Shareable.class);
indexer.indexClass(Tag.class);

indexer.indexClass(Link.class);
indexer.indexClass(Import.class);
indexer.indexClass(Purpose.class);

indexer.indexClass(Policy.class);
indexer.indexClass(PolicyGroup.class);
indexer.indexClass(PolicyItem.class);

indexer.indexClass(RequiresScopes.class);
indexer.indexClass(ScopeGroup.class);
indexer.indexClass(ScopeItem.class);

return indexer.complete();
}

// index the classes of this Gradle module
private Index indexModuleClasses() throws IOException {
Indexer indexer = new Indexer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ public class GradleConfig {

private final boolean includeIntrospectionTypes;

public GradleConfig(boolean includeScalars, boolean includeDirectives, boolean includeSchemaDefinition, boolean includeIntrospectionTypes) {
private boolean federationEnabled;

public GradleConfig(boolean includeScalars, boolean includeDirectives, boolean includeSchemaDefinition,
boolean includeIntrospectionTypes) {
this.includeScalars = includeScalars;
this.includeDirectives = includeDirectives;
this.includeSchemaDefinition = includeSchemaDefinition;
Expand All @@ -32,4 +35,12 @@ public boolean isIncludeSchemaDefinition() {
public boolean isIncludeIntrospectionTypes() {
return includeIntrospectionTypes;
}

public void setFederationEnabled(boolean federationEnabled) {
this.federationEnabled = federationEnabled;
}

public boolean isFederationEnabled() {
return federationEnabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class GradleConfigFacade implements Config {

private boolean includeIntrospectionTypes;

private boolean federationEnabled;

// Constructor used by the ServiceLoader mechanism. When this is called, we assume that GenerateSchemaTask
// has already produced a config based on the environment, and we just make a copy of it
public GradleConfigFacade() {
Expand All @@ -20,17 +22,19 @@ public GradleConfigFacade() {
this.includeDirectives = instance.isIncludeDirectives();
this.includeSchemaDefinition = instance.isIncludeSchemaDefinition();
this.includeIntrospectionTypes = instance.isIncludeIntrospectionTypes();

this.federationEnabled = instance.isFederationEnabled();
}

public GradleConfigFacade(boolean includeScalarsInSchema,
boolean includeDirectivesInSchema,
boolean includeSchemaDefinitionInSchema,
boolean includeIntrospectionTypesInSchema) {
boolean includeIntrospectionTypesInSchema,
boolean federationEnabled) {
this.includeScalars = includeScalarsInSchema;
this.includeDirectives = includeDirectivesInSchema;
this.includeSchemaDefinition = includeSchemaDefinitionInSchema;
this.includeIntrospectionTypes = includeIntrospectionTypesInSchema;
this.federationEnabled = federationEnabled;
}

@Override
Expand All @@ -57,4 +61,9 @@ public boolean isIncludeSchemaDefinitionInSchema() {
public boolean isIncludeIntrospectionTypesInSchema() {
return includeIntrospectionTypes;
}

@Override
public boolean isFederationEnabled() {
return federationEnabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.gradle.testkit.runner.BuildResult;
Expand All @@ -30,8 +29,13 @@ public void cleanup() {

@Test
public void testIncludeDirectives() throws IOException {
String schema = execute(Collections.singletonList("-DincludeDirectives=true"));
String schema = execute(List.of(
"-DincludeDirectives=true",
"-DincludeScalars=true",
"-DincludeSchemaDefinition=true"));
assertTrue(schema.contains("directive @skip"), "Directives should be included: " + schema);
assertTrue(schema.contains("_entities(representations"));
assertTrue(schema.contains("type Foo @key(fields : \"id\")"));
}

private String execute(List<String> arguments) throws IOException {
Expand Down
2 changes: 1 addition & 1 deletion tools/gradle-plugin/testing-project-kotlin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
}

dependencies {
implementation "io.smallrye:smallrye-graphql:1.3.2"
implementation "io.smallrye:smallrye-graphql:2.10.0"
}

repositories {
Expand Down
4 changes: 3 additions & 1 deletion tools/gradle-plugin/testing-project/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

dependencies {
implementation "io.smallrye:smallrye-graphql:1.3.2"
implementation "io.smallrye:smallrye-graphql:2.10.0"
}

repositories {
Expand All @@ -14,7 +14,9 @@ repositories {

generateSchema {
// FIXME: how to properly pass properties to runs? see the comment in GradlePluginGenerateSchemaTest.java
includeScalars = Boolean.getBoolean("includeScalars")
includeDirectives = Boolean.getBoolean("includeDirectives")
includeSchemaDefinition = Boolean.getBoolean("includeSchemaDefinition")
}

group 'org.acme'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
package org.acme;

import io.smallrye.graphql.api.federation.FieldSet;
import io.smallrye.graphql.api.federation.Key;

@Key(fields = @FieldSet("id"))
public class Foo {
private Integer id;

private Integer number;

public Foo() {
}

public Foo(Integer id, Integer number) {
this.id = id;
this.number = number;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public Integer getNumber() {
return number;
}

public void setNumber(Integer number) {
this.number = number;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,10 @@
import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Query;

import java.util.Collections;
import java.util.List;

@GraphQLApi
class TestingApi {

@Query
public Foo getFoo() {
return null;
}


}
}
Loading