Allow configuring schema through GraphQlSource customizer
As of gh-117, the GraphQlAutoConfiguration throws an exception if no schema file was found while scanning configured locations. This prevents developers from manually configuring the schema using `GraphQlSourceBuilderCustomizer` instances. This commit ensures that a `MissingSchemaException` is only raised if no schema was configured at the time we're building the actual GraphQlSource. This exception is later wrapped by the GraphQlAutoConfiguration to raise an `InvalidSchemaLocationsException` with useful information about configured schema locations. Fixes gh-124
This commit is contained in:
@@ -38,6 +38,7 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.graphql.execution.DataFetcherExceptionResolver;
|
||||
import org.springframework.graphql.execution.GraphQlSource;
|
||||
import org.springframework.graphql.execution.MissingSchemaException;
|
||||
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
|
||||
|
||||
/**
|
||||
@@ -71,7 +72,12 @@ public class GraphQlAutoConfiguration {
|
||||
.instrumentation(instrumentationsProvider.orderedStream().collect(Collectors.toList()));
|
||||
wiringConfigurers.orderedStream().forEach(builder::configureRuntimeWiring);
|
||||
sourceCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
|
||||
return builder.build();
|
||||
try {
|
||||
return builder.build();
|
||||
}
|
||||
catch (MissingSchemaException exc) {
|
||||
throw new InvalidSchemaLocationsException(properties.getSchema().getLocations(), resourcePatternResolver, exc);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Resource> resolveSchemaResources(ResourcePatternResolver resolver, List<String> schemaLocations) throws IOException {
|
||||
@@ -86,9 +92,6 @@ public class GraphQlAutoConfiguration {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (schemaResources.isEmpty()) {
|
||||
throw new MissingSchemaException(schemaLocations, resolver);
|
||||
}
|
||||
return schemaResources;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,18 +21,25 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
|
||||
/**
|
||||
* {@link MissingSchemaException} thrown when no schema can be found in the provided locations.
|
||||
* {@link InvalidSchemaLocationsException} thrown when no schema file could be found in the provided locations.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class MissingSchemaException extends RuntimeException {
|
||||
public class InvalidSchemaLocationsException extends NestedRuntimeException {
|
||||
|
||||
private final List<SchemaLocation> schemaLocations;
|
||||
|
||||
public MissingSchemaException(List<String> locations, ResourcePatternResolver resolver) {
|
||||
public InvalidSchemaLocationsException(List<String> locations, ResourcePatternResolver resolver) {
|
||||
this(locations, resolver, null);
|
||||
}
|
||||
|
||||
public InvalidSchemaLocationsException(List<String> locations, ResourcePatternResolver resolver, Throwable cause) {
|
||||
super("No schema file could be found in the provided locations.", cause);
|
||||
List<SchemaLocation> providedLocations = new ArrayList<>();
|
||||
for (String location : locations) {
|
||||
try {
|
||||
@@ -21,17 +21,17 @@ import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||
|
||||
/**
|
||||
* An implementation of {@link AbstractFailureAnalyzer} to analyze failures caused by
|
||||
* {@link MissingSchemaException}.
|
||||
* {@link InvalidSchemaLocationsException}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class MissingSchemaExceptionFailureAnalyzer extends AbstractFailureAnalyzer<MissingSchemaException> {
|
||||
class InvalidSchemaLocationsExceptionFailureAnalyzer extends AbstractFailureAnalyzer<InvalidSchemaLocationsException> {
|
||||
|
||||
@Override
|
||||
protected FailureAnalysis analyze(Throwable rootFailure, MissingSchemaException cause) {
|
||||
protected FailureAnalysis analyze(Throwable rootFailure, InvalidSchemaLocationsException cause) {
|
||||
String message = "Could not find any GraphQL schema file under configured locations.";
|
||||
StringBuilder action = new StringBuilder("Check that the following locations contain schema files: " + System.lineSeparator());
|
||||
for (MissingSchemaException.SchemaLocation schemaLocation : cause.getSchemaLocations()) {
|
||||
for (InvalidSchemaLocationsException.SchemaLocation schemaLocation : cause.getSchemaLocations()) {
|
||||
action.append(String.format("- '%s' (%s)" + System.lineSeparator(), schemaLocation.getUri(), schemaLocation.getLocation()));
|
||||
}
|
||||
return new FailureAnalysis(message, action.toString(), cause);
|
||||
@@ -11,7 +11,7 @@ org.springframework.graphql.boot.data.GraphQlWebFluxQuerydslAutoConfiguration
|
||||
|
||||
# Failure Analyzers
|
||||
org.springframework.boot.diagnostics.FailureAnalyzer=\
|
||||
org.springframework.graphql.boot.MissingSchemaExceptionFailureAnalyzer
|
||||
org.springframework.graphql.boot.InvalidSchemaLocationsExceptionFailureAnalyzer
|
||||
|
||||
# Spring Test @AutoConfigureGraphQlTester
|
||||
org.springframework.graphql.boot.test.tester.AutoConfigureGraphQlTester=\
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.graphql.execution.GraphQlSource;
|
||||
import org.springframework.graphql.execution.MissingSchemaException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user