From f69aa39211c27ebc89e9534555d30bb7e76c42d3 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 20 Sep 2021 10:29:41 +0200 Subject: [PATCH] Only scan for *.graphqls and *.gqls schema files Prior to this commit, the auto-configuration was scanning for `"*.graphql,*.gql,*.graphqls,*.gqls"` files in the configured locations. This was not flexible enough, as developers could not customize the considered file extensions when scanning for files. This commit provides a new `spring.graphql.schema.file-extensions` configuration property that enables such customizations. Because `"*.graphql,*.gql"` extensions seem to be tied to queries (and not schemas), this commit also changes the default value to only consider the `"*.graphqls,*.gqls"` file extensions by default. Closes gh-134 Closes gh-135 --- .../boot/GraphQlAutoConfiguration.java | 14 ++++---- .../graphql/boot/GraphQlProperties.java | 33 ++++++++++++------- .../boot/InvalidSchemaLocationsException.java | 4 +-- ...itional-spring-configuration-metadata.json | 4 +++ .../boot/GraphQlAutoConfigurationTests.java | 3 +- .../src/main/resources/application.properties | 4 ++- 6 files changed, 40 insertions(+), 22 deletions(-) diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlAutoConfiguration.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlAutoConfiguration.java index 88e5b3b6..21263cdc 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlAutoConfiguration.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlAutoConfiguration.java @@ -56,8 +56,6 @@ public class GraphQlAutoConfiguration { private static final Log logger = LogFactory.getLog(GraphQlAutoConfiguration.class); - private static final String[] SCHEMA_FILES_EXTENSIONS = new String[] {"*.graphqls", "*.graphql", "*.gql", "*.gqls"}; - @Bean public GraphQlSource graphQlSource(ResourcePatternResolver resourcePatternResolver, GraphQlProperties properties, ObjectProvider exceptionResolversProvider, @@ -65,7 +63,8 @@ public class GraphQlAutoConfiguration { ObjectProvider sourceCustomizers, ObjectProvider wiringConfigurers) throws IOException { - List schemaResources = resolveSchemaResources(resourcePatternResolver, properties.getSchema().getLocations()); + List schemaResources = resolveSchemaResources(resourcePatternResolver, properties.getSchema().getLocations(), + properties.getSchema().getFileExtensions()); GraphQlSource.Builder builder = GraphQlSource.builder() .schemaResources(schemaResources.toArray(new Resource[0])) .exceptionResolvers(exceptionResolversProvider.orderedStream().collect(Collectors.toList())) @@ -80,15 +79,16 @@ public class GraphQlAutoConfiguration { } } - private List resolveSchemaResources(ResourcePatternResolver resolver, List schemaLocations) throws IOException { + private List resolveSchemaResources(ResourcePatternResolver resolver, String[] schemaLocations, String[] fileExtensions) { List schemaResources = new ArrayList<>(); for (String location : schemaLocations) { - for (String extension : SCHEMA_FILES_EXTENSIONS) { + for (String extension : fileExtensions) { + String resourcePattern = location + "*" + extension; try { - schemaResources.addAll(Arrays.asList(resolver.getResources(location + extension))); + schemaResources.addAll(Arrays.asList(resolver.getResources(resourcePattern))); } catch (IOException ex) { - logger.debug("Could not resolve schema location: '" + location + extension + "'", ex); + logger.debug("Could not resolve schema location: '" + resourcePattern + "'", ex); } } } diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlProperties.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlProperties.java index 91ce87f3..eade0dd7 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlProperties.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/GraphQlProperties.java @@ -17,10 +17,7 @@ package org.springframework.graphql.boot; import java.time.Duration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; +import java.util.Arrays; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -67,24 +64,38 @@ public class GraphQlProperties { public static class Schema { /** - * Locations of GraphQL '*.graphqls' schema files. + * Locations of GraphQL schema files. */ - private List locations = new ArrayList<>(Collections.singletonList("classpath:graphql/")); + private String[] locations = new String[] { "classpath:graphql/"}; + + /** + * File extensions for GraphQL schema files. + */ + private String[] fileExtensions = new String[] { ".graphqls", ".gqls"}; + private final Printer printer = new Printer(); - public List getLocations() { + public String[] getLocations() { return this.locations; } - public void setLocations(List locations) { + public void setLocations(String[] locations) { this.locations = appendSlashIfNecessary(locations); } - private List appendSlashIfNecessary(List locations) { - return locations.stream() + public String[] getFileExtensions() { + return this.fileExtensions; + } + + public void setFileExtensions(String[] fileExtensions) { + this.fileExtensions = fileExtensions; + } + + private String[] appendSlashIfNecessary(String[] locations) { + return Arrays.stream(locations) .map(location -> location.endsWith("/") ? location : location + "/") - .collect(Collectors.toList()); + .toArray(String[]::new); } public Printer getPrinter() { diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsException.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsException.java index 36eed819..5bec2d89 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsException.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/InvalidSchemaLocationsException.java @@ -35,11 +35,11 @@ public class InvalidSchemaLocationsException extends NestedRuntimeException { private final List schemaLocations; - public InvalidSchemaLocationsException(List locations, ResourcePatternResolver resolver) { + public InvalidSchemaLocationsException(String[] locations, ResourcePatternResolver resolver) { this(locations, resolver, null); } - public InvalidSchemaLocationsException(List locations, ResourcePatternResolver resolver, Throwable cause) { + public InvalidSchemaLocationsException(String[] locations, ResourcePatternResolver resolver, Throwable cause) { super("No schema file could be found in the provided locations.", cause); List providedLocations = new ArrayList<>(); for (String location : locations) { diff --git a/graphql-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/graphql-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json index cf2de433..8ad70484 100644 --- a/graphql-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/graphql-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -4,6 +4,10 @@ "name": "spring.graphql.schema.locations", "defaultValue": "classpath:graphql/" }, + { + "name": "spring.graphql.schema.file-extensions", + "defaultValue": ".graphqls,.gqls" + }, { "name": "management.metrics.graphql.autotime.enabled", "description": "Whether to automatically time graphql requests.", diff --git a/graphql-spring-boot-starter/src/test/java/org/springframework/graphql/boot/GraphQlAutoConfigurationTests.java b/graphql-spring-boot-starter/src/test/java/org/springframework/graphql/boot/GraphQlAutoConfigurationTests.java index 5f47a0b5..eb0fd1ac 100644 --- a/graphql-spring-boot-starter/src/test/java/org/springframework/graphql/boot/GraphQlAutoConfigurationTests.java +++ b/graphql-spring-boot-starter/src/test/java/org/springframework/graphql/boot/GraphQlAutoConfigurationTests.java @@ -62,7 +62,8 @@ class GraphQlAutoConfigurationTests { @Test void shouldScanLocationsForSchemaFiles() { - this.contextRunner.withPropertyValues("spring.graphql.schema.locations:classpath:schema/") + this.contextRunner.withPropertyValues("spring.graphql.schema.locations:classpath:schema/", + "spring.graphql.schema.file-extensions:.gql,.gqls,.graphql,.graphqls") .run((context) -> { assertThat(context).hasSingleBean(GraphQlSource.class); GraphQlSource graphQlSource = context.getBean(GraphQlSource.class); diff --git a/samples/webmvc-http/src/main/resources/application.properties b/samples/webmvc-http/src/main/resources/application.properties index 28e043a8..d31504ed 100644 --- a/samples/webmvc-http/src/main/resources/application.properties +++ b/samples/webmvc-http/src/main/resources/application.properties @@ -1,3 +1,5 @@ management.endpoints.web.exposure.include=health,metrics,info -spring.graphql.schema.printer.enabled=true \ No newline at end of file +spring.graphql.schema.printer.enabled=true + +spring.graph \ No newline at end of file