Refine GraphQL server auto-configuration
Prior to this commit, launching a GraphQL application without any schema file or customizer bean would result in an exception caught by a FailureAnalyzer telling the developer about configured locations. Since then, a new client has been introduced in Spring GraphQL and the mere presence of the GraphQL starter does not mean anymore that the intent is to create a GraphQL API in the app: we could instead just consume an existing, remote API. This commit refines the GraphQL server auto-configuration so that it is enabled only if: * there is at least one schema file in the configured locations * or a `GraphQlSourceCustomizer` bean has been defined in the app These changes make the custom FailureAnalyzer useless and is also removed as part of this commit. Closes gh-30035pull/30406/head
parent
bf79d6baef
commit
087e853c5d
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.graphql;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
|
||||
/**
|
||||
* {@link Conditional @Conditional} that only matches when a GraphQL schema is defined for
|
||||
* the application, via schema files or infrastructure beans.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.7.0
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Conditional(DefaultGraphQlSchemaCondition.class)
|
||||
public @interface ConditionalOnGraphQlSchema {
|
||||
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.graphql;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.ConfigurationCondition;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
/**
|
||||
* {@link Condition} that checks whether a GraphQL schema has been defined in the
|
||||
* application. This is looking for:
|
||||
* <ul>
|
||||
* <li>schema files in the {@link GraphQlProperties configured locations}</li>
|
||||
* <li>or infrastructure beans such as {@link GraphQlSourceBuilderCustomizer}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @see ConditionalOnGraphQlSchema
|
||||
*/
|
||||
class DefaultGraphQlSchemaCondition extends SpringBootCondition implements ConfigurationCondition {
|
||||
|
||||
@Override
|
||||
public ConfigurationCondition.ConfigurationPhase getConfigurationPhase() {
|
||||
return ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
boolean match = false;
|
||||
List<ConditionMessage> messages = new ArrayList<>(2);
|
||||
ConditionMessage.Builder message = ConditionMessage.forCondition(ConditionalOnGraphQlSchema.class);
|
||||
|
||||
Binder binder = Binder.get(context.getEnvironment());
|
||||
GraphQlProperties.Schema schema = binder.bind("spring.graphql.schema", GraphQlProperties.Schema.class)
|
||||
.orElse(new GraphQlProperties.Schema());
|
||||
ResourcePatternResolver resourcePatternResolver = ResourcePatternUtils
|
||||
.getResourcePatternResolver(context.getResourceLoader());
|
||||
List<Resource> schemaResources = resolveSchemaResources(resourcePatternResolver, schema.getLocations(),
|
||||
schema.getFileExtensions());
|
||||
if (!schemaResources.isEmpty()) {
|
||||
match = true;
|
||||
messages.add(message.found("schema", "schemas").items(ConditionMessage.Style.QUOTE, schemaResources));
|
||||
}
|
||||
else {
|
||||
messages.add(message.didNotFind("schema files in locations").items(ConditionMessage.Style.QUOTE,
|
||||
Arrays.asList(schema.getLocations())));
|
||||
}
|
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
|
||||
String[] customizerBeans = beanFactory.getBeanNamesForType(GraphQlSourceBuilderCustomizer.class, false, false);
|
||||
if (customizerBeans.length != 0) {
|
||||
match = true;
|
||||
messages.add(message.found("customizer", "customizers").items(Arrays.asList(customizerBeans)));
|
||||
}
|
||||
else {
|
||||
messages.add((message.didNotFind("GraphQlSourceBuilderCustomizer").atAll()));
|
||||
}
|
||||
return new ConditionOutcome(match, ConditionMessage.of(messages));
|
||||
}
|
||||
|
||||
private List<Resource> resolveSchemaResources(ResourcePatternResolver resolver, String[] locations,
|
||||
String[] extensions) {
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
for (String location : locations) {
|
||||
for (String extension : extensions) {
|
||||
resources.addAll(resolveSchemaResources(resolver, location + "*" + extension));
|
||||
}
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
private List<Resource> resolveSchemaResources(ResourcePatternResolver resolver, String pattern) {
|
||||
try {
|
||||
return Arrays.asList(resolver.getResources(pattern));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.graphql;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link InvalidSchemaLocationsException} thrown when no schema file could be found in
|
||||
* the provided locations.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public class InvalidSchemaLocationsException extends NestedRuntimeException {
|
||||
|
||||
private final List<SchemaLocation> schemaLocations;
|
||||
|
||||
public InvalidSchemaLocationsException(String[] locations, ResourcePatternResolver resolver) {
|
||||
this(locations, resolver, null);
|
||||
}
|
||||
|
||||
public InvalidSchemaLocationsException(String[] locations, ResourcePatternResolver resolver, Throwable cause) {
|
||||
super("No schema file could be found in the provided locations.", cause);
|
||||
Assert.notEmpty(locations, "locations should not be empty");
|
||||
Assert.notNull(resolver, "resolver should not be null");
|
||||
List<SchemaLocation> providedLocations = new ArrayList<>();
|
||||
for (String location : locations) {
|
||||
try {
|
||||
String uri = resolver.getResource(location).getURI().toASCIIString();
|
||||
providedLocations.add(new SchemaLocation(location, uri));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
providedLocations.add(new SchemaLocation(location, ""));
|
||||
}
|
||||
}
|
||||
this.schemaLocations = Collections.unmodifiableList(providedLocations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of provided locations where to look for schemas.
|
||||
* @return the list of locations
|
||||
*/
|
||||
public List<SchemaLocation> getSchemaLocations() {
|
||||
return this.schemaLocations;
|
||||
}
|
||||
|
||||
/**
|
||||
* The location where to look for schemas.
|
||||
*/
|
||||
public static class SchemaLocation {
|
||||
|
||||
private final String location;
|
||||
|
||||
private final String uri;
|
||||
|
||||
SchemaLocation(String location, String uri) {
|
||||
this.location = location;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the location String to be resolved by a {@link ResourcePatternResolver}.
|
||||
* @return the location
|
||||
*/
|
||||
public String getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the resolved URI String for this location, an empty String if resolution
|
||||
* failed.
|
||||
* @return the resolved location or an empty String
|
||||
*/
|
||||
public String getUri() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.graphql;
|
||||
|
||||
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
|
||||
import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||
|
||||
/**
|
||||
* An implementation of {@link AbstractFailureAnalyzer} to analyze failures caused by
|
||||
* {@link InvalidSchemaLocationsException}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class InvalidSchemaLocationsExceptionFailureAnalyzer extends AbstractFailureAnalyzer<InvalidSchemaLocationsException> {
|
||||
|
||||
@Override
|
||||
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 (InvalidSchemaLocationsException.SchemaLocation schemaLocation : cause.getSchemaLocations()) {
|
||||
action.append(String.format("- '%s' (%s)" + System.lineSeparator(), schemaLocation.getUri(),
|
||||
schemaLocation.getLocation()));
|
||||
}
|
||||
return new FailureAnalysis(message, action.toString(), cause);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.graphql;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnGraphQlSchema}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class DefaultGraphQlSchemaConditionTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
void matchesWhenSchemaFilesAreDetected() {
|
||||
this.contextRunner.withUserConfiguration(TestingConfiguration.class).run((context) -> {
|
||||
didMatch(context);
|
||||
assertThat(conditionReportMessage(context)).contains("@ConditionalOnGraphQlSchema found schemas")
|
||||
.contains("@ConditionalOnGraphQlSchema did not find GraphQlSourceBuilderCustomizer");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesWhenCustomizerIsDetected() {
|
||||
this.contextRunner.withUserConfiguration(CustomCustomizerConfiguration.class, TestingConfiguration.class)
|
||||
.withPropertyValues("spring.graphql.schema.locations=classpath:graphql/missing").run((context) -> {
|
||||
didMatch(context);
|
||||
assertThat(conditionReportMessage(context)).contains(
|
||||
"@ConditionalOnGraphQlSchema did not find schema files in locations 'classpath:graphql/missing/'")
|
||||
.contains("@ConditionalOnGraphQlSchema found customizer myBuilderCuystomizer");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotMatchWhenBothAreMissing() {
|
||||
this.contextRunner.withUserConfiguration(TestingConfiguration.class)
|
||||
.withPropertyValues("spring.graphql.schema.locations=classpath:graphql/missing").run((context) -> {
|
||||
assertThat(context).doesNotHaveBean("success");
|
||||
assertThat(conditionReportMessage(context)).contains(
|
||||
"@ConditionalOnGraphQlSchema did not find schema files in locations 'classpath:graphql/missing/'")
|
||||
.contains("@ConditionalOnGraphQlSchema did not find GraphQlSourceBuilderCustomizer");
|
||||
});
|
||||
}
|
||||
|
||||
private void didMatch(AssertableApplicationContext context) {
|
||||
assertThat(context).hasBean("success");
|
||||
assertThat(context.getBean("success")).isEqualTo("success");
|
||||
}
|
||||
|
||||
private String conditionReportMessage(AssertableApplicationContext context) {
|
||||
Collection<ConditionEvaluationReport.ConditionAndOutcomes> conditionAndOutcomes = ConditionEvaluationReport
|
||||
.get(context.getSourceApplicationContext().getBeanFactory()).getConditionAndOutcomesBySource().values();
|
||||
return conditionAndOutcomes.iterator().next().iterator().next().getOutcome().getMessage();
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnGraphQlSchema
|
||||
static class TestingConfiguration {
|
||||
|
||||
@Bean
|
||||
String success() {
|
||||
return "success";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
GraphQlSourceBuilderCustomizer myBuilderCuystomizer() {
|
||||
return (builder) -> {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.graphql;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link InvalidSchemaLocationsExceptionFailureAnalyzer}
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class InvalidSchemaLocationsExceptionFailureAnalyzerTests {
|
||||
|
||||
private final InvalidSchemaLocationsExceptionFailureAnalyzer analyzer = new InvalidSchemaLocationsExceptionFailureAnalyzer();
|
||||
|
||||
private final ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||
|
||||
private final String[] missingLocation = new String[] {
|
||||
"classpath:org/springframework/boot/autoconfigure/graphql/missing/" };
|
||||
|
||||
private final String[] existingLocation = new String[] {
|
||||
"classpath:org/springframework/boot/autoconfigure/graphql/" };
|
||||
|
||||
@Test
|
||||
void shouldReportCause() {
|
||||
InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(this.existingLocation,
|
||||
this.resolver);
|
||||
FailureAnalysis analysis = this.analyzer.analyze(exception);
|
||||
assertThat(analysis.getCause()).isInstanceOf(InvalidSchemaLocationsException.class);
|
||||
assertThat(analysis.getAction()).contains("Check that the following locations contain schema files:");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldListUnresolvableLocation() {
|
||||
InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(this.missingLocation,
|
||||
this.resolver);
|
||||
FailureAnalysis analysis = this.analyzer.analyze(exception);
|
||||
assertThat(analysis.getAction()).contains(this.existingLocation[0]).doesNotContain("file:");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldListExistingLocation() {
|
||||
InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(this.existingLocation,
|
||||
this.resolver);
|
||||
FailureAnalysis analysis = this.analyzer.analyze(exception);
|
||||
assertThat(analysis.getAction()).contains(this.existingLocation[0]).contains("file:");
|
||||
}
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.graphql;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link InvalidSchemaLocationsException}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class InvalidSchemaLocationsExceptionTests {
|
||||
|
||||
private final String schemaFolder = "graphql/";
|
||||
|
||||
private final String[] locations = new String[] { "classpath:" + this.schemaFolder };
|
||||
|
||||
@Test
|
||||
void shouldRejectEmptyLocations() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new InvalidSchemaLocationsException(new String[] {}, new PathMatchingResourcePatternResolver()))
|
||||
.isInstanceOf(IllegalArgumentException.class).withMessage("locations should not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectNullResolver() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new InvalidSchemaLocationsException(this.locations, null))
|
||||
.isInstanceOf(IllegalArgumentException.class).withMessage("resolver should not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExposeConfiguredLocations() {
|
||||
InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(this.locations,
|
||||
new PathMatchingResourcePatternResolver());
|
||||
assertThat(exception.getSchemaLocations()).hasSize(1);
|
||||
InvalidSchemaLocationsException.SchemaLocation schemaLocation = exception.getSchemaLocations().get(0);
|
||||
assertThat(schemaLocation.getLocation()).isEqualTo(this.locations[0]);
|
||||
assertThat(schemaLocation.getUri()).endsWith(this.schemaFolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotFailWithUnresolvableLocations() {
|
||||
String unresolved = "classpath:unresolved/";
|
||||
InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(new String[] { unresolved },
|
||||
new PathMatchingResourcePatternResolver());
|
||||
assertThat(exception.getSchemaLocations()).hasSize(1);
|
||||
InvalidSchemaLocationsException.SchemaLocation schemaLocation = exception.getSchemaLocations().get(0);
|
||||
assertThat(schemaLocation.getLocation()).isEqualTo(unresolved);
|
||||
assertThat(schemaLocation.getUri()).isEmpty();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue