diff --git a/gradle.properties b/gradle.properties
index 98f57787..e85bc033 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,7 +3,7 @@ version = 3.0-SNAPSHOT
# dependencies
annotationsVersion = 24.1.0
-graphQLJavaVersion = 21.3
+graphQLJavaVersion = 22.0
mockWebServerVersion = 4.12.0
protobufVersion = 4.26.1
slf4jVersion = 2.0.13
diff --git a/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/caching/CacheControlInstrumentation.java b/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/caching/CacheControlInstrumentation.java
index 036cbb16..dbeb5a46 100644
--- a/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/caching/CacheControlInstrumentation.java
+++ b/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/caching/CacheControlInstrumentation.java
@@ -11,7 +11,6 @@
import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters;
import graphql.schema.*;
import java.util.*;
-import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable;
@@ -19,13 +18,15 @@
* A GraphQL Java Instrumentation that computes a max age for an operation based on @cacheControl
* directives.
*
- *
You can retrieve the "max-age=..." header value with a {@link graphql.GraphQLContext}:
+ * You can retrieve the "max-age=..." header value with a {@link GraphQLContext}:
* String cacheControlHeader = CacheControlInstrumentation.cacheControlContext(context);
*
*
- *
See https://www.apollographql.com/docs/apollo-server/performance/caching/ and the original
- * implementation at
- * https://github.com/apollographql/apollo-server/blob/main/packages/apollo-server-core/src/plugin/cacheControl/index.ts
+ *
See @cacheControl
+ * documentation and the original Apollo Server plugin-response-cache
+ * implementation.
*/
public class CacheControlInstrumentation extends SimplePerformantInstrumentation {
private final int defaultMaxAge;
@@ -63,9 +64,12 @@ public InstrumentationState createState(InstrumentationCreateStateParameters par
@Override
public InstrumentationContext beginExecution(
InstrumentationExecutionParameters parameters, InstrumentationState state) {
- return new InstrumentationContext() {
+ return new InstrumentationContext<>() {
+
@Override
- public void onDispatched(CompletableFuture completableFuture) {}
+ public void onDispatched() {
+ // do nothing
+ }
@Override
public void onCompleted(ExecutionResult executionResult, Throwable throwable) {
@@ -81,7 +85,7 @@ public void onCompleted(ExecutionResult executionResult, Throwable throwable) {
}
@Override
- public InstrumentationContext beginField(
+ public @Nullable InstrumentationContext beginFieldExecution(
InstrumentationFieldParameters parameters, InstrumentationState state) {
CacheControlState cacheControlState = (CacheControlState) state;
CacheControlPolicy fieldPolicy = new CacheControlPolicy(allowZeroMaxAge);
@@ -168,8 +172,7 @@ public InstrumentationContext beginField(
}
cacheControlState.overallPolicy.restrict(fieldPolicy);
-
- return super.beginField(parameters, state);
+ return super.beginFieldExecution(parameters, state);
}
enum CacheControlScope {
diff --git a/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/directives/LinkDirectiveProcessor.java b/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/directives/LinkDirectiveProcessor.java
index 6e7b9f6d..646500a9 100644
--- a/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/directives/LinkDirectiveProcessor.java
+++ b/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/directives/LinkDirectiveProcessor.java
@@ -144,12 +144,12 @@ private static Map parseLinkImports(Directive linkDirective) {
.filter(field -> field.getName().equals("as"))
.findFirst();
- if (!nameField.isPresent() || !(nameField.get().getValue() instanceof StringValue)) {
+ if (nameField.isEmpty() || !(nameField.get().getValue() instanceof StringValue)) {
throw new UnsupportedLinkImportException(importedObjectValue);
}
final String name = ((StringValue) nameField.get().getValue()).getValue();
- if (!renameAsField.isPresent()) {
+ if (renameAsField.isEmpty()) {
imports.put(name, name);
} else {
final Value renamedAsValue = renameAsField.get().getValue();
diff --git a/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/printer/ServiceSDLPrinter.java b/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/printer/ServiceSDLPrinter.java
index e20f9691..658afd70 100644
--- a/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/printer/ServiceSDLPrinter.java
+++ b/graphql-java-support/src/main/java/com/apollographql/federation/graphqljava/printer/ServiceSDLPrinter.java
@@ -12,9 +12,9 @@
import graphql.schema.GraphQLNamedSchemaElement;
import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLSchemaElement;
+import graphql.schema.idl.DirectiveInfo;
import graphql.schema.idl.SchemaPrinter;
import graphql.schema.visibility.GraphqlFieldVisibility;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -28,10 +28,6 @@
*/
public final class ServiceSDLPrinter {
- // Apollo Gateway will fail Federation v1 composition if it sees standard directive definitions.
- private static final Set STANDARD_DIRECTIVES =
- new HashSet<>(Arrays.asList("deprecated", "include", "oneOf", "skip", "specifiedBy"));
-
private ServiceSDLPrinter() {
// hidden constructor as this is static utility class
}
@@ -44,11 +40,14 @@ private ServiceSDLPrinter() {
* should be removed (at least a single query has to be present for graphql-java to consider
* it as a valid schema)
* @return SDL compatible with Federation v1
+ * @deprecated Migrate to use Federation v2
*/
+ @Deprecated(since = "05/16/2024")
public static String generateServiceSDL(GraphQLSchema schema, boolean queryTypeShouldBeEmpty) {
// Gather directive definitions to hide.
final Set hiddenDirectiveDefinitions = new HashSet<>();
- hiddenDirectiveDefinitions.addAll(STANDARD_DIRECTIVES);
+ // Apollo Gateway will fail Federation v1 composition if it sees standard directive definitions.
+ hiddenDirectiveDefinitions.addAll(DirectiveInfo.GRAPHQL_SPECIFICATION_DIRECTIVE_MAP.keySet());
hiddenDirectiveDefinitions.addAll(FederationDirectives.allNames);
// Gather type definitions to hide.
@@ -102,23 +101,18 @@ public GraphQLFieldDefinition getFieldDefinition(
final GraphQLSchema federatedSchema =
schema.transform(schemaBuilder -> schemaBuilder.codeRegistry(newCodeRegistry));
- final Predicate excludeFedTypeDefinitions =
- element ->
- !(element instanceof GraphQLNamedSchemaElement
- && hiddenTypeDefinitions.contains(((GraphQLNamedSchemaElement) element).getName()));
- final Predicate excludeFedDirectiveDefinitions =
+ final Predicate shouldIncludeSchemaElement =
element ->
!(element instanceof GraphQLDirective
- && hiddenDirectiveDefinitions.contains(((GraphQLDirective) element).getName()));
+ && hiddenDirectiveDefinitions.contains(((GraphQLDirective) element).getName()))
+ && !(element instanceof GraphQLNamedSchemaElement
+ && hiddenTypeDefinitions.contains(
+ ((GraphQLNamedSchemaElement) element).getName()));
final SchemaPrinter.Options options =
SchemaPrinter.Options.defaultOptions()
- .includeScalarTypes(true)
.includeSchemaDefinition(true)
- .includeDirectives(FederationDirectives.allNames::contains)
- .includeSchemaElement(
- element ->
- excludeFedTypeDefinitions.test(element)
- && excludeFedDirectiveDefinitions.test(element));
+ .includeSchemaElement(shouldIncludeSchemaElement);
+
return new SchemaPrinter(options).print(federatedSchema).trim();
}
@@ -130,11 +124,15 @@ public GraphQLFieldDefinition getFieldDefinition(
*/
public static String generateServiceSDLV2(GraphQLSchema schema) {
// federation v2 SDL does not need to filter federation directive definitions
+ final Predicate excludeBuiltInDirectiveDefinitions =
+ element ->
+ !(element instanceof GraphQLDirective
+ && DirectiveInfo.isGraphqlSpecifiedDirective((GraphQLDirective) element));
return new SchemaPrinter(
SchemaPrinter.Options.defaultOptions()
.includeSchemaDefinition(true)
.includeScalarTypes(true)
- .includeDirectives(def -> !STANDARD_DIRECTIVES.contains(def)))
+ .includeSchemaElement(excludeBuiltInDirectiveDefinitions))
.print(schema)
.trim();
}
diff --git a/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FederatedSchemaVerifier.java b/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FederatedSchemaVerifier.java
index a556f983..f6d5cd9e 100644
--- a/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FederatedSchemaVerifier.java
+++ b/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FederatedSchemaVerifier.java
@@ -3,6 +3,7 @@
import static graphql.ExecutionInput.newExecutionInput;
import static graphql.GraphQL.newGraphQL;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -14,15 +15,10 @@
import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLType;
import graphql.schema.idl.SchemaPrinter;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
import org.junit.jupiter.api.Assertions;
final class FederatedSchemaVerifier {
- public static final Set standardDirectives =
- new HashSet<>(Arrays.asList("deprecated", "include", "oneOf", "skip", "specifiedBy"));
private FederatedSchemaVerifier() {}
@@ -35,18 +31,11 @@ static ExecutionResult execute(GraphQLSchema schema, String query) {
*
* @param schema test schema
* @param expectedSchemaSDL expected SDL
- * @param isFederationV2 boolean flag indicating whether we are testing Federation v1 or v2
- * specification.
*/
- public static void verifySchemaSDL(
- GraphQLSchema schema, String expectedSchemaSDL, boolean isFederationV2) {
+ public static void verifyFullSchema(GraphQLSchema schema, String expectedSchemaSDL) {
Assertions.assertEquals(
expectedSchemaSDL.trim(),
- new SchemaPrinter(
- SchemaPrinter.Options.defaultOptions()
- .includeSchemaDefinition(isFederationV2)
- .includeScalarTypes(true)
- .includeDirectives(directive -> !standardDirectives.contains(directive)))
+ new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeSchemaDefinition(true))
.print(schema)
.trim(),
"Generated schema SDL should match expected one");
@@ -64,9 +53,9 @@ public static void verifySchemaContainsServiceFederationType(GraphQLSchema schem
assertNotNull(serviceField, "_service field present");
final GraphQLType serviceType = schema.getType("_Service");
assertNotNull(serviceType, "_Service type present");
- assertTrue(serviceType instanceof GraphQLObjectType, "_Service type is object type");
- assertTrue(
- serviceField.getType() instanceof GraphQLNonNull, "_service returns non-nullable object");
+ assertInstanceOf(GraphQLObjectType.class, serviceType, "_Service type is object type");
+ assertInstanceOf(
+ GraphQLNonNull.class, serviceField.getType(), "_service returns non-nullable object");
final GraphQLNonNull nonNullableServiceType = (GraphQLNonNull) serviceField.getType();
assertEquals(
serviceType,
diff --git a/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FederationTest.java b/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FederationTest.java
index 19d4f79c..01401361 100644
--- a/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FederationTest.java
+++ b/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FederationTest.java
@@ -31,33 +31,33 @@ class FederationTest {
@Test
public void verifyFederationV1Transformation() {
- verifyFederationTransformation("schemas/federationV1.graphql", false);
+ verifyFederationTransformation("schemas/fedV1/schema.graphql");
}
@Test
public void verifyFederationV2Transformation() {
- verifyFederationTransformation("schemas/federationV2.graphql", true);
+ verifyFederationTransformation("schemas/fedV2/schema.graphql");
}
@Test
public void verifyFederationTransformation_subgraphWithoutEntities() {
- verifyFederationTransformation("schemas/subgraphWithoutEntities.graphql", false);
+ verifyFederationTransformation("schemas/noEntities/schema.graphql");
}
@Test
public void verifyFederationTransformation_subgraphWithEntitiesOnly() {
- verifyFederationTransformation("schemas/subgraphWithEntitiesOnly.graphql", false);
+ verifyFederationTransformation("schemas/entitiesOnlySubgraph/schema.graphql");
}
@Test
public void verifyFederationTransformation_nonFederatedSchema_doNotRequireFederatedResolvers() {
- final String schemaSDL = FileUtils.readResource("schemas/subgraphWithoutEntities.graphql");
+ final String schemaSDL = FileUtils.readResource("schemas/noEntities/schema.graphql");
assertDoesNotThrow(() -> Federation.transform(schemaSDL).build());
}
@Test
public void verifyFederationTransformation_noEntityTypeResolver_throwsException() {
- final String schemaSDL = FileUtils.readResource("schemas/federationV2.graphql");
+ final String schemaSDL = FileUtils.readResource("schemas/fedV2/schema.graphql");
assertThrows(
SchemaProblem.class,
() -> Federation.transform(schemaSDL).resolveEntityType(env -> null).build());
@@ -65,7 +65,7 @@ public void verifyFederationTransformation_noEntityTypeResolver_throwsException(
@Test
public void verifyFederationTransformation_noEntitiesDataFetcher_throwsException() {
- final String schemaSDL = FileUtils.readResource("schemas/federationV2.graphql");
+ final String schemaSDL = FileUtils.readResource("schemas/fedV2/schema.graphql");
assertThrows(
SchemaProblem.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -73,7 +73,7 @@ public void verifyFederationTransformation_noEntitiesDataFetcher_throwsException
@Test
public void verifyFederationV2TransformationAndEntityResolution() {
- final String originalSDL = FileUtils.readResource("schemas/federationV2.graphql");
+ final String originalSDL = FileUtils.readResource("schemas/fedV2/schema.graphql");
@SuppressWarnings("rawtypes")
DataFetcher entityDataFetcher =
@@ -136,7 +136,7 @@ public void verifyFederationV2TransformationAndEntityResolution() {
@Test
public void verifyFederationTransformation_noGlobalState() {
// https://github.com/apollographql/federation-jvm/issues/7
- final String sdl = FileUtils.readResource("schemas/federationV2.graphql");
+ final String sdl = FileUtils.readResource("schemas/fedV2/schema.graphql");
final GraphQLSchema first =
Federation.transform(sdl)
.resolveEntityType(env -> null)
@@ -165,43 +165,43 @@ public void verifyFederationV2Transformation_polymorphicTypesMissingKey_throwsEx
MissingKeyException.class,
() ->
verifyFederationTransformation(
- "schemas/polymorphicSubgraphMissingKeys.graphql", runtimeWiring, true));
+ "schemas/invalidPolymorphicSubgraphMissingKeys.graphql", runtimeWiring));
}
@Test
public void verifyWeCannotRenameTagDirective() {
assertThrows(
UnsupportedRenameException.class,
- () -> verifyFederationTransformation("schemas/renamedTagImport.graphql", true));
+ () -> verifyFederationTransformation("schemas/invalidRenameTagImport.graphql"));
}
@Test
public void verifyWeCannotRenameInaccessibleDirective() {
assertThrows(
UnsupportedRenameException.class,
- () -> verifyFederationTransformation("schemas/renamedInaccessibleImport.graphql", true));
+ () -> verifyFederationTransformation("schemas/invalidRenameInaccessibleImport.graphql"));
}
@Test
public void verifyFederationV2Transformation_renames() {
- verifyFederationTransformation("schemas/renamedImports.graphql", true);
+ verifyFederationTransformation("schemas/renamedImports/schema.graphql");
}
@Test
public void verifyFederationV2Transformation_linkOnSchema() {
- verifyFederationTransformation("schemas/schemaImport.graphql", true);
+ verifyFederationTransformation("schemas/schemaImport/schema.graphql");
}
@Test
public void verifyFederationV2Transformation_composeDirective() {
- verifyFederationTransformation("schemas/composeDirective.graphql", true);
+ verifyFederationTransformation("schemas/composeDirective/schema.graphql");
}
@Test
public void
verifyFederationV2Transformation_composeDirectiveFromUnsupportedVersion_throwsException() {
final String schemaSDL =
- FileUtils.readResource("schemas/composeDirectiveUnsupportedSpecVersion.graphql");
+ FileUtils.readResource("schemas/invalidSpecVersionComposeDirective.graphql");
assertThrows(
UnsupportedLinkImportException.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -209,7 +209,7 @@ public void verifyFederationV2Transformation_composeDirective() {
@Test
public void verifyFederationV2Transformation_unknownVersion_throwsException() {
- final String schemaSDL = FileUtils.readResource("schemas/unsupportedSpecVersion.graphql");
+ final String schemaSDL = FileUtils.readResource("schemas/invalidSpecVersion.graphql");
assertThrows(
UnsupportedFederationVersionException.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -217,7 +217,8 @@ public void verifyFederationV2Transformation_unknownVersion_throwsException() {
@Test
public void verifyFederationV2Transformation_multipleFedLinks_throwsException() {
- final String schemaSDL = FileUtils.readResource("schemas/multipleLinks.graphql");
+ final String schemaSDL =
+ FileUtils.readResource("schemas/invalidMultipleFederationLinks.graphql");
assertThrows(
MultipleFederationLinksException.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -225,13 +226,14 @@ public void verifyFederationV2Transformation_multipleFedLinks_throwsException()
@Test
public void verifySchemaCanBeExtended() {
- verifyFederationTransformation("schemas/extendSchema.graphql", true);
+ verifyFederationTransformation("schemas/extendSchema/schema.graphql");
}
@Test
public void
verifyFederationV2Transformation_multipleFedLinksSchemaAndExtension_throwsException() {
- final String schemaSDL = FileUtils.readResource("schemas/multipleSchemaLinks.graphql");
+ final String schemaSDL =
+ FileUtils.readResource("schemas/invalidMultipleFederationSchemaLinks.graphql");
assertThrows(
MultipleFederationLinksException.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -239,14 +241,14 @@ public void verifySchemaCanBeExtended() {
@Test
public void verifyFederationV2Transformation_repeatableShareable() {
- verifyFederationTransformation("schemas/repeatableShareable.graphql", true);
+ verifyFederationTransformation("schemas/repeatableShareable/schema.graphql");
}
@Test
public void
verifyFederationV2Transformation_repeatableShareableFromUnsupportedVersion_throwsException() {
final String schemaSDL =
- FileUtils.readResource("schemas/repeatableShareableUnsupportedVersion.graphql");
+ FileUtils.readResource("schemas/invalidSpecVersionRepeatableShareable.graphql");
assertThrows(
InvalidSchemaException.class,
() ->
@@ -258,14 +260,14 @@ public void verifyFederationV2Transformation_repeatableShareable() {
@Test
public void verifyFederationV2Transformation_interfaceObject() {
- verifyFederationTransformation("schemas/interfaceObject.graphql", true);
+ verifyFederationTransformation("schemas/interfaceObject/schema.graphql");
}
@Test
public void
verifyFederationV2Transformation_interfaceObjectFromUnsupportedVersion_throwsException() {
final String schemaSDL =
- FileUtils.readResource("schemas/interfaceObjectUnsupportedVersion.graphql");
+ FileUtils.readResource("schemas/invalidSpecVersionInterfaceObject.graphql");
assertThrows(
UnsupportedLinkImportException.class,
() ->
@@ -283,36 +285,38 @@ public void verifyFederationV2Transformation_interfaceEntity() {
.type(TypeRuntimeWiring.newTypeWiring("Product").typeResolver(env -> null).build())
.build();
- verifyFederationTransformation("schemas/interfaceEntity.graphql", runtimeWiring, true);
+ verifyFederationTransformation("schemas/interfaceEntity/schema.graphql", runtimeWiring);
}
@Test
public void verifyFederationV2Transformation_nonResolvableKey_doesNotRequireResolvers() {
- final String originalSDL = FileUtils.readResource("schemas/nonResolvableKey.graphql");
+ final String originalSDL = FileUtils.readResource("schemas/nonResolvableKey/schema.graphql");
final RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring().build();
final GraphQLSchema federatedSchema = Federation.transform(originalSDL, runtimeWiring).build();
+ final String expectedFullSchemaSDL =
+ FileUtils.readResource("schemas/nonResolvableKey/schema_full.graphql");
final String expectedFederatedSchemaSDL =
- FileUtils.readResource("schemas/nonResolvableKey_federated.graphql");
- FederatedSchemaVerifier.verifySchemaSDL(federatedSchema, expectedFederatedSchemaSDL, true);
+ FileUtils.readResource("schemas/nonResolvableKey/schema_federated.graphql");
+ FederatedSchemaVerifier.verifyFullSchema(federatedSchema, expectedFullSchemaSDL);
FederatedSchemaVerifier.verifySchemaContainsServiceFederationType(federatedSchema);
FederatedSchemaVerifier.verifyServiceSDL(federatedSchema, expectedFederatedSchemaSDL);
}
@Test
public void verifyFederationV2Transformation_authorization() {
- verifyFederationTransformation("schemas/authorization.graphql", true);
+ verifyFederationTransformation("schemas/authorization/schema.graphql");
}
@Test
public void verifyFederationV2Transformation_customAuthenticated() {
- verifyFederationTransformation("schemas/customAuthenticated.graphql", true);
+ verifyFederationTransformation("schemas/customAuthenticated/schema.graphql");
}
@Test
public void verifyFederationV2Transformation_authorizedFromUnsupportedVersion_throwsException() {
final String schemaSDL =
- FileUtils.readResource("schemas/authenticatedUnsupportedSpecVersion.graphql");
+ FileUtils.readResource("schemas/invalidSpecVersionAuthenticated.graphql");
assertThrows(
UnsupportedLinkImportException.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -320,14 +324,14 @@ public void verifyFederationV2Transformation_authorizedFromUnsupportedVersion_th
@Test
public void verifyFederationV2Transformation_policy() {
- verifyFederationTransformation("schemas/policy.graphql", true);
+ verifyFederationTransformation("schemas/policy/schema.graphql");
}
@Test
public void
verifyFederationV2Transformation_requiresScopesFromUnsupportedVersion_throwsException() {
final String schemaSDL =
- FileUtils.readResource("schemas/requiresScopesUnsupportedSpecVersion.graphql");
+ FileUtils.readResource("schemas/invalidSpecVersionRequiresScopes.graphql");
assertThrows(
UnsupportedLinkImportException.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -335,7 +339,7 @@ public void verifyFederationV2Transformation_policy() {
@Test
public void verifyFederationV2Transformation_policyFromUnsupportedVersion_throwsException() {
- final String schemaSDL = FileUtils.readResource("schemas/policyUnsupportedSpecVersion.graphql");
+ final String schemaSDL = FileUtils.readResource("schemas/invalidSpecVersionPolicy.graphql");
assertThrows(
UnsupportedLinkImportException.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -343,14 +347,14 @@ public void verifyFederationV2Transformation_policyFromUnsupportedVersion_throws
@Test
public void verifyFederationV2Transformation_progressiveOverride() {
- verifyFederationTransformation("schemas/progressiveOverride.graphql", true);
+ verifyFederationTransformation("schemas/progressiveOverride/schema.graphql");
}
@Test
public void
verifyFederationV2Transformation_progressiveOverrideFromUnsupportedVersion_throwsException() {
final String schemaSDL =
- FileUtils.readResource("schemas/progressiveOverrideUnsupportedSpecVersion.graphql");
+ FileUtils.readResource("schemas/invalidSpecVersionProgressiveOverride.graphql");
assertThrows(
SchemaProblem.class,
() -> Federation.transform(schemaSDL).fetchEntities(env -> null).build());
@@ -358,17 +362,25 @@ public void verifyFederationV2Transformation_progressiveOverride() {
@Test
public void verifyFederationV2Transformation_scalarsDefinedInSchemaButNotWired() {
- verifyFederationTransformation("schemas/federationV2_defined_scalars.graphql", true);
+ verifyFederationTransformation("schemas/scalars/schema.graphql");
}
- private GraphQLSchema verifyFederationTransformation(
- String schemaFileName, boolean isFederationV2) {
+ private void verifyFederationTransformation(String schemaFileName) {
final RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring().build();
- return verifyFederationTransformation(schemaFileName, runtimeWiring, isFederationV2);
- }
-
- private GraphQLSchema verifyFederationTransformation(
- String schemaFileName, RuntimeWiring runtimeWiring, boolean isFederationV2) {
+ verifyFederationTransformation(schemaFileName, runtimeWiring);
+ }
+
+ /**
+ * Federate provided GraphQL schema and verifies the transformation.
+ *
+ * Given a path to a schema file, this method assumes there are corresponding `_full` (complete
+ * SDL) and `_federated` (return value from `_service { sdl }` query) schema files that are used
+ * to verify the transformation.
+ *
+ * @param schemaFileName path to a schema file
+ * @param runtimeWiring custom runtime wiring
+ */
+ private void verifyFederationTransformation(String schemaFileName, RuntimeWiring runtimeWiring) {
final String baseFileName = schemaFileName.substring(0, schemaFileName.indexOf(".graphql"));
final String originalSDL = FileUtils.readResource(schemaFileName);
@@ -378,18 +390,12 @@ private GraphQLSchema verifyFederationTransformation(
.fetchEntities(entityFetcher -> null)
.build();
+ final String expectedFullSchemaSDL = FileUtils.readResource(baseFileName + "_full.graphql");
final String expectedFederatedSchemaSDL =
FileUtils.readResource(baseFileName + "_federated.graphql");
- final String expectedServiceSDL;
- if (isFederationV2) {
- expectedServiceSDL = expectedFederatedSchemaSDL;
- } else {
- expectedServiceSDL = FileUtils.readResource(baseFileName + "_serviceSDL.graphql");
- }
- FederatedSchemaVerifier.verifySchemaSDL(
- federatedSchema, expectedFederatedSchemaSDL, isFederationV2);
+
+ FederatedSchemaVerifier.verifyFullSchema(federatedSchema, expectedFullSchemaSDL);
FederatedSchemaVerifier.verifySchemaContainsServiceFederationType(federatedSchema);
- FederatedSchemaVerifier.verifyServiceSDL(federatedSchema, expectedServiceSDL);
- return federatedSchema;
+ FederatedSchemaVerifier.verifyServiceSDL(federatedSchema, expectedFederatedSchemaSDL);
}
}
diff --git a/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FileUtils.java b/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FileUtils.java
index a32f2a59..a27e8c87 100644
--- a/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FileUtils.java
+++ b/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/FileUtils.java
@@ -20,7 +20,7 @@ public static String readResource(String name) {
try (BufferedReader reader =
new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String contents = reader.lines().collect(Collectors.joining(NEW_LINE_SEPARATOR)).trim();
- assert contents.length() > 0;
+ assert !contents.isEmpty();
return contents;
}
} catch (IOException e) {
diff --git a/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/printer/ServiceSDLPrinterTest.java b/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/printer/ServiceSDLPrinterTest.java
index 7a5702d7..3b4e0e23 100644
--- a/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/printer/ServiceSDLPrinterTest.java
+++ b/graphql-java-support/src/test/java/com/apollographql/federation/graphqljava/printer/ServiceSDLPrinterTest.java
@@ -215,7 +215,7 @@ public TraversalControl visitGraphQLFieldDefinition(
final String generatedSDL =
ServiceSDLPrinter.generateServiceSDL(schemaWithAppliedDirectives, false);
- final String expectedSDL = FileUtils.readResource("schemas/federationV1_serviceSDL.graphql");
+ final String expectedSDL = FileUtils.readResource("schemas/fedV1/schema_federated.graphql");
assertEquals(expectedSDL, generatedSDL, "Generated service SDL is the same as expected one");
}
@@ -289,7 +289,7 @@ public TraversalControl visitGraphQLFieldDefinition(
final String generatedSDL =
ServiceSDLPrinter.generateServiceSDL(schemaWithAppliedDirectives, false);
- final String expectedSDL = FileUtils.readResource("schemas/federationV1_serviceSDL.graphql");
+ final String expectedSDL = FileUtils.readResource("schemas/fedV1/schema_federated.graphql");
assertEquals(expectedSDL, generatedSDL, "Generated service SDL is the same as expected one");
}
}
diff --git a/graphql-java-support/src/test/resources/schemas/README.md b/graphql-java-support/src/test/resources/schemas/README.md
new file mode 100644
index 00000000..0beb3f76
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/README.md
@@ -0,0 +1,10 @@
+This directory contains various federation schemas that verify the transformations.
+When creating a new valid (happy path) test case please create a new directory that
+contains
+
+* `schema.graphql` - schema file that will be transformed
+* `schema_full.graphql` - transformed complete GraphQL schema (includes all directive definitions)
+* `schema_federated.graphql` - transformed GraphQL schema returned from `_service { sdl }` query
+
+When creating test cases that verify validations on broken schemas please name your test schema
+with `invalid` prefix.
diff --git a/graphql-java-support/src/test/resources/schemas/authorization.graphql b/graphql-java-support/src/test/resources/schemas/authorization/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/authorization.graphql
rename to graphql-java-support/src/test/resources/schemas/authorization/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/authorization_federated.graphql b/graphql-java-support/src/test/resources/schemas/authorization/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/authorization_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/authorization/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/authorization/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/authorization/schema_full.graphql
new file mode 100644
index 00000000..375a4f30
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/authorization/schema_full.graphql
@@ -0,0 +1,89 @@
+schema @link(import : ["@authenticated", "@key", "@requiresScopes", "Scope", "FieldSet"], url : "https://specs.apollo.dev/federation/v2.5"){
+ query: Query
+}
+
+directive @authenticated on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__composeDirective(name: String!) repeatable on SCHEMA
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__interfaceObject on OBJECT
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: FieldSet!) on FIELD_DEFINITION
+
+directive @federation__shareable repeatable on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @requiresScopes(scopes: [[Scope!]!]!) on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Product
+
+type Product @key(fields : "id", resolvable : true) {
+ id: ID!
+ name: String!
+ supplier: String @requiresScopes(scopes : [["scopeA"]])
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product @authenticated
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar FieldSet
+
+scalar Scope
+
+scalar _Any
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/composeDirective.graphql b/graphql-java-support/src/test/resources/schemas/composeDirective/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/composeDirective.graphql
rename to graphql-java-support/src/test/resources/schemas/composeDirective/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/composeDirective_federated.graphql b/graphql-java-support/src/test/resources/schemas/composeDirective/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/composeDirective_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/composeDirective/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/composeDirective/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/composeDirective/schema_full.graphql
new file mode 100644
index 00000000..5e7f5aa6
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/composeDirective/schema_full.graphql
@@ -0,0 +1,85 @@
+schema @composeDirective(name : "@myDirective") @composeDirective(name : "@hello") @link(import : ["@key", "@composeDirective"], url : "https://specs.apollo.dev/federation/v2.1") @link(import : ["@myDirective", {name : "@anotherDirective", as : "@hello"}], url : "https://myspecs.dev/myDirective/v1.0"){
+ query: Query
+}
+
+directive @composeDirective(name: String!) repeatable on SCHEMA
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__shareable on OBJECT | FIELD_DEFINITION
+
+directive @hello on FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+directive @myDirective(foo: String!) on FIELD_DEFINITION
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Product
+
+type Product @key(fields : "id", resolvable : true) {
+ custom: String @myDirective(foo : "bar")
+ id: ID!
+ name: String! @hello
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/customAuthenticated.graphql b/graphql-java-support/src/test/resources/schemas/customAuthenticated/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/customAuthenticated.graphql
rename to graphql-java-support/src/test/resources/schemas/customAuthenticated/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/customAuthenticated_federated.graphql b/graphql-java-support/src/test/resources/schemas/customAuthenticated/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/customAuthenticated_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/customAuthenticated/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/customAuthenticated/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/customAuthenticated/schema_full.graphql
new file mode 100644
index 00000000..e8062176
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/customAuthenticated/schema_full.graphql
@@ -0,0 +1,91 @@
+schema @link(import : ["@key"], url : "https://specs.apollo.dev/federation/v2.5"){
+ query: Query
+}
+
+directive @authenticated(role: [String!]!) on FIELD_DEFINITION
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__authenticated on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+directive @federation__composeDirective(name: String!) repeatable on SCHEMA
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__interfaceObject on OBJECT
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+directive @federation__shareable repeatable on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Product
+
+type Product @key(fields : "id", resolvable : true) {
+ id: ID!
+ name: String!
+ supplier: String @authenticated(role : ["manager"])
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar federation__Scope
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/subgraphWithEntitiesOnly.graphql b/graphql-java-support/src/test/resources/schemas/entitiesOnlySubgraph/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/subgraphWithEntitiesOnly.graphql
rename to graphql-java-support/src/test/resources/schemas/entitiesOnlySubgraph/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/subgraphWithEntitiesOnly_serviceSDL.graphql b/graphql-java-support/src/test/resources/schemas/entitiesOnlySubgraph/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/subgraphWithEntitiesOnly_serviceSDL.graphql
rename to graphql-java-support/src/test/resources/schemas/entitiesOnlySubgraph/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/entitiesOnlySubgraph/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/entitiesOnlySubgraph/schema_full.graphql
new file mode 100644
index 00000000..8b6461a0
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/entitiesOnlySubgraph/schema_full.graphql
@@ -0,0 +1,65 @@
+schema {
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @extends on OBJECT | INTERFACE
+
+directive @external on FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
+
+directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+union _Entity = Product
+
+type Product @extends @key(fields : "id") {
+ id: ID!
+ reviews: [Review!]!
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+}
+
+type Review {
+ id: ID!
+ text: String!
+}
+
+type _Service {
+ sdl: String!
+}
+
+scalar _Any
+
+scalar _FieldSet
diff --git a/graphql-java-support/src/test/resources/schemas/extendSchema.graphql b/graphql-java-support/src/test/resources/schemas/extendSchema/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/extendSchema.graphql
rename to graphql-java-support/src/test/resources/schemas/extendSchema/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/extendSchema_federated.graphql b/graphql-java-support/src/test/resources/schemas/extendSchema/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/extendSchema_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/extendSchema/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/extendSchema/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/extendSchema/schema_full.graphql
new file mode 100644
index 00000000..a02a2487
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/extendSchema/schema_full.graphql
@@ -0,0 +1,77 @@
+schema @link(import : ["@key"], url : "https://specs.apollo.dev/federation/v2.0"){
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__shareable on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Product
+
+type Product @key(fields : "id", resolvable : true) {
+ id: ID!
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/federationV1.graphql b/graphql-java-support/src/test/resources/schemas/fedV1/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/federationV1.graphql
rename to graphql-java-support/src/test/resources/schemas/fedV1/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/federationV1_serviceSDL.graphql b/graphql-java-support/src/test/resources/schemas/fedV1/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/federationV1_serviceSDL.graphql
rename to graphql-java-support/src/test/resources/schemas/fedV1/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/federationV1_federated.graphql b/graphql-java-support/src/test/resources/schemas/fedV1/schema_full.graphql
similarity index 51%
rename from graphql-java-support/src/test/resources/schemas/federationV1_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/fedV1/schema_full.graphql
index e00dbdac..4b05ce3a 100644
--- a/graphql-java-support/src/test/resources/schemas/federationV1_federated.graphql
+++ b/graphql-java-support/src/test/resources/schemas/fedV1/schema_full.graphql
@@ -1,13 +1,44 @@
+schema {
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
directive @extends on OBJECT | INTERFACE
directive @external on FIELD_DEFINITION
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
union _Entity = Product | User
type Product @key(fields : "id") @key(fields : "sku package") @key(fields : "sku variation { id }") {
diff --git a/graphql-java-support/src/test/resources/schemas/federationV2.graphql b/graphql-java-support/src/test/resources/schemas/fedV2/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/federationV2.graphql
rename to graphql-java-support/src/test/resources/schemas/fedV2/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/federationV2_defined_scalars_federated.graphql b/graphql-java-support/src/test/resources/schemas/fedV2/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/federationV2_defined_scalars_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/fedV2/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/fedV2/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/fedV2/schema_full.graphql
new file mode 100644
index 00000000..db1140a8
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/fedV2/schema_full.graphql
@@ -0,0 +1,131 @@
+schema @composeDirective(name : "@custom") @link(import : ["@composeDirective", "@extends", "@external", "@key", "@inaccessible", "@interfaceObject", "@override", "@provides", "@requires", "@shareable", "@tag"], url : "https://specs.apollo.dev/federation/v2.3") @link(import : ["@custom"], url : "https://myspecs.dev/myCustomDirective/v1.0"){
+ query: Query
+}
+
+directive @composeDirective(name: String!) repeatable on SCHEMA
+
+directive @custom on OBJECT
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @extends on OBJECT | INTERFACE
+
+directive @external on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @interfaceObject on OBJECT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @override(from: String!) on FIELD_DEFINITION
+
+directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @shareable repeatable on OBJECT | FIELD_DEFINITION
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = DeprecatedProduct | Inventory | Product | ProductResearch | User
+
+type CaseStudy {
+ caseNumber: ID!
+ description: String
+}
+
+type DeprecatedProduct @key(fields : "sku package", resolvable : true) {
+ createdBy: User
+ package: String!
+ reason: String
+ sku: String!
+}
+
+type Inventory @interfaceObject @key(fields : "id", resolvable : true) {
+ deprecatedProducts: [DeprecatedProduct!]!
+ id: ID!
+}
+
+type Product @custom @key(fields : "id", resolvable : true) @key(fields : "sku package", resolvable : true) @key(fields : "sku variation { id }", resolvable : true) {
+ createdBy: User @provides(fields : "totalProductsCreated")
+ dimensions: ProductDimension
+ id: ID!
+ notes: String @tag(name : "internal")
+ package: String
+ research: [ProductResearch!]!
+ sku: String
+ variation: ProductVariation
+}
+
+type ProductDimension @shareable {
+ size: String
+ unit: String @inaccessible
+ weight: Float
+}
+
+type ProductResearch @key(fields : "study { caseNumber }", resolvable : true) {
+ outcome: String
+ study: CaseStudy!
+}
+
+type ProductVariation {
+ id: ID!
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ deprecatedProduct(package: String!, sku: String!): DeprecatedProduct @deprecated(reason : "Use product query instead")
+ product(id: ID!): Product
+}
+
+type User @key(fields : "email", resolvable : true) {
+ averageProductsCreatedPerYear: Int @requires(fields : "totalProductsCreated yearsOfEmployment")
+ email: ID! @external
+ name: String @override(from : "users")
+ totalProductsCreated: Int @external
+ yearsOfEmployment: Int! @external
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/interfaceEntity.graphql b/graphql-java-support/src/test/resources/schemas/interfaceEntity/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/interfaceEntity.graphql
rename to graphql-java-support/src/test/resources/schemas/interfaceEntity/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/interfaceEntity_federated.graphql b/graphql-java-support/src/test/resources/schemas/interfaceEntity/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/interfaceEntity_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/interfaceEntity/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/interfaceEntity/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/interfaceEntity/schema_full.graphql
new file mode 100644
index 00000000..63386240
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/interfaceEntity/schema_full.graphql
@@ -0,0 +1,97 @@
+schema @link(import : ["@key"], url : "https://specs.apollo.dev/federation/v2.3"){
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__composeDirective(name: String!) repeatable on SCHEMA
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__interfaceObject on OBJECT
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__shareable repeatable on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+interface Product @key(fields : "id", resolvable : true) {
+ description: String
+ id: ID!
+ price: Float
+}
+
+union _Entity = Book | Movie
+
+type Book implements Product @key(fields : "id", resolvable : true) {
+ description: String
+ id: ID!
+ pages: Int
+ price: Float
+}
+
+type Movie implements Product @key(fields : "id", resolvable : true) {
+ description: String
+ duration: Int
+ id: ID!
+ price: Float
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ products: [Product!]!
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/interfaceObject.graphql b/graphql-java-support/src/test/resources/schemas/interfaceObject/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/interfaceObject.graphql
rename to graphql-java-support/src/test/resources/schemas/interfaceObject/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/interfaceObject_federated.graphql b/graphql-java-support/src/test/resources/schemas/interfaceObject/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/interfaceObject_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/interfaceObject/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/interfaceObject/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/interfaceObject/schema_full.graphql
new file mode 100644
index 00000000..b8d32aba
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/interfaceObject/schema_full.graphql
@@ -0,0 +1,82 @@
+schema @link(import : ["@key", "@interfaceObject"], url : "https://specs.apollo.dev/federation/v2.3"){
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__composeDirective(name: String!) repeatable on SCHEMA
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__shareable repeatable on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @interfaceObject on OBJECT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Product
+
+type Product @interfaceObject @key(fields : "id", resolvable : true) {
+ id: ID!
+ name: String!
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/multipleLinks.graphql b/graphql-java-support/src/test/resources/schemas/invalidMultipleFederationLinks.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/multipleLinks.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidMultipleFederationLinks.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/multipleSchemaLinks.graphql b/graphql-java-support/src/test/resources/schemas/invalidMultipleFederationSchemaLinks.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/multipleSchemaLinks.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidMultipleFederationSchemaLinks.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/polymorphicSubgraphMissingKeys.graphql b/graphql-java-support/src/test/resources/schemas/invalidPolymorphicSubgraphMissingKeys.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/polymorphicSubgraphMissingKeys.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidPolymorphicSubgraphMissingKeys.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/renamedInaccessibleImport.graphql b/graphql-java-support/src/test/resources/schemas/invalidRenameInaccessibleImport.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/renamedInaccessibleImport.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidRenameInaccessibleImport.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/renamedTagImport.graphql b/graphql-java-support/src/test/resources/schemas/invalidRenameTagImport.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/renamedTagImport.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidRenameTagImport.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/unsupportedSpecVersion.graphql b/graphql-java-support/src/test/resources/schemas/invalidSpecVersion.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/unsupportedSpecVersion.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidSpecVersion.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/authenticatedUnsupportedSpecVersion.graphql b/graphql-java-support/src/test/resources/schemas/invalidSpecVersionAuthenticated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/authenticatedUnsupportedSpecVersion.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidSpecVersionAuthenticated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/composeDirectiveUnsupportedSpecVersion.graphql b/graphql-java-support/src/test/resources/schemas/invalidSpecVersionComposeDirective.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/composeDirectiveUnsupportedSpecVersion.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidSpecVersionComposeDirective.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/interfaceObjectUnsupportedVersion.graphql b/graphql-java-support/src/test/resources/schemas/invalidSpecVersionInterfaceObject.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/interfaceObjectUnsupportedVersion.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidSpecVersionInterfaceObject.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/policyUnsupportedSpecVersion.graphql b/graphql-java-support/src/test/resources/schemas/invalidSpecVersionPolicy.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/policyUnsupportedSpecVersion.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidSpecVersionPolicy.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/progressiveOverrideUnsupportedSpecVersion.graphql b/graphql-java-support/src/test/resources/schemas/invalidSpecVersionProgressiveOverride.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/progressiveOverrideUnsupportedSpecVersion.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidSpecVersionProgressiveOverride.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/repeatableShareableUnsupportedVersion.graphql b/graphql-java-support/src/test/resources/schemas/invalidSpecVersionRepeatableShareable.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/repeatableShareableUnsupportedVersion.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidSpecVersionRepeatableShareable.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/requiresScopesUnsupportedSpecVersion.graphql b/graphql-java-support/src/test/resources/schemas/invalidSpecVersionRequiresScopes.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/requiresScopesUnsupportedSpecVersion.graphql
rename to graphql-java-support/src/test/resources/schemas/invalidSpecVersionRequiresScopes.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/noEntities/schema.graphql b/graphql-java-support/src/test/resources/schemas/noEntities/schema.graphql
new file mode 100644
index 00000000..4f8c2d0d
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/noEntities/schema.graphql
@@ -0,0 +1,8 @@
+type Query {
+ product(id: ID!): Product
+}
+
+type Product {
+ id: ID!
+ name: String
+}
diff --git a/graphql-java-support/src/test/resources/schemas/subgraphWithoutEntities_serviceSDL.graphql b/graphql-java-support/src/test/resources/schemas/noEntities/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/subgraphWithoutEntities_serviceSDL.graphql
rename to graphql-java-support/src/test/resources/schemas/noEntities/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/noEntities/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/noEntities/schema_full.graphql
new file mode 100644
index 00000000..6cf50d15
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/noEntities/schema_full.graphql
@@ -0,0 +1,56 @@
+schema {
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @extends on OBJECT | INTERFACE
+
+directive @external on FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
+
+directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+type Product {
+ id: ID!
+ name: String
+}
+
+type Query {
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type _Service {
+ sdl: String!
+}
+
+scalar _FieldSet
diff --git a/graphql-java-support/src/test/resources/schemas/nonResolvableKey.graphql b/graphql-java-support/src/test/resources/schemas/nonResolvableKey/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/nonResolvableKey.graphql
rename to graphql-java-support/src/test/resources/schemas/nonResolvableKey/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/nonResolvableKey_federated.graphql b/graphql-java-support/src/test/resources/schemas/nonResolvableKey/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/nonResolvableKey_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/nonResolvableKey/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/nonResolvableKey/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/nonResolvableKey/schema_full.graphql
new file mode 100644
index 00000000..391a5838
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/nonResolvableKey/schema_full.graphql
@@ -0,0 +1,87 @@
+schema @link(import : ["@key"], url : "https://specs.apollo.dev/federation/v2.3"){
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__composeDirective(name: String!) repeatable on SCHEMA
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__interfaceObject on OBJECT
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__shareable repeatable on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = User
+
+type Product {
+ createdBy: User
+ description: String!
+ id: ID!
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type User @key(fields : "email", resolvable : false) {
+ email: ID!
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/policy.graphql b/graphql-java-support/src/test/resources/schemas/policy/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/policy.graphql
rename to graphql-java-support/src/test/resources/schemas/policy/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/policy_federated.graphql b/graphql-java-support/src/test/resources/schemas/policy/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/policy_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/policy/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/policy/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/policy/schema_full.graphql
new file mode 100644
index 00000000..40efe557
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/policy/schema_full.graphql
@@ -0,0 +1,93 @@
+schema @link(import : ["@key", "@policy", "Policy", "FieldSet"], url : "https://specs.apollo.dev/federation/v2.6"){
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__authenticated on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+directive @federation__composeDirective(name: String!) repeatable on SCHEMA
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__interfaceObject on OBJECT
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+directive @federation__shareable repeatable on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @policy(policies: [[Policy!]!]!) on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Product
+
+type Product @key(fields : "id", resolvable : true) {
+ id: ID!
+ name: String!
+ supplier: String @policy(policies : [["policyA"]])
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar FieldSet
+
+scalar Policy
+
+scalar _Any
+
+scalar federation__Scope
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/progressiveOverride.graphql b/graphql-java-support/src/test/resources/schemas/progressiveOverride/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/progressiveOverride.graphql
rename to graphql-java-support/src/test/resources/schemas/progressiveOverride/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/progressiveOverride_federated.graphql b/graphql-java-support/src/test/resources/schemas/progressiveOverride/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/progressiveOverride_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/progressiveOverride/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/progressiveOverride/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/progressiveOverride/schema_full.graphql
new file mode 100644
index 00000000..6f8baaaa
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/progressiveOverride/schema_full.graphql
@@ -0,0 +1,92 @@
+schema @link(import : ["@authenticated", "@composeDirective", "@extends", "@external", "@inaccessible", "@interfaceObject", "@key", "@override", "@policy", "@provides", "@requires", "@requiresScopes", "@shareable", "@tag", "FieldSet", "Import", "Policy", "Scope"], url : "https://specs.apollo.dev/federation/v2.7"){
+ query: Query
+}
+
+directive @authenticated on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+directive @composeDirective(name: String!) repeatable on SCHEMA
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @extends on OBJECT | INTERFACE
+
+directive @external on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @interfaceObject on OBJECT
+
+directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @override(from: String!, label: String) on FIELD_DEFINITION
+
+directive @policy(policies: [[Policy!]!]!) on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+directive @provides(fields: FieldSet!) on FIELD_DEFINITION
+
+directive @requires(fields: FieldSet!) on FIELD_DEFINITION
+
+directive @requiresScopes(scopes: [[Scope!]!]!) on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
+
+directive @shareable repeatable on OBJECT | FIELD_DEFINITION
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Product
+
+type Product @key(fields : "id", resolvable : true) {
+ id: ID!
+ name: String! @override(from : "old-product-service", label : "percent(5)")
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar FieldSet
+
+scalar Import
+
+scalar Policy
+
+scalar Scope
+
+scalar _Any
diff --git a/graphql-java-support/src/test/resources/schemas/renamedImports.graphql b/graphql-java-support/src/test/resources/schemas/renamedImports/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/renamedImports.graphql
rename to graphql-java-support/src/test/resources/schemas/renamedImports/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/renamedImports_federated.graphql b/graphql-java-support/src/test/resources/schemas/renamedImports/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/renamedImports_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/renamedImports/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/renamedImports/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/renamedImports/schema_full.graphql
new file mode 100644
index 00000000..c5ccbada
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/renamedImports/schema_full.graphql
@@ -0,0 +1,94 @@
+schema @link(import : [{name : "@key", as : "@myKey"}, {name : "@shareable"}, "@provides", "@external", "@tag", "@extends", "@override", "@inaccessible"], url : "https://specs.apollo.dev/federation/v2.0"){
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @extends on OBJECT | INTERFACE
+
+directive @external on OBJECT | FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+directive @myKey(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @override(from: String!) on FIELD_DEFINITION
+
+directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @shareable on OBJECT | FIELD_DEFINITION
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+type Product @myKey(fields : "id", resolvable : true) @myKey(fields : "sku package", resolvable : true) @myKey(fields : "sku variation { id }", resolvable : true) {
+ createdBy: User @provides(fields : "totalProductsCreated")
+ dimensions: ProductDimension
+ id: ID!
+ notes: String @tag(name : "internal")
+ package: String
+ sku: String
+ variation: ProductVariation
+}
+
+type ProductDimension @shareable {
+ size: String
+ unit: String @inaccessible
+ weight: Float
+}
+
+type ProductVariation {
+ id: ID!
+}
+
+type Query {
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type User @myKey(fields : "email", resolvable : true) {
+ email: ID!
+ name: String @override(from : "users") @shareable
+ totalProductsCreated: Int @external
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/repeatableShareable.graphql b/graphql-java-support/src/test/resources/schemas/repeatableShareable/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/repeatableShareable.graphql
rename to graphql-java-support/src/test/resources/schemas/repeatableShareable/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/repeatableShareable_federated.graphql b/graphql-java-support/src/test/resources/schemas/repeatableShareable/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/repeatableShareable_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/repeatableShareable/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/repeatableShareable/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/repeatableShareable/schema_full.graphql
new file mode 100644
index 00000000..04e1628c
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/repeatableShareable/schema_full.graphql
@@ -0,0 +1,87 @@
+schema @link(import : ["@key", "@shareable"], url : "https://specs.apollo.dev/federation/v2.2"){
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__composeDirective(name: String!) repeatable on SCHEMA
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @shareable repeatable on OBJECT | FIELD_DEFINITION
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Product
+
+type Position @shareable @shareable {
+ x: Float!
+ y: Float!
+ z: Float!
+}
+
+type Product @key(fields : "id", resolvable : true) {
+ id: ID!
+ name: String!
+ position: Position
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ product(id: ID!): Product
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/federationV2_defined_scalars.graphql b/graphql-java-support/src/test/resources/schemas/scalars/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/federationV2_defined_scalars.graphql
rename to graphql-java-support/src/test/resources/schemas/scalars/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/federationV2_federated.graphql b/graphql-java-support/src/test/resources/schemas/scalars/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/federationV2_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/scalars/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/scalars/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/scalars/schema_full.graphql
new file mode 100644
index 00000000..db1140a8
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/scalars/schema_full.graphql
@@ -0,0 +1,131 @@
+schema @composeDirective(name : "@custom") @link(import : ["@composeDirective", "@extends", "@external", "@key", "@inaccessible", "@interfaceObject", "@override", "@provides", "@requires", "@shareable", "@tag"], url : "https://specs.apollo.dev/federation/v2.3") @link(import : ["@custom"], url : "https://myspecs.dev/myCustomDirective/v1.0"){
+ query: Query
+}
+
+directive @composeDirective(name: String!) repeatable on SCHEMA
+
+directive @custom on OBJECT
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @extends on OBJECT | INTERFACE
+
+directive @external on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @interfaceObject on OBJECT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+directive @override(from: String!) on FIELD_DEFINITION
+
+directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @shareable repeatable on OBJECT | FIELD_DEFINITION
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = DeprecatedProduct | Inventory | Product | ProductResearch | User
+
+type CaseStudy {
+ caseNumber: ID!
+ description: String
+}
+
+type DeprecatedProduct @key(fields : "sku package", resolvable : true) {
+ createdBy: User
+ package: String!
+ reason: String
+ sku: String!
+}
+
+type Inventory @interfaceObject @key(fields : "id", resolvable : true) {
+ deprecatedProducts: [DeprecatedProduct!]!
+ id: ID!
+}
+
+type Product @custom @key(fields : "id", resolvable : true) @key(fields : "sku package", resolvable : true) @key(fields : "sku variation { id }", resolvable : true) {
+ createdBy: User @provides(fields : "totalProductsCreated")
+ dimensions: ProductDimension
+ id: ID!
+ notes: String @tag(name : "internal")
+ package: String
+ research: [ProductResearch!]!
+ sku: String
+ variation: ProductVariation
+}
+
+type ProductDimension @shareable {
+ size: String
+ unit: String @inaccessible
+ weight: Float
+}
+
+type ProductResearch @key(fields : "study { caseNumber }", resolvable : true) {
+ outcome: String
+ study: CaseStudy!
+}
+
+type ProductVariation {
+ id: ID!
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ deprecatedProduct(package: String!, sku: String!): DeprecatedProduct @deprecated(reason : "Use product query instead")
+ product(id: ID!): Product
+}
+
+type User @key(fields : "email", resolvable : true) {
+ averageProductsCreatedPerYear: Int @requires(fields : "totalProductsCreated yearsOfEmployment")
+ email: ID! @external
+ name: String @override(from : "users")
+ totalProductsCreated: Int @external
+ yearsOfEmployment: Int! @external
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/schemaImport.graphql b/graphql-java-support/src/test/resources/schemas/schemaImport/schema.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/schemaImport.graphql
rename to graphql-java-support/src/test/resources/schemas/schemaImport/schema.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/schemaImport_federated.graphql b/graphql-java-support/src/test/resources/schemas/schemaImport/schema_federated.graphql
similarity index 100%
rename from graphql-java-support/src/test/resources/schemas/schemaImport_federated.graphql
rename to graphql-java-support/src/test/resources/schemas/schemaImport/schema_federated.graphql
diff --git a/graphql-java-support/src/test/resources/schemas/schemaImport/schema_full.graphql b/graphql-java-support/src/test/resources/schemas/schemaImport/schema_full.graphql
new file mode 100644
index 00000000..d242509a
--- /dev/null
+++ b/graphql-java-support/src/test/resources/schemas/schemaImport/schema_full.graphql
@@ -0,0 +1,78 @@
+schema @link(import : ["@key"], url : "https://specs.apollo.dev/federation/v2.0"){
+ query: Query
+}
+
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+directive @federation__extends on OBJECT | INTERFACE
+
+directive @federation__external on OBJECT | FIELD_DEFINITION
+
+directive @federation__override(from: String!) on FIELD_DEFINITION
+
+directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION
+
+directive @federation__shareable on OBJECT | FIELD_DEFINITION
+
+directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
+
+directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA
+
+"Indicates an Input Object is a OneOf Input Object."
+directive @oneOf on INPUT_OBJECT
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+directive @tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
+
+union _Entity = Foo
+
+type Foo @key(fields : "id", resolvable : true) {
+ id: ID!
+ name: String!
+}
+
+type Query {
+ _entities(representations: [_Any!]!): [_Entity]!
+ _service: _Service!
+ foo(id: ID!): Foo
+}
+
+type _Service {
+ sdl: String!
+}
+
+enum link__Purpose {
+ EXECUTION
+ SECURITY
+}
+
+scalar _Any
+
+scalar federation__FieldSet
+
+scalar link__Import
diff --git a/graphql-java-support/src/test/resources/schemas/subgraphWithEntitiesOnly_federated.graphql b/graphql-java-support/src/test/resources/schemas/subgraphWithEntitiesOnly_federated.graphql
deleted file mode 100644
index 7d095ac1..00000000
--- a/graphql-java-support/src/test/resources/schemas/subgraphWithEntitiesOnly_federated.graphql
+++ /dev/null
@@ -1,34 +0,0 @@
-directive @extends on OBJECT | INTERFACE
-
-directive @external on FIELD_DEFINITION
-
-directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
-
-directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
-
-directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
-
-union _Entity = Product
-
-type Product @extends @key(fields : "id") {
- id: ID!
- reviews: [Review!]!
-}
-
-type Query {
- _entities(representations: [_Any!]!): [_Entity]!
- _service: _Service!
-}
-
-type Review {
- id: ID!
- text: String!
-}
-
-type _Service {
- sdl: String!
-}
-
-scalar _Any
-
-scalar _FieldSet
diff --git a/graphql-java-support/src/test/resources/schemas/subgraphWithoutEntities.graphql b/graphql-java-support/src/test/resources/schemas/subgraphWithoutEntities.graphql
deleted file mode 100644
index ab2f54dd..00000000
--- a/graphql-java-support/src/test/resources/schemas/subgraphWithoutEntities.graphql
+++ /dev/null
@@ -1,8 +0,0 @@
-type Query {
- product(id: ID!): Product
-}
-
-type Product {
- id: ID!
- name: String
-}
diff --git a/graphql-java-support/src/test/resources/schemas/subgraphWithoutEntities_federated.graphql b/graphql-java-support/src/test/resources/schemas/subgraphWithoutEntities_federated.graphql
deleted file mode 100644
index c09b0774..00000000
--- a/graphql-java-support/src/test/resources/schemas/subgraphWithoutEntities_federated.graphql
+++ /dev/null
@@ -1,25 +0,0 @@
-directive @extends on OBJECT | INTERFACE
-
-directive @external on FIELD_DEFINITION
-
-directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
-
-directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
-
-directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
-
-type Product {
- id: ID!
- name: String
-}
-
-type Query {
- _service: _Service!
- product(id: ID!): Product
-}
-
-type _Service {
- sdl: String!
-}
-
-scalar _FieldSet
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 989efd1b..040a2883 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,7 +1,9 @@
rootProject.name = "federation-jvm"
include(":federation-graphql-java-support")
-include(":federation-spring-subscription-callback")
+// TODO: disabling spring-subscription-callback module until Spring Boot 3.3 is released
+//include(":federation-spring-subscription-callback")
project(":federation-graphql-java-support").projectDir = file("graphql-java-support")
-project(":federation-spring-subscription-callback").projectDir = file("spring-subscription-callback")
+// TODO: disabling spring-subscription-callback module until Spring Boot 3.3 is released
+//project(":federation-spring-subscription-callback").projectDir = file("spring-subscription-callback")
diff --git a/spring-subscription-callback/build.gradle.kts b/spring-subscription-callback/build.gradle.kts
index f3d95138..78971fca 100644
--- a/spring-subscription-callback/build.gradle.kts
+++ b/spring-subscription-callback/build.gradle.kts
@@ -15,7 +15,9 @@ dependencies {
compileOnly("org.jetbrains", "annotations", annotationsVersion)
implementation("com.graphql-java", "graphql-java", graphQLJavaVersion)
implementation("org.slf4j", "slf4j-api", slf4jVersion)
- implementation("org.springframework.boot", "spring-boot-starter-graphql", springBootVersion)
+ implementation("org.springframework.boot", "spring-boot-starter-graphql", springBootVersion) {
+ exclude(group = "com.graphql-java", module = "graphql-java")
+ }
implementation("org.springframework.boot", "spring-boot-starter-web", springBootVersion)
implementation("org.springframework.boot", "spring-boot-starter-webflux", springBootVersion)
testCompileOnly("org.jetbrains", "annotations", annotationsVersion)