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)