This commit is contained in:
Andy Wilkinson 2017-10-02 13:34:32 +01:00
parent 9ba20cc380
commit 9102eb32d1
8 changed files with 146 additions and 129 deletions

View File

@ -21,8 +21,8 @@ import java.util.Set;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* {@link RuntimeException} thrown when an endpoint invocation does * {@link RuntimeException} thrown when an endpoint invocation does not contain required
* not contain required parameters. * parameters.
* *
* @author Madhura Bhave * @author Madhura Bhave
* @since 2.0.0 * @since 2.0.0
@ -32,8 +32,9 @@ public class ParametersMissingException extends RuntimeException {
private final Set<String> parameters; private final Set<String> parameters;
public ParametersMissingException(Set<String> parameters) { public ParametersMissingException(Set<String> parameters) {
super("Failed to invoke operation because the following required " + super("Failed to invoke operation because the following required "
"parameters were missing: " + StringUtils.collectionToCommaDelimitedString(parameters)); + "parameters were missing: "
+ StringUtils.collectionToCommaDelimitedString(parameters));
this.parameters = parameters; this.parameters = parameters;
} }
@ -45,4 +46,3 @@ public class ParametersMissingException extends RuntimeException {
return this.parameters; return this.parameters;
} }
} }

View File

@ -110,13 +110,15 @@ public class HttpMessageConvertersTests {
@Test @Test
public void postProcessConverters() throws Exception { public void postProcessConverters() throws Exception {
HttpMessageConverters converters = new HttpMessageConverters() { HttpMessageConverters converters = new HttpMessageConverters() {
@Override @Override
protected List<HttpMessageConverter<?>> postProcessConverters( protected List<HttpMessageConverter<?>> postProcessConverters(
List<HttpMessageConverter<?>> converters) { List<HttpMessageConverter<?>> converters) {
converters.removeIf( converters.removeIf((
converter -> converter instanceof MappingJackson2XmlHttpMessageConverter); converter) -> converter instanceof MappingJackson2XmlHttpMessageConverter);
return converters; return converters;
} }
}; };
List<Class<?>> converterClasses = new ArrayList<>(); List<Class<?>> converterClasses = new ArrayList<>();
for (HttpMessageConverter<?> converter : converters) { for (HttpMessageConverter<?> converter : converters) {
@ -135,13 +137,15 @@ public class HttpMessageConvertersTests {
@Test @Test
public void postProcessPartConverters() throws Exception { public void postProcessPartConverters() throws Exception {
HttpMessageConverters converters = new HttpMessageConverters() { HttpMessageConverters converters = new HttpMessageConverters() {
@Override @Override
protected List<HttpMessageConverter<?>> postProcessPartConverters( protected List<HttpMessageConverter<?>> postProcessPartConverters(
List<HttpMessageConverter<?>> converters) { List<HttpMessageConverter<?>> converters) {
converters.removeIf( converters.removeIf((
converter -> converter instanceof MappingJackson2XmlHttpMessageConverter); converter) -> converter instanceof MappingJackson2XmlHttpMessageConverter);
return converters; return converters;
} }
}; };
List<Class<?>> converterClasses = new ArrayList<>(); List<Class<?>> converterClasses = new ArrayList<>();
for (HttpMessageConverter<?> converter : extractFormPartConverters( for (HttpMessageConverter<?> converter : extractFormPartConverters(

View File

@ -65,9 +65,9 @@ public abstract class AbstractJpaAutoConfigurationTests {
this.autoConfiguredClass = autoConfiguredClass; this.autoConfiguredClass = autoConfiguredClass;
this.contextRunner = new ApplicationContextRunner() this.contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.datasource.generate-unique-name=true") .withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestConfiguration.class) .withUserConfiguration(TestConfiguration.class).withConfiguration(
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, AutoConfigurations.of(DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, autoConfiguredClass)); TransactionAutoConfiguration.class, autoConfiguredClass));
} }
protected ApplicationContextRunner contextRunner() { protected ApplicationContextRunner contextRunner() {
@ -76,15 +76,17 @@ public abstract class AbstractJpaAutoConfigurationTests {
@Test @Test
public void dataSourceIsNotAvailable() { public void dataSourceIsNotAvailable() {
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of( new ApplicationContextRunner()
this.autoConfiguredClass)).run((context) -> { .withConfiguration(AutoConfigurations.of(this.autoConfiguredClass))
assertThat(context).hasFailed(); .run((context) -> {
assertThat(context.getStartupFailure()) assertThat(context).hasFailed();
.isInstanceOf(BeanCreationException.class); assertThat(context.getStartupFailure())
assertThat(context.getStartupFailure()) .isInstanceOf(BeanCreationException.class);
.hasMessageContaining("No qualifying bean"); assertThat(context.getStartupFailure())
assertThat(context.getStartupFailure()).hasMessageContaining("DataSource"); .hasMessageContaining("No qualifying bean");
}); assertThat(context.getStartupFailure())
.hasMessageContaining("DataSource");
});
} }
@Test @Test
@ -97,13 +99,15 @@ public abstract class AbstractJpaAutoConfigurationTests {
@Test @Test
public void jtaTransactionManagerTakesPrecedence() { public void jtaTransactionManagerTakesPrecedence() {
this.contextRunner.withConfiguration(AutoConfigurations.of( this.contextRunner
DataSourceTransactionManagerAutoConfiguration.class)).run((context) -> { .withConfiguration(AutoConfigurations
assertThat(context).hasSingleBean(DataSource.class); .of(DataSourceTransactionManagerAutoConfiguration.class))
assertThat(context).hasSingleBean(JpaTransactionManager.class); .run((context) -> {
assertThat(context).getBean("transactionManager") assertThat(context).hasSingleBean(DataSource.class);
.isInstanceOf(JpaTransactionManager.class); assertThat(context).hasSingleBean(JpaTransactionManager.class);
}); assertThat(context).getBean("transactionManager")
.isInstanceOf(JpaTransactionManager.class);
});
} }
@Test @Test
@ -111,7 +115,8 @@ public abstract class AbstractJpaAutoConfigurationTests {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withPropertyValues("spring.datasource.generate-unique-name=true") .withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestConfiguration.class) .withUserConfiguration(TestConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, .withConfiguration(AutoConfigurations.of(
DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, this.autoConfiguredClass)) TransactionAutoConfiguration.class, this.autoConfiguredClass))
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.hasSingleBean(OpenEntityManagerInViewInterceptor.class)); .hasSingleBean(OpenEntityManagerInViewInterceptor.class));
@ -122,7 +127,8 @@ public abstract class AbstractJpaAutoConfigurationTests {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withPropertyValues("spring.datasource.generate-unique-name=true") .withPropertyValues("spring.datasource.generate-unique-name=true")
.withUserConfiguration(TestFilterConfiguration.class) .withUserConfiguration(TestFilterConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, .withConfiguration(AutoConfigurations.of(
DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, this.autoConfiguredClass)) TransactionAutoConfiguration.class, this.autoConfiguredClass))
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.doesNotHaveBean(OpenEntityManagerInViewInterceptor.class)); .doesNotHaveBean(OpenEntityManagerInViewInterceptor.class));
@ -131,11 +137,11 @@ public abstract class AbstractJpaAutoConfigurationTests {
@Test @Test
public void openEntityManagerInViewInterceptorISNotRegisteredWhenExplicitlyOff() { public void openEntityManagerInViewInterceptorISNotRegisteredWhenExplicitlyOff() {
new WebApplicationContextRunner() new WebApplicationContextRunner()
.withPropertyValues( .withPropertyValues("spring.datasource.generate-unique-name=true",
"spring.datasource.generate-unique-name=true",
"spring.jpa.open-in-view=false") "spring.jpa.open-in-view=false")
.withUserConfiguration(TestConfiguration.class) .withUserConfiguration(TestConfiguration.class)
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, .withConfiguration(AutoConfigurations.of(
DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, this.autoConfiguredClass)) TransactionAutoConfiguration.class, this.autoConfiguredClass))
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
.doesNotHaveBean(OpenEntityManagerInViewInterceptor.class)); .doesNotHaveBean(OpenEntityManagerInViewInterceptor.class));
@ -143,69 +149,72 @@ public abstract class AbstractJpaAutoConfigurationTests {
@Test @Test
public void customJpaProperties() { public void customJpaProperties() {
this.contextRunner.withPropertyValues("spring.jpa.properties.a:b", this.contextRunner
"spring.jpa.properties.a.b:c", .withPropertyValues("spring.jpa.properties.a:b",
"spring.jpa.properties.c:d").run((context) -> { "spring.jpa.properties.a.b:c", "spring.jpa.properties.c:d")
LocalContainerEntityManagerFactoryBean bean = context .run((context) -> {
.getBean(LocalContainerEntityManagerFactoryBean.class); LocalContainerEntityManagerFactoryBean bean = context
Map<String, Object> map = bean.getJpaPropertyMap(); .getBean(LocalContainerEntityManagerFactoryBean.class);
assertThat(map.get("a")).isEqualTo("b"); Map<String, Object> map = bean.getJpaPropertyMap();
assertThat(map.get("c")).isEqualTo("d"); assertThat(map.get("a")).isEqualTo("b");
assertThat(map.get("a.b")).isEqualTo("c"); assertThat(map.get("c")).isEqualTo("d");
}); assertThat(map.get("a.b")).isEqualTo("c");
});
} }
@Test @Test
public void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanIfAvailable() { public void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanIfAvailable() {
this.contextRunner.withUserConfiguration( this.contextRunner
TestConfigurationWithLocalContainerEntityManagerFactoryBean.class .withUserConfiguration(
).run((context) -> { TestConfigurationWithLocalContainerEntityManagerFactoryBean.class)
LocalContainerEntityManagerFactoryBean factoryBean = context .run((context) -> {
.getBean(LocalContainerEntityManagerFactoryBean.class); LocalContainerEntityManagerFactoryBean factoryBean = context
Map<String, Object> map = factoryBean.getJpaPropertyMap(); .getBean(LocalContainerEntityManagerFactoryBean.class);
assertThat(map.get("configured")).isEqualTo("manually"); Map<String, Object> map = factoryBean.getJpaPropertyMap();
}); assertThat(map.get("configured")).isEqualTo("manually");
});
} }
@Test @Test
public void usesManuallyDefinedEntityManagerFactoryIfAvailable() { public void usesManuallyDefinedEntityManagerFactoryIfAvailable() {
this.contextRunner.withUserConfiguration( this.contextRunner
TestConfigurationWithLocalContainerEntityManagerFactoryBean.class .withUserConfiguration(
).run((context) -> { TestConfigurationWithLocalContainerEntityManagerFactoryBean.class)
EntityManagerFactory factoryBean = context .run((context) -> {
.getBean(EntityManagerFactory.class); EntityManagerFactory factoryBean = context
Map<String, Object> map = factoryBean.getProperties(); .getBean(EntityManagerFactory.class);
assertThat(map.get("configured")).isEqualTo("manually"); Map<String, Object> map = factoryBean.getProperties();
}); assertThat(map.get("configured")).isEqualTo("manually");
});
} }
@Test @Test
public void usesManuallyDefinedTransactionManagerBeanIfAvailable() { public void usesManuallyDefinedTransactionManagerBeanIfAvailable() {
this.contextRunner.withUserConfiguration( this.contextRunner
TestConfigurationWithTransactionManager.class .withUserConfiguration(TestConfigurationWithTransactionManager.class)
).run((context) -> { .run((context) -> {
PlatformTransactionManager txManager = context PlatformTransactionManager txManager = context
.getBean(PlatformTransactionManager.class); .getBean(PlatformTransactionManager.class);
assertThat(txManager).isInstanceOf(CustomJpaTransactionManager.class); assertThat(txManager).isInstanceOf(CustomJpaTransactionManager.class);
}); });
} }
@Test @Test
public void customPersistenceUnitManager() { public void customPersistenceUnitManager() {
this.contextRunner.withUserConfiguration( this.contextRunner
TestConfigurationWithCustomPersistenceUnitManager.class .withUserConfiguration(
).run((context) -> { TestConfigurationWithCustomPersistenceUnitManager.class)
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context .run((context) -> {
.getBean(LocalContainerEntityManagerFactoryBean.class); LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context
Field field = LocalContainerEntityManagerFactoryBean.class .getBean(LocalContainerEntityManagerFactoryBean.class);
.getDeclaredField("persistenceUnitManager"); Field field = LocalContainerEntityManagerFactoryBean.class
field.setAccessible(true); .getDeclaredField("persistenceUnitManager");
assertThat(field.get(entityManagerFactoryBean)) field.setAccessible(true);
.isEqualTo(context.getBean(PersistenceUnitManager.class)); assertThat(field.get(entityManagerFactoryBean))
}); .isEqualTo(context.getBean(PersistenceUnitManager.class));
});
} }
@Configuration @Configuration
@TestAutoConfigurationPackage(City.class) @TestAutoConfigurationPackage(City.class)
protected static class TestConfiguration { protected static class TestConfiguration {

View File

@ -70,15 +70,15 @@ public class HibernateJpaAutoConfigurationTests
@Test @Test
public void testDataScriptWithMissingDdl() { public void testDataScriptWithMissingDdl() {
contextRunner().withPropertyValues( contextRunner().withPropertyValues("spring.datasource.data:classpath:/city.sql",
"spring.datasource.data:classpath:/city.sql",
// Missing: // Missing:
"spring.datasource.schema:classpath:/ddl.sql").run((context) -> { "spring.datasource.schema:classpath:/ddl.sql").run((context) -> {
assertThat(context).hasFailed(); assertThat(context).hasFailed();
assertThat(context.getStartupFailure()).hasMessageContaining("ddl.sql"); assertThat(context.getStartupFailure())
assertThat(context.getStartupFailure()) .hasMessageContaining("ddl.sql");
.hasMessageContaining("spring.datasource.schema"); assertThat(context.getStartupFailure())
}); .hasMessageContaining("spring.datasource.schema");
});
} }
@Test @Test
@ -86,12 +86,12 @@ public class HibernateJpaAutoConfigurationTests
// This can't succeed because the data SQL is executed immediately after the // This can't succeed because the data SQL is executed immediately after the
// schema // schema
// and Hibernate hasn't initialized yet at that point // and Hibernate hasn't initialized yet at that point
contextRunner().withPropertyValues( contextRunner().withPropertyValues("spring.datasource.data:classpath:/city.sql")
"spring.datasource.data:classpath:/city.sql").run((context) -> { .run((context) -> {
assertThat(context).hasFailed(); assertThat(context).hasFailed();
assertThat(context.getStartupFailure()) assertThat(context.getStartupFailure())
.isInstanceOf(BeanCreationException.class); .isInstanceOf(BeanCreationException.class);
}); });
} }
@Test @Test
@ -100,9 +100,10 @@ public class HibernateJpaAutoConfigurationTests
.withClassLoader(new HideDataScriptClassLoader()) .withClassLoader(new HideDataScriptClassLoader())
.withPropertyValues("spring.jpa.show-sql=true", .withPropertyValues("spring.jpa.show-sql=true",
"spring.jpa.hibernate.ddl-auto:create-drop", "spring.jpa.hibernate.ddl-auto:create-drop",
"spring.datasource.data:classpath:/city.sql").run((context) -> "spring.datasource.data:classpath:/city.sql")
assertThat(context.getBean(TestInitializedJpaConfiguration.class).called) .run((context) -> assertThat(
.isTrue()); context.getBean(TestInitializedJpaConfiguration.class).called)
.isTrue());
} }
@Test @Test
@ -111,7 +112,7 @@ public class HibernateJpaAutoConfigurationTests
.withPropertyValues("spring.datasource.initialize:false", .withPropertyValues("spring.datasource.initialize:false",
"spring.flyway.locations:classpath:db/city") "spring.flyway.locations:classpath:db/city")
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
.run(context -> assertThat(context).hasNotFailed()); .run((context) -> assertThat(context).hasNotFailed());
} }
@Test @Test
@ -121,7 +122,7 @@ public class HibernateJpaAutoConfigurationTests
"spring.flyway.locations:classpath:db/city", "spring.flyway.locations:classpath:db/city",
"spring.jpa.hibernate.ddl-auto:validate") "spring.jpa.hibernate.ddl-auto:validate")
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
.run(context -> assertThat(context).hasNotFailed()); .run((context) -> assertThat(context).hasNotFailed());
} }
@Test @Test
@ -130,20 +131,22 @@ public class HibernateJpaAutoConfigurationTests
.withPropertyValues("spring.datasource.initialize:false", .withPropertyValues("spring.datasource.initialize:false",
"spring.liquibase.changeLog:classpath:db/changelog/db.changelog-city.yaml", "spring.liquibase.changeLog:classpath:db/changelog/db.changelog-city.yaml",
"spring.jpa.hibernate.ddl-auto:validate") "spring.jpa.hibernate.ddl-auto:validate")
.withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class)) .withConfiguration(
.run(context -> assertThat(context).hasNotFailed()); AutoConfigurations.of(LiquibaseAutoConfiguration.class))
.run((context) -> assertThat(context).hasNotFailed());
} }
@Test @Test
public void jtaDefaultPlatform() { public void jtaDefaultPlatform() {
contextRunner().withConfiguration(AutoConfigurations.of( contextRunner()
JtaAutoConfiguration.class)).run((context) -> { .withConfiguration(AutoConfigurations.of(JtaAutoConfiguration.class))
Map<String, Object> jpaPropertyMap = context .run((context) -> {
.getBean(LocalContainerEntityManagerFactoryBean.class) Map<String, Object> jpaPropertyMap = context
.getJpaPropertyMap(); .getBean(LocalContainerEntityManagerFactoryBean.class)
assertThat(jpaPropertyMap.get("hibernate.transaction.jta.platform")) .getJpaPropertyMap();
.isInstanceOf(SpringJtaPlatform.class); assertThat(jpaPropertyMap.get("hibernate.transaction.jta.platform"))
}); .isInstanceOf(SpringJtaPlatform.class);
});
} }
@Test @Test
@ -152,25 +155,28 @@ public class HibernateJpaAutoConfigurationTests
.withPropertyValues( .withPropertyValues(
"spring.jpa.properties.hibernate.transaction.jta.platform:" "spring.jpa.properties.hibernate.transaction.jta.platform:"
+ TestJtaPlatform.class.getName()) + TestJtaPlatform.class.getName())
.withConfiguration(AutoConfigurations.of( .withConfiguration(AutoConfigurations.of(JtaAutoConfiguration.class))
JtaAutoConfiguration.class)).run((context) -> { .run((context) -> {
Map<String, Object> jpaPropertyMap = context Map<String, Object> jpaPropertyMap = context
.getBean(LocalContainerEntityManagerFactoryBean.class) .getBean(LocalContainerEntityManagerFactoryBean.class)
.getJpaPropertyMap(); .getJpaPropertyMap();
assertThat((String) jpaPropertyMap.get("hibernate.transaction.jta.platform")) assertThat((String) jpaPropertyMap
.isEqualTo(TestJtaPlatform.class.getName()); .get("hibernate.transaction.jta.platform"))
}); .isEqualTo(TestJtaPlatform.class.getName());
});
} }
@Test @Test
public void jtaCustomTransactionManagerUsingProperties() { public void jtaCustomTransactionManagerUsingProperties() {
contextRunner().withPropertyValues("spring.transaction.default-timeout:30", contextRunner()
"spring.transaction.rollback-on-commit-failure:true").run((context) -> { .withPropertyValues("spring.transaction.default-timeout:30",
JpaTransactionManager transactionManager = context "spring.transaction.rollback-on-commit-failure:true")
.getBean(JpaTransactionManager.class); .run((context) -> {
assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); JpaTransactionManager transactionManager = context
assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); .getBean(JpaTransactionManager.class);
}); assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30);
assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue();
});
} }
@Configuration @Configuration

View File

@ -149,7 +149,7 @@ public class TestRestTemplate {
} }
interceptors = new ArrayList<>(interceptors); interceptors = new ArrayList<>(interceptors);
interceptors.removeIf( interceptors.removeIf(
interceptor -> interceptor instanceof BasicAuthorizationInterceptor); (interceptor) -> interceptor instanceof BasicAuthorizationInterceptor);
interceptors.add(new BasicAuthorizationInterceptor(username, password)); interceptors.add(new BasicAuthorizationInterceptor(username, password));
restTemplate.setInterceptors(interceptors); restTemplate.setInterceptors(interceptors);
} }

View File

@ -148,7 +148,7 @@ public class ConfigurationMetadata {
if (candidates == null || candidates.isEmpty()) { if (candidates == null || candidates.isEmpty()) {
return null; return null;
} }
candidates.removeIf(itemMetadata -> !itemMetadata.hasSameType(metadata)); candidates.removeIf((itemMetadata) -> !itemMetadata.hasSameType(metadata));
if (candidates.size() == 1) { if (candidates.size() == 1) {
return candidates.get(0); return candidates.get(0);
} }

View File

@ -40,9 +40,8 @@ class CollectionBinder extends IndexedElementsBinder<Collection<Object>> {
AggregateElementBinder elementBinder) { AggregateElementBinder elementBinder) {
Class<?> collectionType = (target.getValue() == null ? target.getType().resolve() Class<?> collectionType = (target.getValue() == null ? target.getType().resolve()
: List.class); : List.class);
IndexedCollectionSupplier collection = new IndexedCollectionSupplier(() -> { IndexedCollectionSupplier collection = new IndexedCollectionSupplier(
return CollectionFactory.createCollection(collectionType, 0); () -> CollectionFactory.createCollection(collectionType, 0));
});
ResolvableType elementType = target.getType().asCollection().getGeneric(); ResolvableType elementType = target.getType().asCollection().getGeneric();
ResolvableType aggregateType = ResolvableType.forClassWithGenerics(List.class, ResolvableType aggregateType = ResolvableType.forClassWithGenerics(List.class,
target.getType().asCollection().getGenerics()); target.getType().asCollection().getGenerics());

View File

@ -95,9 +95,8 @@ public class ValidationErrors implements Iterable<ObjectError> {
private boolean isForError(ConfigurationPropertyName name, private boolean isForError(ConfigurationPropertyName name,
ConfigurationPropertyName boundPropertyName, FieldError error) { ConfigurationPropertyName boundPropertyName, FieldError error) {
return name.isParentOf(boundPropertyName) return name.isParentOf(boundPropertyName) && boundPropertyName
&& boundPropertyName.getLastElement(Form.UNIFORM) .getLastElement(Form.UNIFORM).equalsIgnoreCase(error.getField());
.equalsIgnoreCase(error.getField());
} }
/** /**