Relocate projects to spring-boot-project
Move projects to better reflect the way that Spring Boot is released. The following projects are under `spring-boot-project`: - `spring-boot` - `spring-boot-autoconfigure` - `spring-boot-tools` - `spring-boot-starters` - `spring-boot-actuator` - `spring-boot-actuator-autoconfigure` - `spring-boot-test` - `spring-boot-test-autoconfigure` - `spring-boot-devtools` - `spring-boot-cli` - `spring-boot-docs` See gh-9316
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfigurationTests;
|
||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfigurationTests;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorControllerDirectMockMvcTests;
|
||||
|
||||
/**
|
||||
* A test suite for probing weird ordering problems in the tests.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({ BasicErrorControllerDirectMockMvcTests.class,
|
||||
JmxAutoConfigurationTests.class, IntegrationAutoConfigurationTests.class })
|
||||
@Ignore
|
||||
public class AdhocTestSuite {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.autoconfigure.context.filtersample.ExampleConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.filtersample.ExampleFilteredAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutoConfigurationExcludeFilter}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class AutoConfigurationExcludeFilterTests {
|
||||
|
||||
private static final Class<?> FILTERED = ExampleFilteredAutoConfiguration.class;
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterExcludeAutoConfiguration() {
|
||||
this.context = new AnnotationConfigApplicationContext(Config.class);
|
||||
assertThat(this.context.getBeansOfType(String.class)).hasSize(1);
|
||||
assertThat(this.context.getBean(String.class)).isEqualTo("test");
|
||||
this.thrown.expect(NoSuchBeanDefinitionException.class);
|
||||
this.context.getBean(FILTERED);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses = ExampleConfiguration.class, excludeFilters = @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TestAutoConfigurationExcludeFilter.class))
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
static class TestAutoConfigurationExcludeFilter
|
||||
extends AutoConfigurationExcludeFilter {
|
||||
|
||||
@Override
|
||||
protected List<String> getAutoConfigurations() {
|
||||
return Collections.singletonList(FILTERED.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.core.type.StandardAnnotationMetadata;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutoConfigurationImportSelector}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Stephane Nicoll
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class AutoConfigurationImportSelectorTests {
|
||||
|
||||
private final TestAutoConfigurationImportSelector importSelector = new TestAutoConfigurationImportSelector();
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
private final MockEnvironment environment = new MockEnvironment();
|
||||
|
||||
private List<AutoConfigurationImportFilter> filters = new ArrayList<>();
|
||||
|
||||
@Rule
|
||||
public ExpectedException expected = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.importSelector.setBeanFactory(this.beanFactory);
|
||||
this.importSelector.setEnvironment(this.environment);
|
||||
this.importSelector.setResourceLoader(new DefaultResourceLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importsAreSelectedWhenUsingEnableAutoConfiguration() {
|
||||
String[] imports = selectImports(BasicEnableAutoConfiguration.class);
|
||||
assertThat(imports).hasSameSizeAs(SpringFactoriesLoader.loadFactoryNames(
|
||||
EnableAutoConfiguration.class, getClass().getClassLoader()));
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classExclusionsAreApplied() {
|
||||
String[] imports = selectImports(
|
||||
EnableAutoConfigurationWithClassExclusions.class);
|
||||
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions())
|
||||
.contains(FreeMarkerAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classExclusionsAreAppliedWhenUsingSpringBootApplication() {
|
||||
String[] imports = selectImports(SpringBootApplicationWithClassExclusions.class);
|
||||
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions())
|
||||
.contains(FreeMarkerAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classNamesExclusionsAreApplied() {
|
||||
String[] imports = selectImports(
|
||||
EnableAutoConfigurationWithClassNameExclusions.class);
|
||||
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions())
|
||||
.contains(MustacheAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classNamesExclusionsAreAppliedWhenUsingSpringBootApplication() {
|
||||
String[] imports = selectImports(
|
||||
SpringBootApplicationWithClassNameExclusions.class);
|
||||
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions())
|
||||
.contains(MustacheAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyExclusionsAreApplied() {
|
||||
this.environment.setProperty("spring.autoconfigure.exclude",
|
||||
FreeMarkerAutoConfiguration.class.getName());
|
||||
String[] imports = selectImports(BasicEnableAutoConfiguration.class);
|
||||
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions())
|
||||
.contains(FreeMarkerAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void severalPropertyExclusionsAreApplied() {
|
||||
this.environment.setProperty("spring.autoconfigure.exclude",
|
||||
FreeMarkerAutoConfiguration.class.getName() + ","
|
||||
+ MustacheAutoConfiguration.class.getName());
|
||||
testSeveralPropertyExclusionsAreApplied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void severalPropertyExclusionsAreAppliedWithExtraSpaces() {
|
||||
this.environment.setProperty("spring.autoconfigure.exclude",
|
||||
FreeMarkerAutoConfiguration.class.getName() + " , "
|
||||
+ MustacheAutoConfiguration.class.getName() + " ");
|
||||
testSeveralPropertyExclusionsAreApplied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void severalPropertyYamlExclusionsAreApplied() {
|
||||
this.environment.setProperty("spring.autoconfigure.exclude[0]",
|
||||
FreeMarkerAutoConfiguration.class.getName());
|
||||
this.environment.setProperty("spring.autoconfigure.exclude[1]",
|
||||
MustacheAutoConfiguration.class.getName());
|
||||
testSeveralPropertyExclusionsAreApplied();
|
||||
}
|
||||
|
||||
private void testSeveralPropertyExclusionsAreApplied() {
|
||||
String[] imports = selectImports(BasicEnableAutoConfiguration.class);
|
||||
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 2);
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions()).contains(
|
||||
FreeMarkerAutoConfiguration.class.getName(),
|
||||
MustacheAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combinedExclusionsAreApplied() {
|
||||
this.environment.setProperty("spring.autoconfigure.exclude",
|
||||
ThymeleafAutoConfiguration.class.getName());
|
||||
String[] imports = selectImports(
|
||||
EnableAutoConfigurationWithClassAndClassNameExclusions.class);
|
||||
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 3);
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions()).contains(
|
||||
FreeMarkerAutoConfiguration.class.getName(),
|
||||
MustacheAutoConfiguration.class.getName(),
|
||||
ThymeleafAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonAutoConfigurationClassExclusionsShouldThrowException()
|
||||
throws Exception {
|
||||
this.expected.expect(IllegalStateException.class);
|
||||
selectImports(EnableAutoConfigurationWithFaultyClassExclude.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonAutoConfigurationClassNameExclusionsWhenPresentOnClassPathShouldThrowException()
|
||||
throws Exception {
|
||||
this.expected.expect(IllegalStateException.class);
|
||||
selectImports(EnableAutoConfigurationWithFaultyClassNameExclude.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonAutoConfigurationPropertyExclusionsWhenPresentOnClassPathShouldThrowException()
|
||||
throws Exception {
|
||||
this.environment.setProperty("spring.autoconfigure.exclude",
|
||||
"org.springframework.boot.autoconfigure."
|
||||
+ "AutoConfigurationImportSelectorTests.TestConfiguration");
|
||||
this.expected.expect(IllegalStateException.class);
|
||||
selectImports(BasicEnableAutoConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameAndPropertyExclusionsWhenNotPresentOnClasspathShouldNotThrowException()
|
||||
throws Exception {
|
||||
this.environment.setProperty("spring.autoconfigure.exclude",
|
||||
"org.springframework.boot.autoconfigure.DoesNotExist2");
|
||||
selectImports(EnableAutoConfigurationWithAbsentClassNameExclude.class);
|
||||
assertThat(this.importSelector.getLastEvent().getExclusions())
|
||||
.containsExactlyInAnyOrder(
|
||||
"org.springframework.boot.autoconfigure.DoesNotExist1",
|
||||
"org.springframework.boot.autoconfigure.DoesNotExist2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterShouldFilterImports() throws Exception {
|
||||
String[] defaultImports = selectImports(BasicEnableAutoConfiguration.class);
|
||||
this.filters.add(new TestAutoConfigurationImportFilter(defaultImports, 1));
|
||||
this.filters.add(new TestAutoConfigurationImportFilter(defaultImports, 3, 4));
|
||||
String[] filtered = selectImports(BasicEnableAutoConfiguration.class);
|
||||
assertThat(filtered).hasSize(defaultImports.length - 3);
|
||||
assertThat(filtered).doesNotContain(defaultImports[1], defaultImports[3],
|
||||
defaultImports[4]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterShouldSupportAware() throws Exception {
|
||||
TestAutoConfigurationImportFilter filter = new TestAutoConfigurationImportFilter(
|
||||
new String[] {});
|
||||
this.filters.add(filter);
|
||||
selectImports(BasicEnableAutoConfiguration.class);
|
||||
assertThat(filter.getBeanFactory()).isEqualTo(this.beanFactory);
|
||||
}
|
||||
|
||||
private String[] selectImports(Class<?> source) {
|
||||
return this.importSelector.selectImports(new StandardAnnotationMetadata(source));
|
||||
}
|
||||
|
||||
private List<String> getAutoConfigurationClassNames() {
|
||||
return SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,
|
||||
getClass().getClassLoader());
|
||||
}
|
||||
|
||||
private class TestAutoConfigurationImportSelector
|
||||
extends AutoConfigurationImportSelector {
|
||||
|
||||
private AutoConfigurationImportEvent lastEvent;
|
||||
|
||||
@Override
|
||||
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {
|
||||
return AutoConfigurationImportSelectorTests.this.filters;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AutoConfigurationImportListener> getAutoConfigurationImportListeners() {
|
||||
return Collections.<AutoConfigurationImportListener>singletonList(
|
||||
(event) -> this.lastEvent = event);
|
||||
}
|
||||
|
||||
public AutoConfigurationImportEvent getLastEvent() {
|
||||
return this.lastEvent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestAutoConfigurationImportFilter
|
||||
implements AutoConfigurationImportFilter, BeanFactoryAware {
|
||||
|
||||
private final Set<String> nonMatching = new HashSet<>();
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
TestAutoConfigurationImportFilter(String[] configurations, int... nonMatching) {
|
||||
for (int i : nonMatching) {
|
||||
this.nonMatching.add(configurations[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] match(String[] autoConfigurationClasses,
|
||||
AutoConfigurationMetadata autoConfigurationMetadata) {
|
||||
boolean[] result = new boolean[autoConfigurationClasses.length];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = !this.nonMatching.contains(autoConfigurationClasses[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
public BeanFactory getBeanFactory() {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
private class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
private class BasicEnableAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(exclude = FreeMarkerAutoConfiguration.class)
|
||||
private class EnableAutoConfigurationWithClassExclusions {
|
||||
|
||||
}
|
||||
|
||||
@SpringBootApplication(exclude = FreeMarkerAutoConfiguration.class)
|
||||
private class SpringBootApplicationWithClassExclusions {
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(excludeName = "org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration")
|
||||
private class EnableAutoConfigurationWithClassNameExclusions {
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(exclude = MustacheAutoConfiguration.class, excludeName = "org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration")
|
||||
private class EnableAutoConfigurationWithClassAndClassNameExclusions {
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(exclude = TestConfiguration.class)
|
||||
private class EnableAutoConfigurationWithFaultyClassExclude {
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(excludeName = "org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests.TestConfiguration")
|
||||
private class EnableAutoConfigurationWithFaultyClassNameExclude {
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(excludeName = "org.springframework.boot.autoconfigure.DoesNotExist1")
|
||||
private class EnableAutoConfigurationWithAbsentClassNameExclude {
|
||||
|
||||
}
|
||||
|
||||
@SpringBootApplication(excludeName = "org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration")
|
||||
private class SpringBootApplicationWithClassNameExclusions {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link AutoConfigurationMetadataLoader}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class AutoConfigurationMetadataLoaderTests {
|
||||
|
||||
@Test
|
||||
public void loadShouldLoadProperties() throws Exception {
|
||||
assertThat(load()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wasProcessedWhenProcessedShouldReturnTrue() throws Exception {
|
||||
assertThat(load().wasProcessed("test")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wasProcessedWhenNotProcessedShouldReturnFalse() throws Exception {
|
||||
assertThat(load().wasProcessed("testx")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIntegerShouldReturnValue() throws Exception {
|
||||
assertThat(load().getInteger("test", "int")).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIntegerWhenMissingShouldReturnNull() throws Exception {
|
||||
assertThat(load().getInteger("test", "intx")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIntegerWithDefaultWhenMissingShouldReturnDefault() throws Exception {
|
||||
assertThat(load().getInteger("test", "intx", 345)).isEqualTo(345);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSetShouldReturnValue() throws Exception {
|
||||
assertThat(load().getSet("test", "set")).containsExactly("a", "b", "c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSetWhenMissingShouldReturnNull() throws Exception {
|
||||
assertThat(load().getSet("test", "setx")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSetWithDefaultWhenMissingShouldReturnDefault() throws Exception {
|
||||
assertThat(load().getSet("test", "setx", Collections.singleton("x")))
|
||||
.containsExactly("x");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getShouldReturnValue() throws Exception {
|
||||
assertThat(load().get("test", "string")).isEqualTo("abc");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWhenMissingShouldReturnNull() throws Exception {
|
||||
assertThat(load().get("test", "stringx")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWithDefaultWhenMissingShouldReturnDefault() throws Exception {
|
||||
assertThat(load().get("test", "stringx", "xyz")).isEqualTo("xyz");
|
||||
}
|
||||
|
||||
private AutoConfigurationMetadata load() {
|
||||
return AutoConfigurationMetadataLoader.loadMetadata(null,
|
||||
"META-INF/AutoConfigurationMetadataLoaderTests.properties");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationPackages.Registrar;
|
||||
import org.springframework.boot.autoconfigure.packagestest.one.FirstConfiguration;
|
||||
import org.springframework.boot.autoconfigure.packagestest.two.SecondConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutoConfigurationPackages}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class AutoConfigurationPackagesTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void setAndGet() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
ConfigWithRegistrar.class);
|
||||
assertThat(AutoConfigurationPackages.get(context.getBeanFactory()))
|
||||
.containsExactly(getClass().getPackage().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWithoutSet() throws Exception {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
EmptyConfig.class);
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage(
|
||||
"Unable to retrieve @EnableAutoConfiguration base packages");
|
||||
AutoConfigurationPackages.get(context.getBeanFactory());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detectsMultipleAutoConfigurationPackages() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
FirstConfiguration.class, SecondConfiguration.class);
|
||||
List<String> packages = AutoConfigurationPackages.get(context.getBeanFactory());
|
||||
Package package1 = FirstConfiguration.class.getPackage();
|
||||
Package package2 = SecondConfiguration.class.getPackage();
|
||||
assertThat(packages).containsOnly(package1.getName(), package2.getName());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(AutoConfigurationPackages.Registrar.class)
|
||||
static class ConfigWithRegistrar {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class EmptyConfig {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test helper to allow {@link Registrar} to be referenced from other packages.
|
||||
*/
|
||||
public static class TestRegistrar extends Registrar {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests to reproduce reported issues.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class AutoConfigurationReproTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotEarlyInitializeFactoryBeans() throws Exception {
|
||||
SpringApplication application = new SpringApplication(EarlyInitConfig.class,
|
||||
PropertySourcesPlaceholderConfigurer.class,
|
||||
ServletWebServerFactoryAutoConfiguration.class);
|
||||
this.context = application.run("--server.port=0");
|
||||
String bean = (String) this.context.getBean("earlyInit");
|
||||
assertThat(bean).isEqualTo("bucket");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class Config {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("classpath:/early-init-test.xml")
|
||||
public static class EarlyInitConfig {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutoConfigurationSorter}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class AutoConfigurationSorterTests {
|
||||
|
||||
private static final String DEFAULT = OrderUnspecified.class.getName();
|
||||
|
||||
private static final String LOWEST = OrderLowest.class.getName();
|
||||
|
||||
private static final String HIGHEST = OrderHighest.class.getName();
|
||||
|
||||
private static final String A = AutoConfigureA.class.getName();
|
||||
|
||||
private static final String B = AutoConfigureB.class.getName();
|
||||
|
||||
private static final String C = AutoConfigureC.class.getName();
|
||||
|
||||
private static final String D = AutoConfigureD.class.getName();
|
||||
|
||||
private static final String E = AutoConfigureE.class.getName();
|
||||
|
||||
private static final String W = AutoConfigureW.class.getName();
|
||||
|
||||
private static final String X = AutoConfigureX.class.getName();
|
||||
|
||||
private static final String Y = AutoConfigureY.class.getName();
|
||||
|
||||
private static final String Z = AutoConfigureZ.class.getName();
|
||||
|
||||
private static final String A2 = AutoConfigureA2.class.getName();
|
||||
|
||||
private static final String W2 = AutoConfigureW2.class.getName();
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private AutoConfigurationSorter sorter;
|
||||
|
||||
private AutoConfigurationMetadata autoConfigurationMetadata = mock(
|
||||
AutoConfigurationMetadata.class);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.sorter = new AutoConfigurationSorter(new CachingMetadataReaderFactory(),
|
||||
this.autoConfigurationMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byOrderAnnotation() throws Exception {
|
||||
List<String> actual = this.sorter
|
||||
.getInPriorityOrder(Arrays.asList(LOWEST, HIGHEST, DEFAULT));
|
||||
assertThat(actual).containsExactly(HIGHEST, DEFAULT, LOWEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byAutoConfigureAfter() throws Exception {
|
||||
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B, C));
|
||||
assertThat(actual).containsExactly(C, B, A);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byAutoConfigureBefore() throws Exception {
|
||||
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(X, Y, Z));
|
||||
assertThat(actual).containsExactly(Z, Y, X);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byAutoConfigureAfterDoubles() throws Exception {
|
||||
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B, C, E));
|
||||
assertThat(actual).containsExactly(C, E, B, A);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byAutoConfigureMixedBeforeAndAfter() throws Exception {
|
||||
List<String> actual = this.sorter
|
||||
.getInPriorityOrder(Arrays.asList(A, B, C, W, X));
|
||||
assertThat(actual).containsExactly(C, W, B, A, X);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byAutoConfigureMixedBeforeAndAfterWithClassNames() throws Exception {
|
||||
List<String> actual = this.sorter
|
||||
.getInPriorityOrder(Arrays.asList(A2, B, C, W2, X));
|
||||
assertThat(actual).containsExactly(C, W2, B, A2, X);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byAutoConfigureMixedBeforeAndAfterWithDifferentInputOrder()
|
||||
throws Exception {
|
||||
List<String> actual = this.sorter
|
||||
.getInPriorityOrder(Arrays.asList(W, X, A, B, C));
|
||||
assertThat(actual).containsExactly(C, W, B, A, X);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byAutoConfigureAfterWithMissing() throws Exception {
|
||||
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B));
|
||||
assertThat(actual).containsExactly(B, A);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byAutoConfigureAfterWithCycle() throws Exception {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage("AutoConfigure cycle detected");
|
||||
this.sorter.getInPriorityOrder(Arrays.asList(A, B, C, D));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesAnnotationPropertiesWhenPossible() throws Exception {
|
||||
MetadataReaderFactory readerFactory = mock(MetadataReaderFactory.class);
|
||||
this.autoConfigurationMetadata = getAutoConfigurationMetadata(A2, B, C, W2, X);
|
||||
this.sorter = new AutoConfigurationSorter(readerFactory,
|
||||
this.autoConfigurationMetadata);
|
||||
List<String> actual = this.sorter
|
||||
.getInPriorityOrder(Arrays.asList(A2, B, C, W2, X));
|
||||
assertThat(actual).containsExactly(C, W2, B, A2, X);
|
||||
}
|
||||
|
||||
private AutoConfigurationMetadata getAutoConfigurationMetadata(String... classNames)
|
||||
throws Exception {
|
||||
Properties properties = new Properties();
|
||||
for (String className : classNames) {
|
||||
Class<?> type = ClassUtils.forName(className, null);
|
||||
properties.put(type.getName(), "");
|
||||
AutoConfigureOrder order = type
|
||||
.getDeclaredAnnotation(AutoConfigureOrder.class);
|
||||
if (order != null) {
|
||||
properties.put(className + ".AutoConfigureOrder",
|
||||
String.valueOf(order.value()));
|
||||
}
|
||||
AutoConfigureBefore autoConfigureBefore = type
|
||||
.getDeclaredAnnotation(AutoConfigureBefore.class);
|
||||
if (autoConfigureBefore != null) {
|
||||
properties.put(className + ".AutoConfigureBefore",
|
||||
merge(autoConfigureBefore.value(), autoConfigureBefore.name()));
|
||||
}
|
||||
AutoConfigureAfter autoConfigureAfter = type
|
||||
.getDeclaredAnnotation(AutoConfigureAfter.class);
|
||||
if (autoConfigureAfter != null) {
|
||||
properties.put(className + ".AutoConfigureAfter",
|
||||
merge(autoConfigureAfter.value(), autoConfigureAfter.name()));
|
||||
}
|
||||
}
|
||||
return AutoConfigurationMetadataLoader.loadMetadata(properties);
|
||||
}
|
||||
|
||||
private String merge(Class<?>[] value, String[] name) {
|
||||
Set<String> items = new LinkedHashSet<>();
|
||||
for (Class<?> type : value) {
|
||||
items.add(type.getName());
|
||||
}
|
||||
for (String type : name) {
|
||||
items.add(type);
|
||||
}
|
||||
return StringUtils.collectionToCommaDelimitedString(items);
|
||||
}
|
||||
|
||||
@AutoConfigureOrder
|
||||
public static class OrderUnspecified {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
|
||||
public static class OrderLowest {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
public static class OrderHighest {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureAfter(AutoConfigureB.class)
|
||||
public static class AutoConfigureA {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureAfter(name = "org.springframework.boot.autoconfigure.AutoConfigurationSorterTests$AutoConfigureB")
|
||||
public static class AutoConfigureA2 {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureAfter({ AutoConfigureC.class, AutoConfigureD.class,
|
||||
AutoConfigureE.class })
|
||||
public static class AutoConfigureB {
|
||||
|
||||
}
|
||||
|
||||
public static class AutoConfigureC {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureAfter(AutoConfigureA.class)
|
||||
public static class AutoConfigureD {
|
||||
|
||||
}
|
||||
|
||||
public static class AutoConfigureE {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureBefore(AutoConfigureB.class)
|
||||
public static class AutoConfigureW {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureBefore(name = "org.springframework.boot.autoconfigure.AutoConfigurationSorterTests$AutoConfigureB")
|
||||
public static class AutoConfigureW2 {
|
||||
|
||||
}
|
||||
|
||||
public static class AutoConfigureX {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureBefore(AutoConfigureX.class)
|
||||
public static class AutoConfigureY {
|
||||
|
||||
}
|
||||
|
||||
@AutoConfigureBefore(AutoConfigureY.class)
|
||||
public static class AutoConfigureZ {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.context.annotation.Configurations;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutoConfigurations}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class AutoConfigurationsTests {
|
||||
|
||||
@Test
|
||||
public void ofShouldCreateOrderedConfigurations() throws Exception {
|
||||
Configurations configurations = AutoConfigurations.of(AutoConfigureA.class,
|
||||
AutoConfigureB.class);
|
||||
assertThat(Configurations.getClasses(configurations))
|
||||
.containsExactly(AutoConfigureB.class, AutoConfigureA.class);
|
||||
}
|
||||
|
||||
@AutoConfigureAfter(AutoConfigureB.class)
|
||||
public static class AutoConfigureA {
|
||||
|
||||
}
|
||||
|
||||
public static class AutoConfigureB {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import org.springframework.boot.testsupport.context.AbstractConfigurationClassTests;
|
||||
|
||||
/**
|
||||
* Tests for the auto-configure module's {@code @Configuration} classes.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class AutoConfigureConfigurationClassTests
|
||||
extends AbstractConfigurationClassTests {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
public class EarlyInitFactoryBean implements FactoryBean<String> {
|
||||
|
||||
private String propertyFromConfig;
|
||||
|
||||
public void setPropertyFromConfig(String propertyFromConfig) {
|
||||
this.propertyFromConfig = propertyFromConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObject() throws Exception {
|
||||
return this.propertyFromConfig;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImportAutoConfigurationImportSelector}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class ImportAutoConfigurationImportSelectorTests {
|
||||
|
||||
private final ImportAutoConfigurationImportSelector importSelector = new TestImportAutoConfigurationImportSelector();
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
@Mock
|
||||
private Environment environment;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.importSelector.setBeanFactory(this.beanFactory);
|
||||
this.importSelector.setEnvironment(this.environment);
|
||||
this.importSelector.setResourceLoader(new DefaultResourceLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importsAreSelected() throws Exception {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
|
||||
ImportFreeMarker.class);
|
||||
String[] imports = this.importSelector.selectImports(annotationMetadata);
|
||||
assertThat(imports).containsExactly(FreeMarkerAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importsAreSelectedUsingClassesAttribute() throws Exception {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
|
||||
ImportFreeMarkerUsingClassesAttribute.class);
|
||||
String[] imports = this.importSelector.selectImports(annotationMetadata);
|
||||
assertThat(imports).containsExactly(FreeMarkerAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyExclusionsAreNotApplied() throws Exception {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
|
||||
ImportFreeMarker.class);
|
||||
this.importSelector.selectImports(annotationMetadata);
|
||||
verifyZeroInteractions(this.environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleImportsAreFound() throws Exception {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
|
||||
MultipleImports.class);
|
||||
String[] imports = this.importSelector.selectImports(annotationMetadata);
|
||||
assertThat(imports).containsOnly(FreeMarkerAutoConfiguration.class.getName(),
|
||||
ThymeleafAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selfAnnotatingAnnotationDoesNotCauseStackOverflow() throws IOException {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
|
||||
ImportWithSelfAnnotatingAnnotation.class);
|
||||
String[] imports = this.importSelector.selectImports(annotationMetadata);
|
||||
assertThat(imports).containsOnly(ThymeleafAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exclusionsAreApplied() throws Exception {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
|
||||
MultipleImportsWithExclusion.class);
|
||||
String[] imports = this.importSelector.selectImports(annotationMetadata);
|
||||
assertThat(imports).containsOnly(FreeMarkerAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exclusionsWithoutImport() throws Exception {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
|
||||
ExclusionWithoutImport.class);
|
||||
String[] imports = this.importSelector.selectImports(annotationMetadata);
|
||||
assertThat(imports).containsOnly(FreeMarkerAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exclusionsAliasesAreApplied() throws Exception {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(
|
||||
ImportWithSelfAnnotatingAnnotationExclude.class);
|
||||
String[] imports = this.importSelector.selectImports(annotationMetadata);
|
||||
assertThat(imports).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineImportsWhenUsingMetaWithoutClassesShouldBeEqual()
|
||||
throws Exception {
|
||||
Set<Object> set1 = this.importSelector.determineImports(
|
||||
getAnnotationMetadata(ImportMetaAutoConfigurationWithUnrelatedOne.class));
|
||||
Set<Object> set2 = this.importSelector.determineImports(
|
||||
getAnnotationMetadata(ImportMetaAutoConfigurationWithUnrelatedTwo.class));
|
||||
assertThat(set1).isEqualTo(set2);
|
||||
assertThat(set1.hashCode()).isEqualTo(set2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineImportsWhenUsingNonMetaWithoutClassesShouldBeSame()
|
||||
throws Exception {
|
||||
Set<Object> set1 = this.importSelector.determineImports(
|
||||
getAnnotationMetadata(ImportAutoConfigurationWithUnrelatedOne.class));
|
||||
Set<Object> set2 = this.importSelector.determineImports(
|
||||
getAnnotationMetadata(ImportAutoConfigurationWithUnrelatedTwo.class));
|
||||
assertThat(set1).isEqualTo(set2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineImportsWhenUsingNonMetaWithClassesShouldBeSame()
|
||||
throws Exception {
|
||||
Set<Object> set1 = this.importSelector.determineImports(
|
||||
getAnnotationMetadata(ImportAutoConfigurationWithItemsOne.class));
|
||||
Set<Object> set2 = this.importSelector.determineImports(
|
||||
getAnnotationMetadata(ImportAutoConfigurationWithItemsTwo.class));
|
||||
assertThat(set1).isEqualTo(set2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineImportsWhenUsingMetaExcludeWithoutClassesShouldBeEqual()
|
||||
throws Exception {
|
||||
Set<Object> set1 = this.importSelector.determineImports(getAnnotationMetadata(
|
||||
ImportMetaAutoConfigurationExcludeWithUnrelatedOne.class));
|
||||
Set<Object> set2 = this.importSelector.determineImports(getAnnotationMetadata(
|
||||
ImportMetaAutoConfigurationExcludeWithUnrelatedTwo.class));
|
||||
assertThat(set1).isEqualTo(set2);
|
||||
assertThat(set1.hashCode()).isEqualTo(set2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineImportsWhenUsingMetaDifferentExcludeWithoutClassesShouldBeDifferent()
|
||||
throws Exception {
|
||||
Set<Object> set1 = this.importSelector.determineImports(getAnnotationMetadata(
|
||||
ImportMetaAutoConfigurationExcludeWithUnrelatedOne.class));
|
||||
Set<Object> set2 = this.importSelector.determineImports(
|
||||
getAnnotationMetadata(ImportMetaAutoConfigurationWithUnrelatedTwo.class));
|
||||
assertThat(set1).isNotEqualTo(set2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineImportsShouldNotSetPackageImport() throws Exception {
|
||||
Class<?> packageImportClass = ClassUtils.resolveClassName(
|
||||
"org.springframework.boot.autoconfigure.AutoConfigurationPackages.PackageImport",
|
||||
null);
|
||||
Set<Object> selectedImports = this.importSelector
|
||||
.determineImports(getAnnotationMetadata(
|
||||
ImportMetaAutoConfigurationExcludeWithUnrelatedOne.class));
|
||||
for (Object selectedImport : selectedImports) {
|
||||
assertThat(selectedImport).isNotInstanceOf(packageImportClass);
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationMetadata getAnnotationMetadata(Class<?> source) throws IOException {
|
||||
return new SimpleMetadataReaderFactory().getMetadataReader(source.getName())
|
||||
.getAnnotationMetadata();
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration(FreeMarkerAutoConfiguration.class)
|
||||
static class ImportFreeMarker {
|
||||
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration(classes = FreeMarkerAutoConfiguration.class)
|
||||
static class ImportFreeMarkerUsingClassesAttribute {
|
||||
|
||||
}
|
||||
|
||||
@ImportOne
|
||||
@ImportTwo
|
||||
static class MultipleImports {
|
||||
|
||||
}
|
||||
|
||||
@ImportOne
|
||||
@ImportTwo
|
||||
@ImportAutoConfiguration(exclude = ThymeleafAutoConfiguration.class)
|
||||
static class MultipleImportsWithExclusion {
|
||||
|
||||
}
|
||||
|
||||
@ImportOne
|
||||
@ImportAutoConfiguration(exclude = ThymeleafAutoConfiguration.class)
|
||||
static class ExclusionWithoutImport {
|
||||
|
||||
}
|
||||
|
||||
@SelfAnnotating
|
||||
static class ImportWithSelfAnnotatingAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@SelfAnnotating(excludeAutoConfiguration = ThymeleafAutoConfiguration.class)
|
||||
static class ImportWithSelfAnnotatingAnnotationExclude {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ImportAutoConfiguration(FreeMarkerAutoConfiguration.class)
|
||||
@interface ImportOne {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ImportAutoConfiguration(ThymeleafAutoConfiguration.class)
|
||||
@interface ImportTwo {
|
||||
|
||||
}
|
||||
|
||||
@MetaImportAutoConfiguration
|
||||
@UnrelatedOne
|
||||
static class ImportMetaAutoConfigurationWithUnrelatedOne {
|
||||
|
||||
}
|
||||
|
||||
@MetaImportAutoConfiguration
|
||||
@UnrelatedTwo
|
||||
static class ImportMetaAutoConfigurationWithUnrelatedTwo {
|
||||
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration
|
||||
@UnrelatedOne
|
||||
static class ImportAutoConfigurationWithUnrelatedOne {
|
||||
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration
|
||||
@UnrelatedTwo
|
||||
static class ImportAutoConfigurationWithUnrelatedTwo {
|
||||
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration(classes = ThymeleafAutoConfiguration.class)
|
||||
@UnrelatedOne
|
||||
static class ImportAutoConfigurationWithItemsOne {
|
||||
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration(classes = ThymeleafAutoConfiguration.class)
|
||||
@UnrelatedTwo
|
||||
static class ImportAutoConfigurationWithItemsTwo {
|
||||
|
||||
}
|
||||
|
||||
@MetaImportAutoConfiguration(exclude = ThymeleafAutoConfiguration.class)
|
||||
@UnrelatedOne
|
||||
static class ImportMetaAutoConfigurationExcludeWithUnrelatedOne {
|
||||
|
||||
}
|
||||
|
||||
@MetaImportAutoConfiguration(exclude = ThymeleafAutoConfiguration.class)
|
||||
@UnrelatedTwo
|
||||
static class ImportMetaAutoConfigurationExcludeWithUnrelatedTwo {
|
||||
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface MetaImportAutoConfiguration {
|
||||
|
||||
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
|
||||
Class<?>[] exclude() default {};
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface UnrelatedOne {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface UnrelatedTwo {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ImportAutoConfiguration(ThymeleafAutoConfiguration.class)
|
||||
@SelfAnnotating
|
||||
@interface SelfAnnotating {
|
||||
|
||||
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
|
||||
Class<?>[] excludeAutoConfiguration() default {};
|
||||
|
||||
}
|
||||
|
||||
private static class TestImportAutoConfigurationImportSelector
|
||||
extends ImportAutoConfigurationImportSelector {
|
||||
|
||||
@Override
|
||||
protected Collection<String> loadFactoryNames(Class<?> source) {
|
||||
if (source == MetaImportAutoConfiguration.class) {
|
||||
return Arrays.asList(ThymeleafAutoConfiguration.class.getName(),
|
||||
FreeMarkerAutoConfiguration.class.getName());
|
||||
}
|
||||
return super.loadFactoryNames(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImportAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ImportAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void multipleAnnotationsShouldMergeCorrectly() {
|
||||
assertThat(getImportedConfigBeans(Config.class)).containsExactly("ConfigA",
|
||||
"ConfigB", "ConfigC", "ConfigD");
|
||||
assertThat(getImportedConfigBeans(AnotherConfig.class)).containsExactly("ConfigA",
|
||||
"ConfigB", "ConfigC", "ConfigD");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classesAsAnAlias() throws Exception {
|
||||
assertThat(getImportedConfigBeans(AnotherConfigUsingClasses.class))
|
||||
.containsExactly("ConfigA", "ConfigB", "ConfigC", "ConfigD");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void excluding() throws Exception {
|
||||
assertThat(getImportedConfigBeans(ExcludingConfig.class))
|
||||
.containsExactly("ConfigA", "ConfigB", "ConfigD");
|
||||
}
|
||||
|
||||
private List<String> getImportedConfigBeans(Class<?> config) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
config);
|
||||
String shortName = ClassUtils.getShortName(ImportAutoConfigurationTests.class);
|
||||
int beginIndex = shortName.length() + 1;
|
||||
List<String> orderedConfigBeans = new ArrayList<>();
|
||||
for (String bean : context.getBeanDefinitionNames()) {
|
||||
if (bean.contains("$Config")) {
|
||||
String shortBeanName = ClassUtils.getShortName(bean);
|
||||
orderedConfigBeans.add(shortBeanName.substring(beginIndex));
|
||||
}
|
||||
}
|
||||
context.close();
|
||||
return orderedConfigBeans;
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration({ ConfigD.class, ConfigB.class })
|
||||
@MetaImportAutoConfiguration
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
@MetaImportAutoConfiguration
|
||||
@ImportAutoConfiguration({ ConfigB.class, ConfigD.class })
|
||||
static class AnotherConfig {
|
||||
|
||||
}
|
||||
|
||||
@MetaImportAutoConfiguration
|
||||
@ImportAutoConfiguration(classes = { ConfigB.class, ConfigD.class })
|
||||
static class AnotherConfigUsingClasses {
|
||||
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration(classes = { ConfigD.class,
|
||||
ConfigB.class }, exclude = ConfigC.class)
|
||||
@MetaImportAutoConfiguration
|
||||
static class ExcludingConfig {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ImportAutoConfiguration({ ConfigC.class, ConfigA.class })
|
||||
@interface MetaImportAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ConfigA {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@AutoConfigureAfter(ConfigA.class)
|
||||
static class ConfigB {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@AutoConfigureAfter(ConfigB.class)
|
||||
static class ConfigC {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@AutoConfigureAfter(ConfigC.class)
|
||||
static class ConfigD {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@DirtiesContext
|
||||
@SpringBootTest
|
||||
public class SpringJUnitTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Value("${foo:spam}")
|
||||
private String foo = "bar";
|
||||
|
||||
@Test
|
||||
public void testContextCreated() {
|
||||
assertThat(this.context).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextInitialized() {
|
||||
assertThat(this.foo).isEqualTo("bucket");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ PropertyPlaceholderAutoConfiguration.class })
|
||||
public static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
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.Import;
|
||||
|
||||
/**
|
||||
* Test annotation to configure the {@link AutoConfigurationPackages} to an arbitrary
|
||||
* value.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import(TestAutoConfigurationPackageRegistrar.class)
|
||||
public @interface TestAutoConfigurationPackage {
|
||||
|
||||
Class<?> value();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link ImportBeanDefinitionRegistrar} to store the base package for tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class TestAutoConfigurationPackageRegistrar
|
||||
implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
AnnotationAttributes attributes = AnnotationAttributes
|
||||
.fromMap(metadata.getAnnotationAttributes(
|
||||
TestAutoConfigurationPackage.class.getName(), true));
|
||||
AutoConfigurationPackages.register(registry,
|
||||
ClassUtils.getPackageName(attributes.getString("value")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
|
||||
/**
|
||||
* Public version of {@link AutoConfigurationSorter} for use in tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class TestAutoConfigurationSorter extends AutoConfigurationSorter {
|
||||
|
||||
public TestAutoConfigurationSorter(MetadataReaderFactory metadataReaderFactory) {
|
||||
super(metadataReaderFactory,
|
||||
AutoConfigurationMetadataLoader.loadMetadata(new Properties()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.admin;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectInstance;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringApplicationAdminJmxAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class SpringApplicationAdminJmxAutoConfigurationTests {
|
||||
|
||||
private static final String ENABLE_ADMIN_PROP = "spring.application.admin.enabled=true";
|
||||
|
||||
private static final String DEFAULT_JMX_NAME = "org.springframework.boot:type=Admin,name=SpringApplication";
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class,
|
||||
SpringApplicationAdminJmxAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void notRegisteredByDefault()
|
||||
throws MalformedObjectNameException, InstanceNotFoundException {
|
||||
this.contextRunner.run((context) -> {
|
||||
this.thrown.expect(InstanceNotFoundException.class);
|
||||
this.server.getObjectInstance(createDefaultObjectName());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registeredWithProperty() throws Exception {
|
||||
this.contextRunner.withPropertyValues(ENABLE_ADMIN_PROP).run((context) -> {
|
||||
ObjectName objectName = createDefaultObjectName();
|
||||
ObjectInstance objectInstance = this.server.getObjectInstance(objectName);
|
||||
assertThat(objectInstance).as("Lifecycle bean should have been registered")
|
||||
.isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerWithCustomJmxName() throws InstanceNotFoundException {
|
||||
String customJmxName = "org.acme:name=FooBar";
|
||||
this.contextRunner
|
||||
.withSystemProperties(
|
||||
"spring.application.admin.jmx-name=" + customJmxName)
|
||||
.withPropertyValues(ENABLE_ADMIN_PROP).run((context) -> {
|
||||
try {
|
||||
this.server.getObjectInstance(createObjectName(customJmxName));
|
||||
}
|
||||
catch (InstanceNotFoundException ex) {
|
||||
fail("Admin MBean should have been exposed with custom name");
|
||||
}
|
||||
this.thrown.expect(InstanceNotFoundException.class); // Should not be
|
||||
// exposed
|
||||
this.server.getObjectInstance(createDefaultObjectName());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerWithSimpleWebApp() throws Exception {
|
||||
try (ConfigurableApplicationContext context = new SpringApplicationBuilder()
|
||||
.sources(ServletWebServerFactoryAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class,
|
||||
JmxAutoConfiguration.class,
|
||||
SpringApplicationAdminJmxAutoConfiguration.class)
|
||||
.run("--" + ENABLE_ADMIN_PROP, "--server.port=0")) {
|
||||
assertThat(context).isInstanceOf(ServletWebServerApplicationContext.class);
|
||||
assertThat(this.server.getAttribute(createDefaultObjectName(),
|
||||
"EmbeddedWebApplication")).isEqualTo(Boolean.TRUE);
|
||||
int expected = ((ServletWebServerApplicationContext) context).getWebServer()
|
||||
.getPort();
|
||||
String actual = getProperty(createDefaultObjectName(), "local.server.port");
|
||||
assertThat(actual).isEqualTo(String.valueOf(expected));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onlyRegisteredOnceWhenThereIsAChildContext() throws Exception {
|
||||
SpringApplicationBuilder parentBuilder = new SpringApplicationBuilder()
|
||||
.web(WebApplicationType.NONE).sources(JmxAutoConfiguration.class,
|
||||
SpringApplicationAdminJmxAutoConfiguration.class);
|
||||
SpringApplicationBuilder childBuilder = parentBuilder
|
||||
.child(JmxAutoConfiguration.class,
|
||||
SpringApplicationAdminJmxAutoConfiguration.class)
|
||||
.web(WebApplicationType.NONE);
|
||||
try (ConfigurableApplicationContext parent = parentBuilder
|
||||
.run("--" + ENABLE_ADMIN_PROP);
|
||||
ConfigurableApplicationContext child = childBuilder
|
||||
.run("--" + ENABLE_ADMIN_PROP)) {
|
||||
BeanFactoryUtils.beanOfType(parent.getBeanFactory(),
|
||||
SpringApplicationAdminMXBeanRegistrar.class);
|
||||
this.thrown.expect(NoSuchBeanDefinitionException.class);
|
||||
BeanFactoryUtils.beanOfType(child.getBeanFactory(),
|
||||
SpringApplicationAdminMXBeanRegistrar.class);
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectName createDefaultObjectName() {
|
||||
return createObjectName(DEFAULT_JMX_NAME);
|
||||
}
|
||||
|
||||
private ObjectName createObjectName(String jmxName) {
|
||||
try {
|
||||
return new ObjectName(jmxName);
|
||||
}
|
||||
catch (MalformedObjectNameException ex) {
|
||||
throw new IllegalStateException("Invalid jmx name " + jmxName, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String getProperty(ObjectName objectName, String key) throws Exception {
|
||||
return (String) this.server.invoke(objectName, "getProperty",
|
||||
new Object[] { key }, new String[] { String.class.getName() });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,726 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.amqp;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
import com.rabbitmq.client.Address;
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.amqp.core.AcknowledgeMode;
|
||||
import org.springframework.amqp.core.AmqpAdmin;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
|
||||
import org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.config.RabbitListenerConfigUtils;
|
||||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory.CacheMode;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
|
||||
import org.springframework.amqp.rabbit.support.ValueExpression;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
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 org.springframework.context.annotation.Primary;
|
||||
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
|
||||
import org.springframework.retry.interceptor.MethodInvocationRecoverer;
|
||||
import org.springframework.retry.policy.SimpleRetryPolicy;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link RabbitAutoConfiguration}.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Stephane Nicoll
|
||||
* @author Gary Russell
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class RabbitAutoConfigurationTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void testDefaultRabbitConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.run((context) -> {
|
||||
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
|
||||
RabbitMessagingTemplate messagingTemplate = context
|
||||
.getBean(RabbitMessagingTemplate.class);
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(connectionFactory);
|
||||
RabbitAdmin amqpAdmin = context.getBean(RabbitAdmin.class);
|
||||
assertThat(rabbitTemplate.getConnectionFactory())
|
||||
.isEqualTo(connectionFactory);
|
||||
assertThat(getMandatory(rabbitTemplate)).isFalse();
|
||||
assertThat(messagingTemplate.getRabbitTemplate())
|
||||
.isEqualTo(rabbitTemplate);
|
||||
assertThat(amqpAdmin).isNotNull();
|
||||
assertThat(connectionFactory.getHost()).isEqualTo("localhost");
|
||||
assertThat(dfa.getPropertyValue("publisherConfirms"))
|
||||
.isEqualTo(false);
|
||||
assertThat(dfa.getPropertyValue("publisherReturns")).isEqualTo(false);
|
||||
assertThat(context.containsBean("rabbitListenerContainerFactory"))
|
||||
.as("Listener container factory should be created by default")
|
||||
.isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryWithOverrides() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.host:remote-server",
|
||||
"spring.rabbitmq.port:9000", "spring.rabbitmq.username:alice",
|
||||
"spring.rabbitmq.password:secret",
|
||||
"spring.rabbitmq.virtual_host:/vhost",
|
||||
"spring.rabbitmq.connection-timeout:123")
|
||||
.run((context) -> {
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
assertThat(connectionFactory.getHost()).isEqualTo("remote-server");
|
||||
assertThat(connectionFactory.getPort()).isEqualTo(9000);
|
||||
assertThat(connectionFactory.getVirtualHost()).isEqualTo("/vhost");
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(connectionFactory);
|
||||
com.rabbitmq.client.ConnectionFactory rcf = (com.rabbitmq.client.ConnectionFactory) dfa
|
||||
.getPropertyValue("rabbitConnectionFactory");
|
||||
assertThat(rcf.getConnectionTimeout()).isEqualTo(123);
|
||||
assertThat((Address[]) dfa.getPropertyValue("addresses")).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryEmptyVirtualHost() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.virtual_host:").run((context) -> {
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
assertThat(connectionFactory.getVirtualHost()).isEqualTo("/");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryVirtualHostNoLeadingSlash() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.virtual_host:foo").run((context) -> {
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
assertThat(connectionFactory.getVirtualHost()).isEqualTo("foo");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryVirtualHostMultiLeadingSlashes() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.virtual_host:///foo")
|
||||
.run((context) -> {
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
assertThat(connectionFactory.getVirtualHost()).isEqualTo("///foo");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryDefaultVirtualHost() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.virtual_host:/").run((context) -> {
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
assertThat(connectionFactory.getVirtualHost()).isEqualTo("/");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryPublisherSettings() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.publisher-confirms=true",
|
||||
"spring.rabbitmq.publisher-returns=true")
|
||||
.run((context) -> {
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(connectionFactory);
|
||||
assertThat(dfa.getPropertyValue("publisherConfirms")).isEqualTo(true);
|
||||
assertThat(dfa.getPropertyValue("publisherReturns")).isEqualTo(true);
|
||||
assertThat(getMandatory(rabbitTemplate)).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitTemplateMessageConverters() {
|
||||
this.contextRunner.withUserConfiguration(MessageConvertersConfiguration.class)
|
||||
.run((context) -> {
|
||||
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
|
||||
assertThat(rabbitTemplate.getMessageConverter())
|
||||
.isSameAs(context.getBean("myMessageConverter"));
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(rabbitTemplate);
|
||||
assertThat(dfa.getPropertyValue("retryTemplate")).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitTemplateRetry() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.template.retry.enabled:true",
|
||||
"spring.rabbitmq.template.retry.maxAttempts:4",
|
||||
"spring.rabbitmq.template.retry.initialInterval:2000",
|
||||
"spring.rabbitmq.template.retry.multiplier:1.5",
|
||||
"spring.rabbitmq.template.retry.maxInterval:5000",
|
||||
"spring.rabbitmq.template.receiveTimeout:123",
|
||||
"spring.rabbitmq.template.replyTimeout:456")
|
||||
.run((context) -> {
|
||||
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(rabbitTemplate);
|
||||
assertThat(dfa.getPropertyValue("receiveTimeout")).isEqualTo(123L);
|
||||
assertThat(dfa.getPropertyValue("replyTimeout")).isEqualTo(456L);
|
||||
RetryTemplate retryTemplate = (RetryTemplate) dfa
|
||||
.getPropertyValue("retryTemplate");
|
||||
assertThat(retryTemplate).isNotNull();
|
||||
dfa = new DirectFieldAccessor(retryTemplate);
|
||||
SimpleRetryPolicy retryPolicy = (SimpleRetryPolicy) dfa
|
||||
.getPropertyValue("retryPolicy");
|
||||
ExponentialBackOffPolicy backOffPolicy = (ExponentialBackOffPolicy) dfa
|
||||
.getPropertyValue("backOffPolicy");
|
||||
assertThat(retryPolicy.getMaxAttempts()).isEqualTo(4);
|
||||
assertThat(backOffPolicy.getInitialInterval()).isEqualTo(2000);
|
||||
assertThat(backOffPolicy.getMultiplier()).isEqualTo(1.5);
|
||||
assertThat(backOffPolicy.getMaxInterval()).isEqualTo(5000);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitTemplateMandatory() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.template.mandatory:true")
|
||||
.run((context) -> {
|
||||
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
|
||||
assertThat(getMandatory(rabbitTemplate)).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitTemplateMandatoryDisabledEvenIfPublisherReturnsIsSet() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.template.mandatory:false",
|
||||
"spring.rabbitmq.publisher-returns=true")
|
||||
.run((context) -> {
|
||||
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
|
||||
assertThat(getMandatory(rabbitTemplate)).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryBackOff() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration2.class)
|
||||
.run((context) -> {
|
||||
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
assertThat(connectionFactory)
|
||||
.isEqualTo(rabbitTemplate.getConnectionFactory());
|
||||
assertThat(connectionFactory.getHost()).isEqualTo("otherserver");
|
||||
assertThat(connectionFactory.getPort()).isEqualTo(8001);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryCacheSettings() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.cache.channel.size=23",
|
||||
"spring.rabbitmq.cache.channel.checkoutTimeout=1000",
|
||||
"spring.rabbitmq.cache.connection.mode=CONNECTION",
|
||||
"spring.rabbitmq.cache.connection.size=2")
|
||||
.run((context) -> {
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(connectionFactory);
|
||||
assertThat(dfa.getPropertyValue("channelCacheSize")).isEqualTo(23);
|
||||
assertThat(dfa.getPropertyValue("cacheMode"))
|
||||
.isEqualTo(CacheMode.CONNECTION);
|
||||
assertThat(dfa.getPropertyValue("connectionCacheSize")).isEqualTo(2);
|
||||
assertThat(dfa.getPropertyValue("channelCheckoutTimeout"))
|
||||
.isEqualTo(1000L);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitTemplateBackOff() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration3.class)
|
||||
.run((context) -> {
|
||||
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
|
||||
assertThat(rabbitTemplate.getMessageConverter())
|
||||
.isEqualTo(context.getBean("testMessageConverter"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitMessagingTemplateBackOff() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration4.class)
|
||||
.run((context) -> {
|
||||
RabbitMessagingTemplate messagingTemplate = context
|
||||
.getBean(RabbitMessagingTemplate.class);
|
||||
assertThat(messagingTemplate.getDefaultDestination())
|
||||
.isEqualTo("fooBar");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStaticQueues() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.dynamic:false").run((context) -> {
|
||||
// There should NOT be an AmqpAdmin bean when dynamic is switch to
|
||||
// false
|
||||
this.thrown.expect(NoSuchBeanDefinitionException.class);
|
||||
this.thrown.expectMessage("No qualifying bean of type");
|
||||
this.thrown.expectMessage(AmqpAdmin.class.getName());
|
||||
context.getBean(AmqpAdmin.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableRabbitCreateDefaultContainerFactory() {
|
||||
this.contextRunner.withUserConfiguration(EnableRabbitConfiguration.class)
|
||||
.run((context) -> {
|
||||
RabbitListenerContainerFactory<?> rabbitListenerContainerFactory = context
|
||||
.getBean("rabbitListenerContainerFactory",
|
||||
RabbitListenerContainerFactory.class);
|
||||
assertThat(rabbitListenerContainerFactory.getClass())
|
||||
.isEqualTo(SimpleRabbitListenerContainerFactory.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitListenerContainerFactoryBackOff() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration5.class)
|
||||
.run((context) -> {
|
||||
SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory = context
|
||||
.getBean("rabbitListenerContainerFactory",
|
||||
SimpleRabbitListenerContainerFactory.class);
|
||||
rabbitListenerContainerFactory.setTxSize(10);
|
||||
verify(rabbitListenerContainerFactory).setTxSize(10);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(
|
||||
rabbitListenerContainerFactory);
|
||||
Advice[] adviceChain = (Advice[]) dfa.getPropertyValue("adviceChain");
|
||||
assertThat(adviceChain).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRabbitListenerContainerFactoryWithCustomSettings() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(MessageConvertersConfiguration.class,
|
||||
MessageRecoverersConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.listener.simple.retry.enabled:true",
|
||||
"spring.rabbitmq.listener.simple.retry.maxAttempts:4",
|
||||
"spring.rabbitmq.listener.simple.retry.initialInterval:2000",
|
||||
"spring.rabbitmq.listener.simple.retry.multiplier:1.5",
|
||||
"spring.rabbitmq.listener.simple.retry.maxInterval:5000",
|
||||
"spring.rabbitmq.listener.simple.autoStartup:false",
|
||||
"spring.rabbitmq.listener.simple.acknowledgeMode:manual",
|
||||
"spring.rabbitmq.listener.simple.concurrency:5",
|
||||
"spring.rabbitmq.listener.simple.maxConcurrency:10",
|
||||
"spring.rabbitmq.listener.simple.prefetch:40",
|
||||
"spring.rabbitmq.listener.simple.defaultRequeueRejected:false",
|
||||
"spring.rabbitmq.listener.simple.idleEventInterval:5",
|
||||
"spring.rabbitmq.listener.simple.transactionSize:20")
|
||||
.run((context) -> {
|
||||
SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory = context
|
||||
.getBean("rabbitListenerContainerFactory",
|
||||
SimpleRabbitListenerContainerFactory.class);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(
|
||||
rabbitListenerContainerFactory);
|
||||
assertThat(dfa.getPropertyValue("concurrentConsumers")).isEqualTo(5);
|
||||
assertThat(dfa.getPropertyValue("maxConcurrentConsumers"))
|
||||
.isEqualTo(10);
|
||||
assertThat(dfa.getPropertyValue("txSize")).isEqualTo(20);
|
||||
checkCommonProps(context, dfa);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectRabbitListenerContainerFactoryWithCustomSettings() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(MessageConvertersConfiguration.class,
|
||||
MessageRecoverersConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.listener.type:direct",
|
||||
"spring.rabbitmq.listener.direct.retry.enabled:true",
|
||||
"spring.rabbitmq.listener.direct.retry.maxAttempts:4",
|
||||
"spring.rabbitmq.listener.direct.retry.initialInterval:2000",
|
||||
"spring.rabbitmq.listener.direct.retry.multiplier:1.5",
|
||||
"spring.rabbitmq.listener.direct.retry.maxInterval:5000",
|
||||
"spring.rabbitmq.listener.direct.autoStartup:false",
|
||||
"spring.rabbitmq.listener.direct.acknowledgeMode:manual",
|
||||
"spring.rabbitmq.listener.direct.consumers-per-queue:5",
|
||||
"spring.rabbitmq.listener.direct.prefetch:40",
|
||||
"spring.rabbitmq.listener.direct.defaultRequeueRejected:false",
|
||||
"spring.rabbitmq.listener.direct.idleEventInterval:5")
|
||||
.run((context) -> {
|
||||
DirectRabbitListenerContainerFactory rabbitListenerContainerFactory = context
|
||||
.getBean("rabbitListenerContainerFactory",
|
||||
DirectRabbitListenerContainerFactory.class);
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(
|
||||
rabbitListenerContainerFactory);
|
||||
assertThat(dfa.getPropertyValue("consumersPerQueue")).isEqualTo(5);
|
||||
checkCommonProps(context, dfa);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitListenerContainerFactoryConfigurersAreAvailable() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.listener.simple.concurrency:5",
|
||||
"spring.rabbitmq.listener.simple.maxConcurrency:10",
|
||||
"spring.rabbitmq.listener.simple.prefetch:40",
|
||||
"spring.rabbitmq.listener.direct.consumers-per-queue:5",
|
||||
"spring.rabbitmq.listener.direct.prefetch:40")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(
|
||||
SimpleRabbitListenerContainerFactoryConfigurer.class);
|
||||
assertThat(context).hasSingleBean(
|
||||
DirectRabbitListenerContainerFactoryConfigurer.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRabbitListenerContainerFactoryConfigurerUsesConfig() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.listener.type:direct",
|
||||
"spring.rabbitmq.listener.simple.concurrency:5",
|
||||
"spring.rabbitmq.listener.simple.maxConcurrency:10",
|
||||
"spring.rabbitmq.listener.simple.prefetch:40")
|
||||
.run((context) -> {
|
||||
SimpleRabbitListenerContainerFactoryConfigurer configurer = context
|
||||
.getBean(
|
||||
SimpleRabbitListenerContainerFactoryConfigurer.class);
|
||||
SimpleRabbitListenerContainerFactory factory = mock(
|
||||
SimpleRabbitListenerContainerFactory.class);
|
||||
configurer.configure(factory, mock(ConnectionFactory.class));
|
||||
verify(factory).setConcurrentConsumers(5);
|
||||
verify(factory).setMaxConcurrentConsumers(10);
|
||||
verify(factory).setPrefetchCount(40);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectRabbitListenerContainerFactoryConfigurerUsesConfig() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.listener.type:simple",
|
||||
"spring.rabbitmq.listener.direct.consumers-per-queue:5",
|
||||
"spring.rabbitmq.listener.direct.prefetch:40")
|
||||
.run((context) -> {
|
||||
DirectRabbitListenerContainerFactoryConfigurer configurer = context
|
||||
.getBean(
|
||||
DirectRabbitListenerContainerFactoryConfigurer.class);
|
||||
DirectRabbitListenerContainerFactory factory = mock(
|
||||
DirectRabbitListenerContainerFactory.class);
|
||||
configurer.configure(factory, mock(ConnectionFactory.class));
|
||||
verify(factory).setConsumersPerQueue(5);
|
||||
verify(factory).setPrefetchCount(40);
|
||||
});
|
||||
}
|
||||
|
||||
private void checkCommonProps(AssertableApplicationContext context,
|
||||
DirectFieldAccessor dfa) {
|
||||
assertThat(dfa.getPropertyValue("autoStartup")).isEqualTo(Boolean.FALSE);
|
||||
assertThat(dfa.getPropertyValue("acknowledgeMode"))
|
||||
.isEqualTo(AcknowledgeMode.MANUAL);
|
||||
assertThat(dfa.getPropertyValue("prefetchCount")).isEqualTo(40);
|
||||
assertThat(dfa.getPropertyValue("messageConverter"))
|
||||
.isSameAs(context.getBean("myMessageConverter"));
|
||||
assertThat(dfa.getPropertyValue("defaultRequeueRejected"))
|
||||
.isEqualTo(Boolean.FALSE);
|
||||
assertThat(dfa.getPropertyValue("idleEventInterval")).isEqualTo(5L);
|
||||
Advice[] adviceChain = (Advice[]) dfa.getPropertyValue("adviceChain");
|
||||
assertThat(adviceChain).isNotNull();
|
||||
assertThat(adviceChain.length).isEqualTo(1);
|
||||
dfa = new DirectFieldAccessor(adviceChain[0]);
|
||||
MessageRecoverer messageRecoverer = context.getBean("myMessageRecoverer",
|
||||
MessageRecoverer.class);
|
||||
MethodInvocationRecoverer<?> mir = (MethodInvocationRecoverer<?>) dfa
|
||||
.getPropertyValue("recoverer");
|
||||
Message message = mock(Message.class);
|
||||
Exception ex = new Exception("test");
|
||||
mir.recover(new Object[] { "foo", message }, ex);
|
||||
verify(messageRecoverer).recover(message, ex);
|
||||
RetryTemplate retryTemplate = (RetryTemplate) dfa
|
||||
.getPropertyValue("retryOperations");
|
||||
assertThat(retryTemplate).isNotNull();
|
||||
dfa = new DirectFieldAccessor(retryTemplate);
|
||||
SimpleRetryPolicy retryPolicy = (SimpleRetryPolicy) dfa
|
||||
.getPropertyValue("retryPolicy");
|
||||
ExponentialBackOffPolicy backOffPolicy = (ExponentialBackOffPolicy) dfa
|
||||
.getPropertyValue("backOffPolicy");
|
||||
assertThat(retryPolicy.getMaxAttempts()).isEqualTo(4);
|
||||
assertThat(backOffPolicy.getInitialInterval()).isEqualTo(2000);
|
||||
assertThat(backOffPolicy.getMultiplier()).isEqualTo(1.5);
|
||||
assertThat(backOffPolicy.getMaxInterval()).isEqualTo(5000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableRabbitAutomatically() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(NoEnableRabbitConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean(
|
||||
RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME);
|
||||
assertThat(context).hasBean(
|
||||
RabbitListenerConfigUtils.RABBIT_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeRequestedHeartBeat() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.requestedHeartbeat:20")
|
||||
.run((context) -> {
|
||||
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(
|
||||
context);
|
||||
assertThat(rabbitConnectionFactory.getRequestedHeartbeat())
|
||||
.isEqualTo(20);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noSslByDefault() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.run((context) -> {
|
||||
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(
|
||||
context);
|
||||
assertThat(rabbitConnectionFactory.getSocketFactory()).isNull();
|
||||
assertThat(rabbitConnectionFactory.isSSL()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableSsl() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.ssl.enabled:true").run((context) -> {
|
||||
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(
|
||||
context);
|
||||
assertThat(rabbitConnectionFactory.isSSL()).isTrue();
|
||||
assertThat(rabbitConnectionFactory.getSocketFactory())
|
||||
.as("SocketFactory must use SSL")
|
||||
.isInstanceOf(SSLSocketFactory.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
// Make sure that we at least attempt to load the store
|
||||
public void enableSslWithNonExistingKeystoreShouldFail() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.ssl.enabled:true",
|
||||
"spring.rabbitmq.ssl.keyStore=foo",
|
||||
"spring.rabbitmq.ssl.keyStorePassword=secret")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context).getFailure().hasMessageContaining("foo");
|
||||
assertThat(context).getFailure()
|
||||
.hasMessageContaining("does not exist");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
// Make sure that we at least attempt to load the store
|
||||
public void enableSslWithNonExistingTrustStoreShouldFail() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.ssl.enabled:true",
|
||||
"spring.rabbitmq.ssl.trustStore=bar",
|
||||
"spring.rabbitmq.ssl.trustStorePassword=secret")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context).getFailure().hasMessageContaining("bar");
|
||||
assertThat(context).getFailure()
|
||||
.hasMessageContaining("does not exist");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableSslWithInvalidKeystoreTypeShouldFail() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.ssl.enabled:true",
|
||||
"spring.rabbitmq.ssl.keyStore=foo",
|
||||
"spring.rabbitmq.ssl.keyStoreType=fooType")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context).getFailure().hasMessageContaining("fooType");
|
||||
assertThat(context).getFailure()
|
||||
.hasRootCauseInstanceOf(NoSuchAlgorithmException.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableSslWithInvalidTrustStoreTypeShouldFail() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.ssl.enabled:true",
|
||||
"spring.rabbitmq.ssl.trustStore=bar",
|
||||
"spring.rabbitmq.ssl.trustStoreType=barType")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context).getFailure().hasMessageContaining("barType");
|
||||
assertThat(context).getFailure()
|
||||
.hasRootCauseInstanceOf(NoSuchAlgorithmException.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableSslWithKeystoreTypeAndTrustStoreTypeShouldWork() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.rabbitmq.ssl.enabled:true",
|
||||
"spring.rabbitmq.ssl.keyStore=/org/springframework/boot/autoconfigure/amqp/test.jks",
|
||||
"spring.rabbitmq.ssl.keyStoreType=jks",
|
||||
"spring.rabbitmq.ssl.keyStorePassword=secret",
|
||||
"spring.rabbitmq.ssl.trustStore=/org/springframework/boot/autoconfigure/amqp/test.jks",
|
||||
"spring.rabbitmq.ssl.trustStoreType=jks",
|
||||
"spring.rabbitmq.ssl.trustStorePassword=secret")
|
||||
.run((context) -> assertThat(context).hasNotFailed());
|
||||
}
|
||||
|
||||
private com.rabbitmq.client.ConnectionFactory getTargetConnectionFactory(
|
||||
AssertableApplicationContext context) {
|
||||
CachingConnectionFactory connectionFactory = context
|
||||
.getBean(CachingConnectionFactory.class);
|
||||
return (com.rabbitmq.client.ConnectionFactory) new DirectFieldAccessor(
|
||||
connectionFactory).getPropertyValue("rabbitConnectionFactory");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean getMandatory(RabbitTemplate rabbitTemplate) {
|
||||
ValueExpression<Boolean> expression = (ValueExpression<Boolean>) new DirectFieldAccessor(
|
||||
rabbitTemplate).getPropertyValue("mandatoryExpression");
|
||||
return expression.getValue();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration2 {
|
||||
|
||||
@Bean
|
||||
ConnectionFactory aDifferentConnectionFactory() {
|
||||
return new CachingConnectionFactory("otherserver", 8001);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration3 {
|
||||
|
||||
@Bean
|
||||
RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
|
||||
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
|
||||
rabbitTemplate.setMessageConverter(testMessageConverter());
|
||||
return rabbitTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageConverter testMessageConverter() {
|
||||
return mock(MessageConverter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration4 {
|
||||
|
||||
@Bean
|
||||
RabbitMessagingTemplate messagingTemplate(RabbitTemplate rabbitTemplate) {
|
||||
RabbitMessagingTemplate messagingTemplate = new RabbitMessagingTemplate(
|
||||
rabbitTemplate);
|
||||
messagingTemplate.setDefaultDestination("fooBar");
|
||||
return messagingTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration5 {
|
||||
|
||||
@Bean
|
||||
RabbitListenerContainerFactory<?> rabbitListenerContainerFactory() {
|
||||
return mock(SimpleRabbitListenerContainerFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class MessageConvertersConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public MessageConverter myMessageConverter() {
|
||||
return mock(MessageConverter.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageConverter anotherMessageConverter() {
|
||||
return mock(MessageConverter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class MessageRecoverersConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public MessageRecoverer myMessageRecoverer() {
|
||||
return mock(MessageRecoverer.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageRecoverer anotherMessageRecoverer() {
|
||||
return mock(MessageRecoverer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRabbit
|
||||
protected static class EnableRabbitConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class NoEnableRabbitConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.amqp;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link RabbitProperties}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class RabbitPropertiesTests {
|
||||
|
||||
private final RabbitProperties properties = new RabbitProperties();
|
||||
|
||||
@Test
|
||||
public void hostDefaultsToLocalhost() {
|
||||
assertThat(this.properties.getHost()).isEqualTo("localhost");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customHost() {
|
||||
this.properties.setHost("rabbit.example.com");
|
||||
assertThat(this.properties.getHost()).isEqualTo("rabbit.example.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hostIsDeterminedFromFirstAddress() {
|
||||
this.properties.setAddresses("rabbit1.example.com:1234,rabbit2.example.com:2345");
|
||||
assertThat(this.properties.determineHost()).isEqualTo("rabbit1.example.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineHostReturnsHostPropertyWhenNoAddresses() {
|
||||
this.properties.setHost("rabbit.example.com");
|
||||
assertThat(this.properties.determineHost()).isEqualTo("rabbit.example.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void portDefaultsTo5672() {
|
||||
assertThat(this.properties.getPort()).isEqualTo(5672);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customPort() {
|
||||
this.properties.setPort(1234);
|
||||
assertThat(this.properties.getPort()).isEqualTo(1234);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determinePortReturnsPortOfFirstAddress() {
|
||||
this.properties.setAddresses("rabbit1.example.com:1234,rabbit2.example.com:2345");
|
||||
assertThat(this.properties.determinePort()).isEqualTo(1234);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determinePortReturnsPortPropertyWhenNoAddresses() {
|
||||
this.properties.setPort(1234);
|
||||
assertThat(this.properties.determinePort()).isEqualTo(1234);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determinePortReturnsDefaultAmqpPortWhenFirstAddressHasNoExplicitPort() {
|
||||
this.properties.setPort(1234);
|
||||
this.properties.setAddresses("rabbit1.example.com,rabbit2.example.com:2345");
|
||||
assertThat(this.properties.determinePort()).isEqualTo(5672);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void virtualHostDefaultsToNull() {
|
||||
assertThat(this.properties.getVirtualHost()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customVirtualHost() {
|
||||
this.properties.setVirtualHost("alpha");
|
||||
assertThat(this.properties.getVirtualHost()).isEqualTo("alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void virtualHostRetainsALeadingSlash() {
|
||||
this.properties.setVirtualHost("/alpha");
|
||||
assertThat(this.properties.getVirtualHost()).isEqualTo("/alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineVirtualHostReturnsVirtualHostOfFirstAddress() {
|
||||
this.properties.setAddresses(
|
||||
"rabbit1.example.com:1234/alpha,rabbit2.example.com:2345/bravo");
|
||||
assertThat(this.properties.determineVirtualHost()).isEqualTo("alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineVirtualHostReturnsPropertyWhenNoAddresses() {
|
||||
this.properties.setVirtualHost("alpha");
|
||||
assertThat(this.properties.determineVirtualHost()).isEqualTo("alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineVirtualHostReturnsPropertyWhenFirstAddressHasNoVirtualHost() {
|
||||
this.properties.setVirtualHost("alpha");
|
||||
this.properties
|
||||
.setAddresses("rabbit1.example.com:1234,rabbit2.example.com:2345/bravo");
|
||||
assertThat(this.properties.determineVirtualHost()).isEqualTo("alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineVirtualHostIsSlashWhenAddressHasTrailingSlash() {
|
||||
this.properties.setAddresses("amqp://root:password@otherhost:1111/");
|
||||
assertThat(this.properties.determineVirtualHost()).isEqualTo("/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyVirtualHostIsCoercedToASlash() {
|
||||
this.properties.setVirtualHost("");
|
||||
assertThat(this.properties.getVirtualHost()).isEqualTo("/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usernameDefaultsToNull() {
|
||||
assertThat(this.properties.getUsername()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customUsername() {
|
||||
this.properties.setUsername("user");
|
||||
assertThat(this.properties.getUsername()).isEqualTo("user");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineUsernameReturnsUsernameOfFirstAddress() {
|
||||
this.properties.setAddresses("user:secret@rabbit1.example.com:1234/alpha,"
|
||||
+ "rabbit2.example.com:2345/bravo");
|
||||
assertThat(this.properties.determineUsername()).isEqualTo("user");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineUsernameReturnsPropertyWhenNoAddresses() {
|
||||
this.properties.setUsername("alice");
|
||||
assertThat(this.properties.determineUsername()).isEqualTo("alice");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineUsernameReturnsPropertyWhenFirstAddressHasNoUsername() {
|
||||
this.properties.setUsername("alice");
|
||||
this.properties.setAddresses("rabbit1.example.com:1234/alpha,"
|
||||
+ "user:secret@rabbit2.example.com:2345/bravo");
|
||||
assertThat(this.properties.determineUsername()).isEqualTo("alice");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void passwordDefaultsToNull() {
|
||||
assertThat(this.properties.getPassword()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customPassword() {
|
||||
this.properties.setPassword("secret");
|
||||
assertThat(this.properties.getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determinePasswordReturnsPasswordOfFirstAddress() {
|
||||
this.properties.setAddresses("user:secret@rabbit1.example.com:1234/alpha,"
|
||||
+ "rabbit2.example.com:2345/bravo");
|
||||
assertThat(this.properties.determinePassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determinePasswordReturnsPropertyWhenNoAddresses() {
|
||||
this.properties.setPassword("secret");
|
||||
assertThat(this.properties.determinePassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determinePasswordReturnsPropertyWhenFirstAddressHasNoPassword() {
|
||||
this.properties.setPassword("12345678");
|
||||
this.properties.setAddresses("rabbit1.example.com:1234/alpha,"
|
||||
+ "user:secret@rabbit2.example.com:2345/bravo");
|
||||
assertThat(this.properties.determinePassword()).isEqualTo("12345678");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addressesDefaultsToNull() {
|
||||
assertThat(this.properties.getAddresses()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customAddresses() {
|
||||
this.properties.setAddresses(
|
||||
"user:secret@rabbit1.example.com:1234/alpha,rabbit2.example.com");
|
||||
assertThat(this.properties.getAddresses()).isEqualTo(
|
||||
"user:secret@rabbit1.example.com:1234/alpha,rabbit2.example.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineAddressesReturnsAddressesWithJustHostAndPort() {
|
||||
this.properties.setAddresses(
|
||||
"user:secret@rabbit1.example.com:1234/alpha,rabbit2.example.com");
|
||||
assertThat(this.properties.determineAddresses())
|
||||
.isEqualTo("rabbit1.example.com:1234,rabbit2.example.com:5672");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void determineAddressesUsesHostAndPortPropertiesWhenNoAddressesSet() {
|
||||
this.properties.setHost("rabbit.example.com");
|
||||
this.properties.setPort(1234);
|
||||
assertThat(this.properties.determineAddresses())
|
||||
.isEqualTo("rabbit.example.com:1234");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.aop;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link AopAutoConfiguration}.
|
||||
*
|
||||
* @author Eberhard Wolff
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class AopAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(AopAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void aopDisabled() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.aop.auto:false").run((context) -> {
|
||||
TestAspect aspect = context.getBean(TestAspect.class);
|
||||
assertThat(aspect.isCalled()).isFalse();
|
||||
TestBean bean = context.getBean(TestBean.class);
|
||||
bean.foo();
|
||||
assertThat(aspect.isCalled()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aopWithDefaultSettings() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.run(proxyTargetClassEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aopWithEnabledProxyTargetClass() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.aop.proxy-target-class:true")
|
||||
.run(proxyTargetClassEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aopWithDisabledProxyTargetClass() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withPropertyValues("spring.aop.proxy-target-class:false")
|
||||
.run(proxyTargetClassDisabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aopWithCustomConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(CustomTestConfiguration.class)
|
||||
.run(proxyTargetClassEnabled());
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> proxyTargetClassEnabled() {
|
||||
return (context) -> {
|
||||
TestAspect aspect = context.getBean(TestAspect.class);
|
||||
assertThat(aspect.isCalled()).isFalse();
|
||||
TestBean bean = context.getBean(TestBean.class);
|
||||
bean.foo();
|
||||
assertThat(aspect.isCalled()).isTrue();
|
||||
};
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> proxyTargetClassDisabled() {
|
||||
return (context) -> {
|
||||
TestAspect aspect = context.getBean(TestAspect.class);
|
||||
assertThat(aspect.isCalled()).isFalse();
|
||||
TestInterface bean = context.getBean(TestInterface.class);
|
||||
bean.foo();
|
||||
assertThat(aspect.isCalled()).isTrue();
|
||||
assertThat(context).doesNotHaveBean(TestBean.class);
|
||||
};
|
||||
}
|
||||
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true)
|
||||
@Configuration
|
||||
@Import(TestConfiguration.class)
|
||||
protected static class CustomTestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public TestAspect aspect() {
|
||||
return new TestAspect();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestInterface bean() {
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class TestBean implements TestInterface {
|
||||
|
||||
@Override
|
||||
public void foo() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Aspect
|
||||
protected static class TestAspect {
|
||||
|
||||
private boolean called;
|
||||
|
||||
public boolean isCalled() {
|
||||
return this.called;
|
||||
}
|
||||
|
||||
@Before("execution(* foo(..))")
|
||||
public void before() {
|
||||
this.called = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface TestInterface {
|
||||
|
||||
void foo();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.batch;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.JobRegistry;
|
||||
import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean;
|
||||
import org.springframework.batch.core.job.AbstractJob;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.DatabaseInitializationMode;
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link BatchAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
* @author Vedran Pavic
|
||||
* @author Kazuki Shimizu
|
||||
*/
|
||||
public class BatchAutoConfigurationTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException expected = ExpectedException.none();
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(BatchAutoConfiguration.class,
|
||||
TransactionAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void testDefaultContext() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
assertThat(context).hasSingleBean(JobExplorer.class);
|
||||
assertThat(
|
||||
context.getBean(BatchProperties.class).getInitializeSchema())
|
||||
.isEqualTo(DatabaseInitializationMode.EMBEDDED);
|
||||
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
|
||||
.queryForList("select * from BATCH_JOB_EXECUTION")).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoDatabase() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(TestCustomConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
JobExplorer explorer = context.getBean(JobExplorer.class);
|
||||
assertThat(explorer.getJobInstances("job", 0, 100)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoBatchConfiguration() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(JobLauncher.class);
|
||||
assertThat(context).doesNotHaveBean(JobRepository.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefinesAndLaunchesJob() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(JobConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
context.getBean(JobLauncherCommandLineRunner.class).run();
|
||||
assertThat(context.getBean(JobRepository.class)
|
||||
.getLastJobExecution("job", new JobParameters())).isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefinesAndLaunchesNamedJob() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(NamedJobConfigurationWithRegisteredJob.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.batch.job.names:discreteRegisteredJob")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
context.getBean(JobLauncherCommandLineRunner.class).run();
|
||||
assertThat(context.getBean(JobRepository.class).getLastJobExecution(
|
||||
"discreteRegisteredJob", new JobParameters())).isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefinesAndLaunchesLocalJob() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(NamedJobConfigurationWithLocalJob.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.batch.job.names:discreteLocalJob")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
context.getBean(JobLauncherCommandLineRunner.class).run();
|
||||
assertThat(context.getBean(JobRepository.class)
|
||||
.getLastJobExecution("discreteLocalJob", new JobParameters()))
|
||||
.isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableLaunchesJob() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(JobConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.batch.job.enabled:false").run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
assertThat(context).doesNotHaveBean(CommandLineRunner.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableSchemaLoader() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TestConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||
"spring.batch.initialize-schema:never")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
assertThat(
|
||||
context.getBean(BatchProperties.class).getInitializeSchema())
|
||||
.isEqualTo(DatabaseInitializationMode.NEVER);
|
||||
this.expected.expect(BadSqlGrammarException.class);
|
||||
new JdbcTemplate(context.getBean(DataSource.class))
|
||||
.queryForList("select * from BATCH_JOB_EXECUTION");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsingJpa() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class).run((context) -> {
|
||||
PlatformTransactionManager transactionManager = context
|
||||
.getBean(PlatformTransactionManager.class);
|
||||
// It's a lazy proxy, but it does render its target if you ask for
|
||||
// toString():
|
||||
assertThat(transactionManager.toString()
|
||||
.contains("JpaTransactionManager")).isTrue();
|
||||
assertThat(context).hasSingleBean(EntityManagerFactory.class);
|
||||
// Ensure the JobRepository can be used (no problem with isolation
|
||||
// level)
|
||||
assertThat(context.getBean(JobRepository.class)
|
||||
.getLastJobExecution("job", new JobParameters())).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenamePrefix() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TestConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class)
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||
"spring.batch.schema:classpath:batch/custom-schema-hsql.sql",
|
||||
"spring.batch.tablePrefix:PREFIX_")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
assertThat(
|
||||
context.getBean(BatchProperties.class).getInitializeSchema())
|
||||
.isEqualTo(DatabaseInitializationMode.EMBEDDED);
|
||||
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
|
||||
.queryForList("select * from PREFIX_JOB_EXECUTION"))
|
||||
.isEmpty();
|
||||
JobExplorer jobExplorer = context.getBean(JobExplorer.class);
|
||||
assertThat(jobExplorer.findRunningJobExecutions("test")).isEmpty();
|
||||
JobRepository jobRepository = context.getBean(JobRepository.class);
|
||||
assertThat(jobRepository.getLastJobExecution("test",
|
||||
new JobParameters())).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomizeJpaTransactionManagerUsingProperties() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TestConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class)
|
||||
.withPropertyValues("spring.transaction.default-timeout:30",
|
||||
"spring.transaction.rollback-on-commit-failure:true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(BatchConfigurer.class);
|
||||
JpaTransactionManager transactionManager = JpaTransactionManager.class
|
||||
.cast(context.getBean(BatchConfigurer.class)
|
||||
.getTransactionManager());
|
||||
assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30);
|
||||
assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomizeDataSourceTransactionManagerUsingProperties()
|
||||
throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TestConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.transaction.default-timeout:30",
|
||||
"spring.transaction.rollback-on-commit-failure:true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(BatchConfigurer.class);
|
||||
DataSourceTransactionManager transactionManager = DataSourceTransactionManager.class
|
||||
.cast(context.getBean(BatchConfigurer.class)
|
||||
.getTransactionManager());
|
||||
assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30);
|
||||
assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
protected static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
protected static class TestCustomConfiguration implements BatchConfigurer {
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
|
||||
|
||||
@Override
|
||||
public JobRepository getJobRepository() throws Exception {
|
||||
if (this.jobRepository == null) {
|
||||
this.factory.afterPropertiesSet();
|
||||
this.jobRepository = this.factory.getObject();
|
||||
}
|
||||
return this.jobRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformTransactionManager getTransactionManager() throws Exception {
|
||||
return new ResourcelessTransactionManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobLauncher getJobLauncher() throws Exception {
|
||||
SimpleJobLauncher launcher = new SimpleJobLauncher();
|
||||
launcher.setJobRepository(this.jobRepository);
|
||||
return launcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobExplorer getJobExplorer() throws Exception {
|
||||
MapJobExplorerFactoryBean explorer = new MapJobExplorerFactoryBean(
|
||||
this.factory);
|
||||
explorer.afterPropertiesSet();
|
||||
return explorer.getObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
protected static class NamedJobConfigurationWithRegisteredJob {
|
||||
|
||||
@Autowired
|
||||
private JobRegistry jobRegistry;
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Bean
|
||||
public JobRegistryBeanPostProcessor registryProcessor() {
|
||||
JobRegistryBeanPostProcessor processor = new JobRegistryBeanPostProcessor();
|
||||
processor.setJobRegistry(this.jobRegistry);
|
||||
return processor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Job discreteJob() {
|
||||
AbstractJob job = new AbstractJob("discreteRegisteredJob") {
|
||||
|
||||
@Override
|
||||
public Collection<String> getStepNames() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step getStep(String stepName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecution execution)
|
||||
throws JobExecutionException {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
}
|
||||
};
|
||||
job.setJobRepository(this.jobRepository);
|
||||
return job;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
protected static class NamedJobConfigurationWithLocalJob {
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Bean
|
||||
public Job discreteJob() {
|
||||
AbstractJob job = new AbstractJob("discreteLocalJob") {
|
||||
|
||||
@Override
|
||||
public Collection<String> getStepNames() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step getStep(String stepName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecution execution)
|
||||
throws JobExecutionException {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
}
|
||||
};
|
||||
job.setJobRepository(this.jobRepository);
|
||||
return job;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
protected static class JobConfiguration {
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Bean
|
||||
public Job job() {
|
||||
AbstractJob job = new AbstractJob() {
|
||||
|
||||
@Override
|
||||
public Collection<String> getStepNames() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step getStep(String stepName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecution execution)
|
||||
throws JobExecutionException {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
}
|
||||
};
|
||||
job.setJobRepository(this.jobRepository);
|
||||
return job;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.batch;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.DatabaseInitializationMode;
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link BatchAutoConfiguration} when JPA is not on the classpath.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(ModifiedClassPathRunner.class)
|
||||
@ClassPathExclusions("hibernate-jpa-*.jar")
|
||||
public class BatchAutoConfigurationWithoutJpaTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(BatchAutoConfiguration.class,
|
||||
TransactionAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void jdbcWithDefaultSettings() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(DefaultConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
assertThat(context).hasSingleBean(JobExplorer.class);
|
||||
assertThat(context).hasSingleBean(JobRepository.class);
|
||||
assertThat(context).hasSingleBean(PlatformTransactionManager.class);
|
||||
assertThat(
|
||||
context.getBean(PlatformTransactionManager.class).toString())
|
||||
.contains("DataSourceTransactionManager");
|
||||
assertThat(
|
||||
context.getBean(BatchProperties.class).getInitializeSchema())
|
||||
.isEqualTo(DatabaseInitializationMode.EMBEDDED);
|
||||
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
|
||||
.queryForList("select * from BATCH_JOB_EXECUTION")).isEmpty();
|
||||
assertThat(context.getBean(JobExplorer.class)
|
||||
.findRunningJobExecutions("test")).isEmpty();
|
||||
assertThat(context.getBean(JobRepository.class)
|
||||
.getLastJobExecution("test", new JobParameters())).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jdbcWithCustomPrefix() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(DefaultConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.datasource.generate-unique-name=true",
|
||||
"spring.batch.schema:classpath:batch/custom-schema-hsql.sql",
|
||||
"spring.batch.tablePrefix:PREFIX_")
|
||||
.run((context) -> {
|
||||
assertThat(new JdbcTemplate(context.getBean(DataSource.class))
|
||||
.queryForList("select * from PREFIX_JOB_EXECUTION"))
|
||||
.isEmpty();
|
||||
assertThat(context.getBean(JobExplorer.class)
|
||||
.findRunningJobExecutions("test")).isEmpty();
|
||||
assertThat(context.getBean(JobRepository.class)
|
||||
.getLastJobExecution("test", new JobParameters())).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
protected static class DefaultConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.batch;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JobExecutionExitCodeGenerator}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class JobExecutionExitCodeGeneratorTests {
|
||||
|
||||
private final JobExecutionExitCodeGenerator generator = new JobExecutionExitCodeGenerator();
|
||||
|
||||
@Test
|
||||
public void testExitCodeForRunning() {
|
||||
this.generator.onApplicationEvent(new JobExecutionEvent(new JobExecution(0L)));
|
||||
assertThat(this.generator.getExitCode()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExitCodeForCompleted() {
|
||||
JobExecution execution = new JobExecution(0L);
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
this.generator.onApplicationEvent(new JobExecutionEvent(execution));
|
||||
assertThat(this.generator.getExitCode()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExitCodeForFailed() {
|
||||
JobExecution execution = new JobExecution(0L);
|
||||
execution.setStatus(BatchStatus.FAILED);
|
||||
this.generator.onApplicationEvent(new JobExecutionEvent(execution));
|
||||
assertThat(this.generator.getExitCode()).isEqualTo(5);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.batch;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
||||
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.SyncTaskExecutor;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JobLauncherCommandLineRunner}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Jean-Pierre Bergamin
|
||||
*/
|
||||
public class JobLauncherCommandLineRunnerTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
private JobLauncherCommandLineRunner runner;
|
||||
|
||||
private JobExplorer jobExplorer;
|
||||
|
||||
private JobBuilderFactory jobs;
|
||||
|
||||
private StepBuilderFactory steps;
|
||||
|
||||
private Job job;
|
||||
|
||||
private Step step;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
this.context.register(BatchConfiguration.class);
|
||||
this.context.refresh();
|
||||
JobRepository jobRepository = this.context.getBean(JobRepository.class);
|
||||
JobLauncher jobLauncher = this.context.getBean(JobLauncher.class);
|
||||
this.jobs = new JobBuilderFactory(jobRepository);
|
||||
PlatformTransactionManager transactionManager = this.context
|
||||
.getBean(PlatformTransactionManager.class);
|
||||
this.steps = new StepBuilderFactory(jobRepository, transactionManager);
|
||||
Tasklet tasklet = (contribution, chunkContext) -> null;
|
||||
this.step = this.steps.get("step").tasklet(tasklet).build();
|
||||
this.job = this.jobs.get("job").start(this.step).build();
|
||||
this.jobExplorer = this.context.getBean(JobExplorer.class);
|
||||
this.runner = new JobLauncherCommandLineRunner(jobLauncher, this.jobExplorer);
|
||||
this.context.getBean(BatchConfiguration.class).clear();
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicExecution() throws Exception {
|
||||
this.runner.execute(this.job, new JobParameters());
|
||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
||||
this.runner.execute(this.job,
|
||||
new JobParametersBuilder().addLong("id", 1L).toJobParameters());
|
||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incrementExistingExecution() throws Exception {
|
||||
this.job = this.jobs.get("job").start(this.step)
|
||||
.incrementer(new RunIdIncrementer()).build();
|
||||
this.runner.execute(this.job, new JobParameters());
|
||||
this.runner.execute(this.job, new JobParameters());
|
||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryFailedExecution() throws Exception {
|
||||
this.job = this.jobs.get("job")
|
||||
.start(this.steps.get("step").tasklet(throwingTasklet()).build())
|
||||
.incrementer(new RunIdIncrementer()).build();
|
||||
this.runner.execute(this.job, new JobParameters());
|
||||
this.runner.execute(this.job, new JobParameters());
|
||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryFailedExecutionOnNonRestartableJob() throws Exception {
|
||||
this.job = this.jobs.get("job").preventRestart()
|
||||
.start(this.steps.get("step").tasklet(throwingTasklet()).build())
|
||||
.incrementer(new RunIdIncrementer()).build();
|
||||
this.runner.execute(this.job, new JobParameters());
|
||||
this.runner.execute(this.job, new JobParameters());
|
||||
// A failed job that is not restartable does not re-use the job params of
|
||||
// the last execution, but creates a new job instance when running it again.
|
||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryFailedExecutionWithNonIdentifyingParameters() throws Exception {
|
||||
this.job = this.jobs.get("job")
|
||||
.start(this.steps.get("step").tasklet(throwingTasklet()).build())
|
||||
.incrementer(new RunIdIncrementer()).build();
|
||||
JobParameters jobParameters = new JobParametersBuilder().addLong("id", 1L, false)
|
||||
.addLong("foo", 2L, false).toJobParameters();
|
||||
this.runner.execute(this.job, jobParameters);
|
||||
this.runner.execute(this.job, jobParameters);
|
||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
||||
}
|
||||
|
||||
private Tasklet throwingTasklet() {
|
||||
return (contribution, chunkContext) -> {
|
||||
throw new RuntimeException("Planned");
|
||||
};
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
protected static class BatchConfiguration implements BatchConfigurer {
|
||||
|
||||
private ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager();
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private MapJobRepositoryFactoryBean jobRepositoryFactory = new MapJobRepositoryFactoryBean(
|
||||
this.transactionManager);
|
||||
|
||||
public BatchConfiguration() throws Exception {
|
||||
this.jobRepository = this.jobRepositoryFactory.getObject();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.jobRepositoryFactory.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobRepository getJobRepository() throws Exception {
|
||||
return this.jobRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformTransactionManager getTransactionManager() throws Exception {
|
||||
return this.transactionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobLauncher getJobLauncher() throws Exception {
|
||||
SimpleJobLauncher launcher = new SimpleJobLauncher();
|
||||
launcher.setJobRepository(this.jobRepository);
|
||||
launcher.setTaskExecutor(new SyncTaskExecutor());
|
||||
return launcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobExplorer getJobExplorer() throws Exception {
|
||||
return new MapJobExplorerFactoryBean(this.jobRepositoryFactory).getObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CacheManagerCustomizersTests {
|
||||
|
||||
@Test
|
||||
public void customizeWithNullCustomizersShouldDoNothing() {
|
||||
new CacheManagerCustomizers(null).customize(mock(CacheManager.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeSimpleCacheManager() {
|
||||
CacheManagerCustomizers customizers = new CacheManagerCustomizers(
|
||||
Collections.singletonList(new CacheNamesCacheManagerCustomizer()));
|
||||
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
|
||||
customizers.customize(cacheManager);
|
||||
assertThat(cacheManager.getCacheNames()).containsOnly("one", "two");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeShouldCheckGeneric() throws Exception {
|
||||
List<TestCustomizer<?>> list = new ArrayList<>();
|
||||
list.add(new TestCustomizer<>());
|
||||
list.add(new TestConcurrentMapCacheManagerCustomizer());
|
||||
CacheManagerCustomizers customizers = new CacheManagerCustomizers(list);
|
||||
customizers.customize(mock(CacheManager.class));
|
||||
assertThat(list.get(0).getCount()).isEqualTo(1);
|
||||
assertThat(list.get(1).getCount()).isEqualTo(0);
|
||||
customizers.customize(mock(ConcurrentMapCacheManager.class));
|
||||
assertThat(list.get(0).getCount()).isEqualTo(2);
|
||||
assertThat(list.get(1).getCount()).isEqualTo(1);
|
||||
customizers.customize(mock(CaffeineCacheManager.class));
|
||||
assertThat(list.get(0).getCount()).isEqualTo(3);
|
||||
assertThat(list.get(1).getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
static class CacheNamesCacheManagerCustomizer
|
||||
implements CacheManagerCustomizer<ConcurrentMapCacheManager> {
|
||||
|
||||
@Override
|
||||
public void customize(ConcurrentMapCacheManager cacheManager) {
|
||||
cacheManager.setCacheNames(Arrays.asList("one", "two"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestCustomizer<T extends CacheManager>
|
||||
implements CacheManagerCustomizer<T> {
|
||||
|
||||
private int count;
|
||||
|
||||
@Override
|
||||
public void customize(T cacheManager) {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestConcurrentMapCacheManagerCustomizer
|
||||
extends TestCustomizer<ConcurrentMapCacheManager> {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.cache.support;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.cache.Cache;
|
||||
import javax.cache.CacheManager;
|
||||
import javax.cache.configuration.Configuration;
|
||||
import javax.cache.configuration.OptionalFeature;
|
||||
import javax.cache.spi.CachingProvider;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* A mock {@link CachingProvider} that exposes a JSR-107 cache manager for testing
|
||||
* purposes.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class MockCachingProvider implements CachingProvider {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public CacheManager getCacheManager(URI uri, ClassLoader classLoader,
|
||||
Properties properties) {
|
||||
CacheManager cacheManager = mock(CacheManager.class);
|
||||
given(cacheManager.getURI()).willReturn(uri);
|
||||
given(cacheManager.getClassLoader()).willReturn(classLoader);
|
||||
final Map<String, Cache> caches = new HashMap<>();
|
||||
given(cacheManager.getCacheNames()).willReturn(caches.keySet());
|
||||
given(cacheManager.getCache(anyString())).willAnswer((invocation) -> {
|
||||
String cacheName = (String) invocation.getArguments()[0];
|
||||
return caches.get(cacheName);
|
||||
});
|
||||
given(cacheManager.createCache(anyString(), any(Configuration.class)))
|
||||
.will((invocation) -> {
|
||||
String cacheName = (String) invocation.getArguments()[0];
|
||||
Cache cache = mock(Cache.class);
|
||||
given(cache.getName()).willReturn(cacheName);
|
||||
caches.put(cacheName, cache);
|
||||
return cache;
|
||||
});
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getDefaultClassLoader() {
|
||||
return mock(ClassLoader.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getDefaultURI() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getDefaultProperties() {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CacheManager getCacheManager(URI uri, ClassLoader classLoader) {
|
||||
return getCacheManager(uri, classLoader, getDefaultProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CacheManager getCacheManager() {
|
||||
return getCacheManager(getDefaultURI(), getDefaultClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(ClassLoader classLoader) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(URI uri, ClassLoader classLoader) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(OptionalFeature optionalFeature) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.cassandra;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.datastax.driver.core.PoolingOptions;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
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;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CassandraAutoConfiguration}
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CassandraAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(CassandraAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void createClusterWithDefault() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(Cluster.class);
|
||||
assertThat(context.getBean(Cluster.class).getClusterName())
|
||||
.startsWith("cluster");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createClusterWithOverrides() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.data.cassandra.cluster-name=testcluster")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(Cluster.class);
|
||||
assertThat(context.getBean(Cluster.class).getClusterName())
|
||||
.isEqualTo("testcluster");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createCustomizeCluster() {
|
||||
this.contextRunner.withUserConfiguration(MockCustomizerConfig.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(Cluster.class);
|
||||
assertThat(context).hasSingleBean(ClusterBuilderCustomizer.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizerOverridesAutoConfig() {
|
||||
this.contextRunner.withUserConfiguration(SimpleCustomizerConfig.class)
|
||||
.withPropertyValues("spring.data.cassandra.cluster-name=testcluster")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(Cluster.class);
|
||||
assertThat(context.getBean(Cluster.class).getClusterName())
|
||||
.isEqualTo("overridden-name");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultPoolOptions() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(Cluster.class);
|
||||
PoolingOptions poolingOptions = context.getBean(Cluster.class)
|
||||
.getConfiguration().getPoolingOptions();
|
||||
assertThat(poolingOptions.getIdleTimeoutSeconds())
|
||||
.isEqualTo(PoolingOptions.DEFAULT_IDLE_TIMEOUT_SECONDS);
|
||||
assertThat(poolingOptions.getPoolTimeoutMillis())
|
||||
.isEqualTo(PoolingOptions.DEFAULT_POOL_TIMEOUT_MILLIS);
|
||||
assertThat(poolingOptions.getHeartbeatIntervalSeconds())
|
||||
.isEqualTo(PoolingOptions.DEFAULT_HEARTBEAT_INTERVAL_SECONDS);
|
||||
assertThat(poolingOptions.getMaxQueueSize())
|
||||
.isEqualTo(PoolingOptions.DEFAULT_MAX_QUEUE_SIZE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizePoolOptions() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.data.cassandra.pool.idle-timeout=42",
|
||||
"spring.data.cassandra.pool.pool-timeout=52",
|
||||
"spring.data.cassandra.pool.heartbeat-interval=62",
|
||||
"spring.data.cassandra.pool.max-queue-size=72")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(Cluster.class);
|
||||
PoolingOptions poolingOptions = context.getBean(Cluster.class)
|
||||
.getConfiguration().getPoolingOptions();
|
||||
assertThat(poolingOptions.getIdleTimeoutSeconds()).isEqualTo(42);
|
||||
assertThat(poolingOptions.getPoolTimeoutMillis()).isEqualTo(52);
|
||||
assertThat(poolingOptions.getHeartbeatIntervalSeconds())
|
||||
.isEqualTo(62);
|
||||
assertThat(poolingOptions.getMaxQueueSize()).isEqualTo(72);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class MockCustomizerConfig {
|
||||
|
||||
@Bean
|
||||
public ClusterBuilderCustomizer customizer() {
|
||||
return mock(ClusterBuilderCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class SimpleCustomizerConfig {
|
||||
|
||||
@Bean
|
||||
public ClusterBuilderCustomizer customizer() {
|
||||
return (clusterBuilder) -> clusterBuilder.withClusterName("overridden-name");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.cloud;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationSorter;
|
||||
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link CloudAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class CloudAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testOrder() throws Exception {
|
||||
TestAutoConfigurationSorter sorter = new TestAutoConfigurationSorter(
|
||||
new CachingMetadataReaderFactory());
|
||||
Collection<String> classNames = new ArrayList<>();
|
||||
classNames.add(MongoAutoConfiguration.class.getName());
|
||||
classNames.add(DataSourceAutoConfiguration.class.getName());
|
||||
classNames.add(MongoRepositoriesAutoConfiguration.class.getName());
|
||||
classNames.add(JpaRepositoriesAutoConfiguration.class.getName());
|
||||
classNames.add(CloudAutoConfiguration.class.getName());
|
||||
List<String> ordered = sorter.getInPriorityOrder(classNames);
|
||||
assertThat(ordered.get(0)).isEqualTo(CloudAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link AllNestedConditions}.
|
||||
*/
|
||||
public class AllNestedConditionsTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
public void neither() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(Config.class).run(match(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyA() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(Config.class).withPropertyValues("a:a")
|
||||
.run(match(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyB() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(Config.class).withPropertyValues("b:b")
|
||||
.run(match(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void both() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(Config.class)
|
||||
.withPropertyValues("a:a", "b:b").run(match(true));
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> match(boolean expected) {
|
||||
return (context) -> {
|
||||
if (expected) {
|
||||
assertThat(context).hasBean("myBean");
|
||||
}
|
||||
else {
|
||||
assertThat(context).doesNotHaveBean("myBean");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional(OnPropertyAAndBCondition.class)
|
||||
public static class Config {
|
||||
|
||||
@Bean
|
||||
public String myBean() {
|
||||
return "myBean";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class OnPropertyAAndBCondition extends AllNestedConditions {
|
||||
|
||||
OnPropertyAAndBCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty("a")
|
||||
static class HasPropertyA {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty("b")
|
||||
static class HasPropertyB {
|
||||
|
||||
}
|
||||
|
||||
@Conditional(NonSpringBootCondition.class)
|
||||
static class SubclassC {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NonSpringBootCondition implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link AnyNestedCondition}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class AnyNestedConditionTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
public void neither() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(Config.class).run(match(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyA() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(Config.class).withPropertyValues("a:a")
|
||||
.run(match(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyB() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(Config.class).withPropertyValues("b:b")
|
||||
.run(match(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void both() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(Config.class)
|
||||
.withPropertyValues("a:a", "b:b").run(match(true));
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> match(boolean expected) {
|
||||
return (context) -> {
|
||||
if (expected) {
|
||||
assertThat(context).hasBean("myBean");
|
||||
}
|
||||
else {
|
||||
assertThat(context).doesNotHaveBean("myBean");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional(OnPropertyAorBCondition.class)
|
||||
public static class Config {
|
||||
|
||||
@Bean
|
||||
public String myBean() {
|
||||
return "myBean";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class OnPropertyAorBCondition extends AnyNestedCondition {
|
||||
|
||||
OnPropertyAorBCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty("a")
|
||||
static class HasPropertyA {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnExpression("true")
|
||||
@ConditionalOnProperty("b")
|
||||
static class HasPropertyB {
|
||||
|
||||
}
|
||||
|
||||
@Conditional(NonSpringBootCondition.class)
|
||||
static class SubclassC {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NonSpringBootCondition implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationImportEvent;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationImportListener;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionEvaluationReportAutoConfigurationImportListener}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ConditionEvaluationReportAutoConfigurationImportListenerTests {
|
||||
|
||||
private ConditionEvaluationReportAutoConfigurationImportListener listener;
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.listener = new ConditionEvaluationReportAutoConfigurationImportListener();
|
||||
this.listener.setBeanFactory(this.beanFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeInSpringFactories() throws Exception {
|
||||
List<AutoConfigurationImportListener> factories = SpringFactoriesLoader
|
||||
.loadFactories(AutoConfigurationImportListener.class, null);
|
||||
assertThat(factories).hasAtLeastOneElementOfType(
|
||||
ConditionEvaluationReportAutoConfigurationImportListener.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAutoConfigurationImportEventShouldRecordCandidates() throws Exception {
|
||||
List<String> candidateConfigurations = Collections.singletonList("Test");
|
||||
Set<String> exclusions = Collections.emptySet();
|
||||
AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this,
|
||||
candidateConfigurations, exclusions);
|
||||
this.listener.onAutoConfigurationImportEvent(event);
|
||||
ConditionEvaluationReport report = ConditionEvaluationReport
|
||||
.get(this.beanFactory);
|
||||
assertThat(report.getUnconditionalClasses())
|
||||
.containsExactlyElementsOf(candidateConfigurations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAutoConfigurationImportEventShouldRecordExclusions() throws Exception {
|
||||
List<String> candidateConfigurations = Collections.emptyList();
|
||||
Set<String> exclusions = Collections.singleton("Test");
|
||||
AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this,
|
||||
candidateConfigurations, exclusions);
|
||||
this.listener.onAutoConfigurationImportEvent(event);
|
||||
ConditionEvaluationReport report = ConditionEvaluationReport
|
||||
.get(this.beanFactory);
|
||||
assertThat(report.getExclusions()).containsExactlyElementsOf(exclusions);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcome;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcomes;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.testsupport.assertj.Matched;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ConfigurationCondition;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionEvaluationReport}.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ConditionEvaluationReportTests {
|
||||
|
||||
private DefaultListableBeanFactory beanFactory;
|
||||
|
||||
private ConditionEvaluationReport report;
|
||||
|
||||
@Mock
|
||||
private Condition condition1;
|
||||
|
||||
@Mock
|
||||
private Condition condition2;
|
||||
|
||||
@Mock
|
||||
private Condition condition3;
|
||||
|
||||
private ConditionOutcome outcome1;
|
||||
|
||||
private ConditionOutcome outcome2;
|
||||
|
||||
private ConditionOutcome outcome3;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.beanFactory = new DefaultListableBeanFactory();
|
||||
this.report = ConditionEvaluationReport.get(this.beanFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get() throws Exception {
|
||||
assertThat(this.report).isNotEqualTo(nullValue());
|
||||
assertThat(this.report).isSameAs(ConditionEvaluationReport.get(this.beanFactory));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parent() throws Exception {
|
||||
this.beanFactory.setParentBeanFactory(new DefaultListableBeanFactory());
|
||||
ConditionEvaluationReport.get((ConfigurableListableBeanFactory) this.beanFactory
|
||||
.getParentBeanFactory());
|
||||
assertThat(this.report).isSameAs(ConditionEvaluationReport.get(this.beanFactory));
|
||||
assertThat(this.report).isNotEqualTo(nullValue());
|
||||
assertThat(this.report.getParent()).isNotEqualTo(nullValue());
|
||||
ConditionEvaluationReport.get((ConfigurableListableBeanFactory) this.beanFactory
|
||||
.getParentBeanFactory());
|
||||
assertThat(this.report).isSameAs(ConditionEvaluationReport.get(this.beanFactory));
|
||||
assertThat(this.report.getParent()).isSameAs(ConditionEvaluationReport
|
||||
.get((ConfigurableListableBeanFactory) this.beanFactory
|
||||
.getParentBeanFactory()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parentBottomUp() throws Exception {
|
||||
this.beanFactory = new DefaultListableBeanFactory(); // NB: overrides setup
|
||||
this.beanFactory.setParentBeanFactory(new DefaultListableBeanFactory());
|
||||
ConditionEvaluationReport.get((ConfigurableListableBeanFactory) this.beanFactory
|
||||
.getParentBeanFactory());
|
||||
this.report = ConditionEvaluationReport.get(this.beanFactory);
|
||||
assertThat(this.report).isNotNull();
|
||||
assertThat(this.report).isNotSameAs(this.report.getParent());
|
||||
assertThat(this.report.getParent()).isNotNull();
|
||||
assertThat(this.report.getParent().getParent()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordConditionEvaluations() throws Exception {
|
||||
this.outcome1 = new ConditionOutcome(false, "m1");
|
||||
this.outcome2 = new ConditionOutcome(false, "m2");
|
||||
this.outcome3 = new ConditionOutcome(false, "m3");
|
||||
this.report.recordConditionEvaluation("a", this.condition1, this.outcome1);
|
||||
this.report.recordConditionEvaluation("a", this.condition2, this.outcome2);
|
||||
this.report.recordConditionEvaluation("b", this.condition3, this.outcome3);
|
||||
Map<String, ConditionAndOutcomes> map = this.report
|
||||
.getConditionAndOutcomesBySource();
|
||||
assertThat(map.size()).isEqualTo(2);
|
||||
Iterator<ConditionAndOutcome> iterator = map.get("a").iterator();
|
||||
|
||||
ConditionAndOutcome conditionAndOutcome = iterator.next();
|
||||
assertThat(conditionAndOutcome.getCondition()).isEqualTo(this.condition1);
|
||||
assertThat(conditionAndOutcome.getOutcome()).isEqualTo(this.outcome1);
|
||||
|
||||
conditionAndOutcome = iterator.next();
|
||||
assertThat(conditionAndOutcome.getCondition()).isEqualTo(this.condition2);
|
||||
assertThat(conditionAndOutcome.getOutcome()).isEqualTo(this.outcome2);
|
||||
assertThat(iterator.hasNext()).isFalse();
|
||||
|
||||
iterator = map.get("b").iterator();
|
||||
conditionAndOutcome = iterator.next();
|
||||
assertThat(conditionAndOutcome.getCondition()).isEqualTo(this.condition3);
|
||||
assertThat(conditionAndOutcome.getOutcome()).isEqualTo(this.outcome3);
|
||||
assertThat(iterator.hasNext()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fullMatch() throws Exception {
|
||||
prepareMatches(true, true, true);
|
||||
assertThat(this.report.getConditionAndOutcomesBySource().get("a").isFullMatch())
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notFullMatch() throws Exception {
|
||||
prepareMatches(true, false, true);
|
||||
assertThat(this.report.getConditionAndOutcomesBySource().get("a").isFullMatch())
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private void prepareMatches(boolean m1, boolean m2, boolean m3) {
|
||||
this.outcome1 = new ConditionOutcome(m1, "m1");
|
||||
this.outcome2 = new ConditionOutcome(m2, "m2");
|
||||
this.outcome3 = new ConditionOutcome(m3, "m3");
|
||||
this.report.recordConditionEvaluation("a", this.condition1, this.outcome1);
|
||||
this.report.recordConditionEvaluation("a", this.condition2, this.outcome2);
|
||||
this.report.recordConditionEvaluation("a", this.condition3, this.outcome3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void springBootConditionPopulatesReport() throws Exception {
|
||||
ConditionEvaluationReport report = ConditionEvaluationReport.get(
|
||||
new AnnotationConfigApplicationContext(Config.class).getBeanFactory());
|
||||
assertThat(report.getConditionAndOutcomesBySource().size()).isNotEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateConditionAndOutcomes() {
|
||||
ConditionAndOutcome outcome1 = new ConditionAndOutcome(this.condition1,
|
||||
new ConditionOutcome(true, "Message 1"));
|
||||
ConditionAndOutcome outcome2 = new ConditionAndOutcome(this.condition2,
|
||||
new ConditionOutcome(true, "Message 2"));
|
||||
ConditionAndOutcome outcome3 = new ConditionAndOutcome(this.condition3,
|
||||
new ConditionOutcome(true, "Message 2"));
|
||||
|
||||
assertThat(outcome1).isEqualTo(outcome1);
|
||||
assertThat(outcome1).isNotEqualTo(outcome2);
|
||||
assertThat(outcome2).isEqualTo(outcome3);
|
||||
|
||||
ConditionAndOutcomes outcomes = new ConditionAndOutcomes();
|
||||
outcomes.add(this.condition1, new ConditionOutcome(true, "Message 1"));
|
||||
outcomes.add(this.condition2, new ConditionOutcome(true, "Message 2"));
|
||||
outcomes.add(this.condition3, new ConditionOutcome(true, "Message 2"));
|
||||
|
||||
assertThat(getNumberOfOutcomes(outcomes)).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void duplicateOutcomes() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
DuplicateConfig.class);
|
||||
ConditionEvaluationReport report = ConditionEvaluationReport
|
||||
.get(context.getBeanFactory());
|
||||
String autoconfigKey = MultipartAutoConfiguration.class.getName();
|
||||
|
||||
ConditionAndOutcomes outcomes = report.getConditionAndOutcomesBySource()
|
||||
.get(autoconfigKey);
|
||||
assertThat(outcomes).isNotEqualTo(nullValue());
|
||||
assertThat(getNumberOfOutcomes(outcomes)).isEqualTo(2);
|
||||
|
||||
List<String> messages = new ArrayList<>();
|
||||
for (ConditionAndOutcome outcome : outcomes) {
|
||||
messages.add(outcome.getOutcome().getMessage());
|
||||
}
|
||||
assertThat(messages).areAtLeastOne(
|
||||
Matched.by(containsString("@ConditionalOnClass found required classes "
|
||||
+ "'javax.servlet.Servlet', 'org.springframework.web.multipart."
|
||||
+ "support.StandardServletMultipartResolver', "
|
||||
+ "'javax.servlet.MultipartConfigElement'")));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void negativeOuterPositiveInnerBean() throws Exception {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("test.present=true").applyTo(context);
|
||||
context.register(NegativeOuterConfig.class);
|
||||
context.refresh();
|
||||
ConditionEvaluationReport report = ConditionEvaluationReport
|
||||
.get(context.getBeanFactory());
|
||||
Map<String, ConditionAndOutcomes> sourceOutcomes = report
|
||||
.getConditionAndOutcomesBySource();
|
||||
assertThat(context.containsBean("negativeOuterPositiveInnerBean")).isFalse();
|
||||
String negativeConfig = NegativeOuterConfig.class.getName();
|
||||
assertThat(sourceOutcomes.get(negativeConfig).isFullMatch()).isFalse();
|
||||
String positiveConfig = NegativeOuterConfig.PositiveInnerConfig.class.getName();
|
||||
assertThat(sourceOutcomes.get(positiveConfig).isFullMatch()).isFalse();
|
||||
}
|
||||
|
||||
private int getNumberOfOutcomes(ConditionAndOutcomes outcomes) {
|
||||
Iterator<ConditionAndOutcome> iterator = outcomes.iterator();
|
||||
int numberOfOutcomesAdded = 0;
|
||||
while (iterator.hasNext()) {
|
||||
numberOfOutcomesAdded++;
|
||||
iterator.next();
|
||||
}
|
||||
return numberOfOutcomesAdded;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(WebMvcAutoConfiguration.class)
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(MultipartAutoConfiguration.class)
|
||||
static class DuplicateConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional({ ConditionEvaluationReportTests.MatchParseCondition.class,
|
||||
ConditionEvaluationReportTests.NoMatchBeanCondition.class })
|
||||
public static class NegativeOuterConfig {
|
||||
|
||||
@Configuration
|
||||
@Conditional({ ConditionEvaluationReportTests.MatchParseCondition.class })
|
||||
public static class PositiveInnerConfig {
|
||||
|
||||
@Bean
|
||||
public String negativeOuterPositiveInnerBean() {
|
||||
return "negativeOuterPositiveInnerBean";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestMatchCondition extends SpringBootCondition
|
||||
implements ConfigurationCondition {
|
||||
|
||||
private final ConfigurationPhase phase;
|
||||
|
||||
private final boolean match;
|
||||
|
||||
TestMatchCondition(ConfigurationPhase phase, boolean match) {
|
||||
this.phase = phase;
|
||||
this.match = match;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationPhase getConfigurationPhase() {
|
||||
return this.phase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
return new ConditionOutcome(this.match, ClassUtils.getShortName(getClass()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MatchParseCondition extends TestMatchCondition {
|
||||
|
||||
MatchParseCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MatchBeanCondition extends TestMatchCondition {
|
||||
|
||||
MatchBeanCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NoMatchParseCondition extends TestMatchCondition {
|
||||
|
||||
NoMatchParseCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NoMatchBeanCondition extends TestMatchCondition {
|
||||
|
||||
NoMatchBeanCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Style;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionMessage}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ConditionMessageTests {
|
||||
|
||||
@Test
|
||||
public void isEmptyWhenEmptyShouldReturnTrue() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.empty();
|
||||
assertThat(message.isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEmptyWhenNotEmptyShouldReturnFalse() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.of("Test");
|
||||
assertThat(message.isEmpty()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringWhenEmptyShouldReturnEmptyString() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.empty();
|
||||
assertThat(message.toString()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringWhenHasMessageShouldReturnMessage() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.of("Test");
|
||||
assertThat(message.toString()).isEqualTo("Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendWhenHasExistingMessageShouldAddSpace() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.of("a").append("b");
|
||||
assertThat(message.toString()).isEqualTo("a b");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendWhenAppendingNullShouldDoNothing() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.of("a").append(null);
|
||||
assertThat(message.toString()).isEqualTo("a");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendWhenNoMessageShouldNotAddSpace() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.empty().append("b");
|
||||
assertThat(message.toString()).isEqualTo("b");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andConditionWhenUsingClassShouldIncludeCondition() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.empty().andCondition(Test.class)
|
||||
.because("OK");
|
||||
assertThat(message.toString()).isEqualTo("@Test OK");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andConditionWhenUsingStringShouldIncludeCondition() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.empty().andCondition("@Test")
|
||||
.because("OK");
|
||||
assertThat(message.toString()).isEqualTo("@Test OK");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andConditionWhenIncludingDetailsShouldIncludeCondition()
|
||||
throws Exception {
|
||||
ConditionMessage message = ConditionMessage.empty()
|
||||
.andCondition(Test.class, "(a=b)").because("OK");
|
||||
assertThat(message.toString()).isEqualTo("@Test (a=b) OK");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ofCollectionShouldCombine() throws Exception {
|
||||
List<ConditionMessage> messages = new ArrayList<>();
|
||||
messages.add(ConditionMessage.of("a"));
|
||||
messages.add(ConditionMessage.of("b"));
|
||||
ConditionMessage message = ConditionMessage.of(messages);
|
||||
assertThat(message.toString()).isEqualTo("a; b");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ofCollectionWhenNullShouldReturnEmpty() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.of((List<ConditionMessage>) null);
|
||||
assertThat(message.isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forConditionShouldIncludeCondition() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition("@Test").because("OK");
|
||||
assertThat(message.toString()).isEqualTo("@Test OK");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forConditionShouldNotAddExtraSpaceWithEmptyCondition() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition("").because("OK");
|
||||
assertThat(message.toString()).isEqualTo("OK");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forConditionWhenClassShouldIncludeCondition() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class, "(a=b)")
|
||||
.because("OK");
|
||||
assertThat(message.toString()).isEqualTo("@Test (a=b) OK");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void foundExactlyShouldConstructMessage() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.foundExactly("abc");
|
||||
assertThat(message.toString()).isEqualTo("@Test found abc");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void foundWhenSingleElementShouldUseSingular() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.found("bean", "beans").items("a");
|
||||
assertThat(message.toString()).isEqualTo("@Test found bean a");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void foundNoneAtAllShouldConstructMessage() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.found("no beans").atAll();
|
||||
assertThat(message.toString()).isEqualTo("@Test found no beans");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void foundWhenMultipleElementsShouldUsePlural() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.found("bean", "beans").items("a", "b", "c");
|
||||
assertThat(message.toString()).isEqualTo("@Test found beans a, b, c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void foundWhenQuoteStyleShouldQuote() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.found("bean", "beans").items(Style.QUOTE, "a", "b", "c");
|
||||
assertThat(message.toString()).isEqualTo("@Test found beans 'a', 'b', 'c'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void didNotFindWhenSingleElementShouldUseSingular() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.didNotFind("class", "classes").items("a");
|
||||
assertThat(message.toString()).isEqualTo("@Test did not find class a");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void didNotFindWhenMultipleElementsShouldUsePlural() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.didNotFind("class", "classes").items("a", "b", "c");
|
||||
assertThat(message.toString()).isEqualTo("@Test did not find classes a, b, c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resultedInShouldConstructMessage() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.resultedIn("Green");
|
||||
assertThat(message.toString()).isEqualTo("@Test resulted in Green");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notAvailableShouldConstructMessage() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.notAvailable("JMX");
|
||||
assertThat(message.toString()).isEqualTo("@Test JMX is not available");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void availableShouldConstructMessage() throws Exception {
|
||||
ConditionMessage message = ConditionMessage.forCondition(Test.class)
|
||||
.available("JMX");
|
||||
assertThat(message.toString()).isEqualTo("@Test JMX is available");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
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 java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
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 org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnBean}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConditionalOnBeanTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
public void testNameOnBeanCondition() {
|
||||
this.contextRunner.withUserConfiguration(FooConfiguration.class,
|
||||
OnBeanNameConfiguration.class).run(this::hasBarBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameAndTypeOnBeanCondition() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(FooConfiguration.class,
|
||||
OnBeanNameAndTypeConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameOnBeanConditionReverseOrder() {
|
||||
// Ideally this should be true
|
||||
this.contextRunner
|
||||
.withUserConfiguration(OnBeanNameConfiguration.class,
|
||||
FooConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassOnBeanCondition() {
|
||||
this.contextRunner.withUserConfiguration(FooConfiguration.class,
|
||||
OnBeanClassConfiguration.class).run(this::hasBarBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassOnBeanClassNameCondition() {
|
||||
this.contextRunner.withUserConfiguration(FooConfiguration.class,
|
||||
OnBeanClassNameConfiguration.class).run(this::hasBarBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBeanConditionWithXml() {
|
||||
this.contextRunner.withUserConfiguration(XmlConfiguration.class,
|
||||
OnBeanNameConfiguration.class).run(this::hasBarBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBeanConditionWithCombinedXml() {
|
||||
// Ideally this should be true
|
||||
this.contextRunner.withUserConfiguration(CombinedXmlConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnBeanCondition() {
|
||||
this.contextRunner.withUserConfiguration(FooConfiguration.class,
|
||||
OnAnnotationConfiguration.class).run(this::hasBarBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanType() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(FooConfiguration.class,
|
||||
OnBeanMissingClassConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withPropertyPlaceholderClassName() throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(PropertySourcesPlaceholderConfigurer.class,
|
||||
WithPropertyPlaceholderClassName.class,
|
||||
OnBeanClassConfiguration.class)
|
||||
.withPropertyValues("mybeanclass=java.lang.String")
|
||||
.run((context) -> assertThat(context).hasNotFailed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanProducedByFactoryBeanIsConsideredWhenMatchingOnAnnotation() {
|
||||
this.contextRunner.withUserConfiguration(FactoryBeanConfiguration.class,
|
||||
OnAnnotationWithFactoryBeanConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("bar");
|
||||
assertThat(context).hasSingleBean(ExampleBean.class);
|
||||
});
|
||||
}
|
||||
|
||||
private void hasBarBean(AssertableApplicationContext context) {
|
||||
assertThat(context).hasBean("bar");
|
||||
assertThat(context.getBean("bar")).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(name = "foo")
|
||||
protected static class OnBeanNameConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(name = "foo", value = Date.class)
|
||||
protected static class OnBeanNameAndTypeConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(annotation = EnableScheduling.class)
|
||||
protected static class OnAnnotationConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(String.class)
|
||||
protected static class OnBeanClassConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(type = "java.lang.String")
|
||||
protected static class OnBeanClassNameConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(type = "some.type.Missing")
|
||||
protected static class OnBeanMissingClassConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
protected static class FooConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("org/springframework/boot/autoconfigure/condition/foo.xml")
|
||||
protected static class XmlConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("org/springframework/boot/autoconfigure/condition/foo.xml")
|
||||
@Import(OnBeanNameConfiguration.class)
|
||||
protected static class CombinedXmlConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(WithPropertyPlaceholderClassNameRegistrar.class)
|
||||
protected static class WithPropertyPlaceholderClassName {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class FactoryBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public ExampleFactoryBean exampleBeanFactoryBean() {
|
||||
return new ExampleFactoryBean();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(annotation = TestAnnotation.class)
|
||||
static class OnAnnotationWithFactoryBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class WithPropertyPlaceholderClassNameRegistrar
|
||||
implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
RootBeanDefinition bd = new RootBeanDefinition();
|
||||
bd.setBeanClassName("${mybeanclass}");
|
||||
registry.registerBeanDefinition("mybean", bd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ExampleFactoryBean implements FactoryBean<ExampleBean> {
|
||||
|
||||
@Override
|
||||
public ExampleBean getObject() throws Exception {
|
||||
return new ExampleBean("fromFactory");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return ExampleBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation
|
||||
public static class ExampleBean {
|
||||
|
||||
private String value;
|
||||
|
||||
public ExampleBean(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface TestAnnotation {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
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 org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnClass}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConditionalOnClassTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
public void testVanillaOnClassCondition() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(BasicConfiguration.class, FooConfiguration.class)
|
||||
.run(this::hasBarBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingOnClassCondition() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(MissingConfiguration.class, FooConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).doesNotHaveBean("bar");
|
||||
assertThat(context).hasBean("foo");
|
||||
assertThat(context.getBean("foo")).isEqualTo("foo");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClassConditionWithXml() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(BasicConfiguration.class, XmlConfiguration.class)
|
||||
.run(this::hasBarBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClassConditionWithCombinedXml() {
|
||||
this.contextRunner.withUserConfiguration(CombinedXmlConfiguration.class)
|
||||
.run(this::hasBarBean);
|
||||
}
|
||||
|
||||
private void hasBarBean(AssertableApplicationContext context) {
|
||||
assertThat(context).hasBean("bar");
|
||||
assertThat(context.getBean("bar")).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(ConditionalOnClassTests.class)
|
||||
protected static class BasicConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(name = "FOO")
|
||||
protected static class MissingConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class FooConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("org/springframework/boot/autoconfigure/condition/foo.xml")
|
||||
protected static class XmlConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(BasicConfiguration.class)
|
||||
@ImportResource("org/springframework/boot/autoconfigure/condition/foo.xml")
|
||||
protected static class CombinedXmlConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
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 ConditionalOnCloudPlatform}.
|
||||
*/
|
||||
public class ConditionalOnCloudPlatformTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
public void outcomeWhenCloudfoundryPlatformNotPresentShouldNotMatch() {
|
||||
this.contextRunner.withUserConfiguration(CloudFoundryPlatformConfig.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outcomeWhenCloudfoundryPlatformPresentShouldMatch() {
|
||||
this.contextRunner.withUserConfiguration(CloudFoundryPlatformConfig.class)
|
||||
.withPropertyValues("VCAP_APPLICATION:---")
|
||||
.run((context) -> assertThat(context).hasBean("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outcomeWhenCloudfoundryPlatformPresentAndMethodTargetShouldMatch() {
|
||||
this.contextRunner.withUserConfiguration(CloudFoundryPlatformOnMethodConfig.class)
|
||||
.withPropertyValues("VCAP_APPLICATION:---")
|
||||
.run((context) -> assertThat(context).hasBean("foo"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)
|
||||
static class CloudFoundryPlatformConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CloudFoundryPlatformOnMethodConfig {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
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 ConditionalOnExpression}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConditionalOnExpressionTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
public void expressionIsTrue() {
|
||||
this.contextRunner.withUserConfiguration(BasicConfiguration.class)
|
||||
.run((context) -> assertThat(context.getBean("foo")).isEqualTo("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expressionIsFalse() {
|
||||
this.contextRunner.withUserConfiguration(MissingConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expressionIsNull() {
|
||||
this.contextRunner.withUserConfiguration(NullConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean("foo"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnExpression("false")
|
||||
protected static class MissingConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnExpression("true")
|
||||
protected static class BasicConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnExpression("true ? null : false")
|
||||
protected static class NullConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.Range;
|
||||
import org.springframework.boot.system.JavaVersion;
|
||||
import org.springframework.boot.test.Assume;
|
||||
import org.springframework.boot.test.context.HideClassesClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnJava}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ConditionalOnJavaTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
private final OnJavaCondition condition = new OnJavaCondition();
|
||||
|
||||
@Test
|
||||
public void doesNotMatchIfBetterVersionIsRequired() {
|
||||
Assume.javaVersion(JavaVersion.EIGHT);
|
||||
this.contextRunner.withUserConfiguration(Java9Required.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotMatchIfLowerIsRequired() {
|
||||
this.contextRunner.withUserConfiguration(Java7Required.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchesIfVersionIsInRange() {
|
||||
this.contextRunner.withUserConfiguration(Java8Required.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void boundsTests() throws Exception {
|
||||
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.NINE, JavaVersion.EIGHT, true);
|
||||
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.EIGHT, JavaVersion.EIGHT, true);
|
||||
testBounds(Range.EQUAL_OR_NEWER, JavaVersion.EIGHT, JavaVersion.NINE, false);
|
||||
testBounds(Range.OLDER_THAN, JavaVersion.NINE, JavaVersion.EIGHT, false);
|
||||
testBounds(Range.OLDER_THAN, JavaVersion.EIGHT, JavaVersion.EIGHT, false);
|
||||
testBounds(Range.OLDER_THAN, JavaVersion.EIGHT, JavaVersion.NINE, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalOrNewerMessage() throws Exception {
|
||||
ConditionOutcome outcome = this.condition.getMatchOutcome(Range.EQUAL_OR_NEWER,
|
||||
JavaVersion.NINE, JavaVersion.EIGHT);
|
||||
assertThat(outcome.getMessage())
|
||||
.isEqualTo("@ConditionalOnJava (1.8 or newer) found 1.9");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void olderThanMessage() throws Exception {
|
||||
ConditionOutcome outcome = this.condition.getMatchOutcome(Range.OLDER_THAN,
|
||||
JavaVersion.NINE, JavaVersion.EIGHT);
|
||||
assertThat(outcome.getMessage())
|
||||
.isEqualTo("@ConditionalOnJava (older than 1.8) found 1.9");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void java8IsDetected() throws Exception {
|
||||
Assume.javaVersion(JavaVersion.EIGHT);
|
||||
assertThat(getJavaVersion()).isEqualTo("1.8");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void java8IsTheFallback() throws Exception {
|
||||
Assume.javaVersion(JavaVersion.EIGHT);
|
||||
assertThat(getJavaVersion(Function.class, Files.class, ServiceLoader.class))
|
||||
.isEqualTo("1.8");
|
||||
}
|
||||
|
||||
private String getJavaVersion(Class<?>... hiddenClasses) throws Exception {
|
||||
HideClassesClassLoader classLoader = new HideClassesClassLoader(hiddenClasses);
|
||||
Class<?> javaVersionClass = classLoader.loadClass(JavaVersion.class.getName());
|
||||
Method getJavaVersionMethod = ReflectionUtils.findMethod(javaVersionClass,
|
||||
"getJavaVersion");
|
||||
Object javaVersion = ReflectionUtils.invokeMethod(getJavaVersionMethod, null);
|
||||
classLoader.close();
|
||||
return javaVersion.toString();
|
||||
}
|
||||
|
||||
private void testBounds(Range range, JavaVersion runningVersion, JavaVersion version,
|
||||
boolean expected) {
|
||||
ConditionOutcome outcome = this.condition.getMatchOutcome(range, runningVersion,
|
||||
version);
|
||||
assertThat(outcome.isMatch()).as(outcome.getMessage()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnJava(JavaVersion.NINE)
|
||||
static class Java9Required {
|
||||
|
||||
@Bean
|
||||
String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnJava(range = Range.OLDER_THAN, value = JavaVersion.EIGHT)
|
||||
static class Java7Required {
|
||||
|
||||
@Bean
|
||||
String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnJava(JavaVersion.EIGHT)
|
||||
static class Java8Required {
|
||||
|
||||
@Bean
|
||||
String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.Context;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jndi.JndiPropertiesHidingClassLoader;
|
||||
import org.springframework.boot.autoconfigure.jndi.TestableInitialContextFactory;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnJndi}
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class ConditionalOnJndiTests {
|
||||
|
||||
private ClassLoader threadContextClassLoader;
|
||||
|
||||
private String initialContextFactory;
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
private MockableOnJndi condition = new MockableOnJndi();
|
||||
|
||||
@Before
|
||||
public void setupThreadContextClassLoader() {
|
||||
this.threadContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(
|
||||
new JndiPropertiesHidingClassLoader(getClass().getClassLoader()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
TestableInitialContextFactory.clearAll();
|
||||
if (this.initialContextFactory != null) {
|
||||
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
|
||||
this.initialContextFactory);
|
||||
}
|
||||
else {
|
||||
System.clearProperty(Context.INITIAL_CONTEXT_FACTORY);
|
||||
}
|
||||
Thread.currentThread().setContextClassLoader(this.threadContextClassLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jndiNotAvailable() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(JndiAvailableConfiguration.class,
|
||||
JndiConditionConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jndiAvailable() {
|
||||
setupJndi();
|
||||
this.contextRunner
|
||||
.withUserConfiguration(JndiAvailableConfiguration.class,
|
||||
JndiConditionConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jndiLocationNotBound() {
|
||||
setupJndi();
|
||||
this.contextRunner.withUserConfiguration(JndiConditionConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jndiLocationBound() {
|
||||
setupJndi();
|
||||
TestableInitialContextFactory.bind("java:/FooManager", new Object());
|
||||
this.contextRunner.withUserConfiguration(JndiConditionConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jndiLocationNotFound() {
|
||||
ConditionOutcome outcome = this.condition.getMatchOutcome(null,
|
||||
mockMetaData("java:/a"));
|
||||
assertThat(outcome.isMatch()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jndiLocationFound() {
|
||||
this.condition.setFoundLocation("java:/b");
|
||||
ConditionOutcome outcome = this.condition.getMatchOutcome(null,
|
||||
mockMetaData("java:/a", "java:/b"));
|
||||
assertThat(outcome.isMatch()).isTrue();
|
||||
}
|
||||
|
||||
private void setupJndi() {
|
||||
this.initialContextFactory = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
|
||||
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
|
||||
TestableInitialContextFactory.class.getName());
|
||||
}
|
||||
|
||||
private AnnotatedTypeMetadata mockMetaData(String... value) {
|
||||
AnnotatedTypeMetadata metadata = mock(AnnotatedTypeMetadata.class);
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("value", value);
|
||||
given(metadata.getAnnotationAttributes(ConditionalOnJndi.class.getName()))
|
||||
.willReturn(attributes);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnJndi
|
||||
static class JndiAvailableConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnJndi("java:/FooManager")
|
||||
static class JndiConditionConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MockableOnJndi extends OnJndiCondition {
|
||||
|
||||
private boolean jndiAvailable = true;
|
||||
|
||||
private String foundLocation;
|
||||
|
||||
@Override
|
||||
protected boolean isJndiAvailable() {
|
||||
return this.jndiAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JndiLocator getJndiLocator(String[] locations) {
|
||||
return new JndiLocator(locations) {
|
||||
@Override
|
||||
public String lookupFirstLocation() {
|
||||
return MockableOnJndi.this.foundLocation;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setFoundLocation(String foundLocation) {
|
||||
this.foundLocation = foundLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,659 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
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 java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.boot.autoconfigure.condition.scan.ScannedFactoryBeanConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.scan.ScannedFactoryBeanWithBeanMethodArgumentsConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnMissingBean}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Jakub Kubrynski
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class ConditionalOnMissingBeanTests {
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@Test
|
||||
public void testNameOnMissingBeanCondition() {
|
||||
this.context.register(FooConfiguration.class, OnBeanNameConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("bar")).isFalse();
|
||||
assertThat(this.context.getBean("foo")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameOnMissingBeanConditionReverseOrder() {
|
||||
this.context.register(OnBeanNameConfiguration.class, FooConfiguration.class);
|
||||
this.context.refresh();
|
||||
// FIXME: ideally this would be false, but the ordering is a problem
|
||||
assertThat(this.context.containsBean("bar")).isTrue();
|
||||
assertThat(this.context.getBean("foo")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameAndTypeOnMissingBeanCondition() {
|
||||
this.context.register(FooConfiguration.class,
|
||||
OnBeanNameAndTypeConfiguration.class);
|
||||
this.context.refresh();
|
||||
/*
|
||||
* Arguably this should be true, but as things are implemented the conditions
|
||||
* specified in the different attributes of @ConditionalOnBean are combined with
|
||||
* logical OR (not AND) so if any of them match the condition is true.
|
||||
*/
|
||||
assertThat(this.context.containsBean("bar")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hierarchyConsidered() throws Exception {
|
||||
this.context.register(FooConfiguration.class);
|
||||
this.context.refresh();
|
||||
AnnotationConfigApplicationContext childContext = new AnnotationConfigApplicationContext();
|
||||
childContext.setParent(this.context);
|
||||
childContext.register(HierarchyConsidered.class);
|
||||
childContext.refresh();
|
||||
assertThat(childContext.containsLocalBean("bar")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hierarchyNotConsidered() throws Exception {
|
||||
this.context.register(FooConfiguration.class);
|
||||
this.context.refresh();
|
||||
AnnotationConfigApplicationContext childContext = new AnnotationConfigApplicationContext();
|
||||
childContext.setParent(this.context);
|
||||
childContext.register(HierarchyNotConsidered.class);
|
||||
childContext.refresh();
|
||||
assertThat(childContext.containsLocalBean("bar")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void impliedOnBeanMethod() throws Exception {
|
||||
this.context.register(ExampleBeanConfiguration.class, ImpliedOnBeanMethod.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBeansOfType(ExampleBean.class).size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMissingBeanCondition() {
|
||||
this.context.register(FooConfiguration.class, OnAnnotationConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("bar")).isFalse();
|
||||
assertThat(this.context.getBean("foo")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
// Rigorous test for SPR-11069
|
||||
@Test
|
||||
public void testAnnotationOnMissingBeanConditionWithEagerFactoryBean() {
|
||||
this.context.register(FooConfiguration.class, OnAnnotationConfiguration.class,
|
||||
FactoryBeanXmlConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("bar")).isFalse();
|
||||
assertThat(this.context.containsBean("example")).isTrue();
|
||||
assertThat(this.context.getBean("foo")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithFactoryBean() {
|
||||
this.context.register(FactoryBeanConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithComponentScannedFactoryBean() {
|
||||
this.context.register(ComponentScannedFactoryBeanBeanMethodConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithComponentScannedFactoryBeanWithBeanMethodArguments() {
|
||||
this.context.register(
|
||||
ComponentScannedFactoryBeanBeanMethodWithArgumentsConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithFactoryBeanWithBeanMethodArguments() {
|
||||
this.context.register(FactoryBeanWithBeanMethodArgumentsConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
TestPropertyValues.of("theValue:foo").applyTo(this.context);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithConcreteFactoryBean() {
|
||||
this.context.register(ConcreteFactoryBeanConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithUnhelpfulFactoryBean() {
|
||||
this.context.register(UnhelpfulFactoryBeanConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
// We could not tell that the FactoryBean would ultimately create an ExampleBean
|
||||
assertThat(this.context.getBeansOfType(ExampleBean.class).values()).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithRegisteredFactoryBean() {
|
||||
this.context.register(RegisteredFactoryBeanConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithNonspecificFactoryBeanWithClassAttribute() {
|
||||
this.context.register(NonspecificFactoryBeanClassAttributeConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithNonspecificFactoryBeanWithStringAttribute() {
|
||||
this.context.register(NonspecificFactoryBeanStringAttributeConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithFactoryBeanInXml() {
|
||||
this.context.register(FactoryBeanXmlConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString())
|
||||
.isEqualTo("fromFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithIgnoredSubclass() {
|
||||
this.context.register(CustomExampleBeanConfiguration.class,
|
||||
ConditionalOnIgnoredSubclass.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBeansOfType(ExampleBean.class)).hasSize(2);
|
||||
assertThat(this.context.getBeansOfType(CustomExampleBean.class)).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithIgnoredSubclassByName() {
|
||||
this.context.register(CustomExampleBeanConfiguration.class,
|
||||
ConditionalOnIgnoredSubclassByName.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBeansOfType(ExampleBean.class)).hasSize(2);
|
||||
assertThat(this.context.getBeansOfType(CustomExampleBean.class)).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void grandparentIsConsideredWhenUsingAncestorsStrategy() {
|
||||
this.context.register(ExampleBeanConfiguration.class);
|
||||
this.context.refresh();
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
|
||||
parent.setParent(this.context);
|
||||
parent.refresh();
|
||||
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
|
||||
child.setParent(parent);
|
||||
child.register(ExampleBeanConfiguration.class,
|
||||
OnBeanInAncestorsConfiguration.class);
|
||||
child.refresh();
|
||||
assertThat(child.getBeansOfType(ExampleBean.class)).hasSize(1);
|
||||
child.close();
|
||||
parent.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void currentContextIsIgnoredWhenUsingAncestorsStrategy() {
|
||||
this.context.refresh();
|
||||
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
|
||||
child.register(ExampleBeanConfiguration.class,
|
||||
OnBeanInAncestorsConfiguration.class);
|
||||
child.setParent(this.context);
|
||||
child.refresh();
|
||||
assertThat(child.getBeansOfType(ExampleBean.class)).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanProducedByFactoryBeanIsConsideredWhenMatchingOnAnnotation() {
|
||||
this.context.register(ConcreteFactoryBeanConfiguration.class,
|
||||
OnAnnotationWithFactoryBeanConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("bar")).isFalse();
|
||||
assertThat(this.context.getBeansOfType(ExampleBean.class)).hasSize(1);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class OnBeanInAncestorsConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(search = SearchStrategy.ANCESTORS)
|
||||
public ExampleBean exampleBean2() {
|
||||
return new ExampleBean("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(name = "foo")
|
||||
protected static class OnBeanNameConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(name = "foo", value = Date.class)
|
||||
@ConditionalOnBean(name = "foo", value = Date.class)
|
||||
protected static class OnBeanNameAndTypeConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class FactoryBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public FactoryBean<ExampleBean> exampleBeanFactoryBean() {
|
||||
return new ExampleFactoryBean("foo");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "org.springframework.boot.autoconfigure.condition.scan", includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ScannedFactoryBeanConfiguration.class))
|
||||
protected static class ComponentScannedFactoryBeanBeanMethodConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "org.springframework.boot.autoconfigure.condition.scan", includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ScannedFactoryBeanWithBeanMethodArgumentsConfiguration.class))
|
||||
protected static class ComponentScannedFactoryBeanBeanMethodWithArgumentsConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class FactoryBeanWithBeanMethodArgumentsConfiguration {
|
||||
|
||||
@Bean
|
||||
public FactoryBean<ExampleBean> exampleBeanFactoryBean(
|
||||
@Value("${theValue}") String value) {
|
||||
return new ExampleFactoryBean(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ConcreteFactoryBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public ExampleFactoryBean exampleBeanFactoryBean() {
|
||||
return new ExampleFactoryBean("foo");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class UnhelpfulFactoryBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("rawtypes")
|
||||
public FactoryBean exampleBeanFactoryBean() {
|
||||
return new ExampleFactoryBean("foo");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(NonspecificFactoryBeanClassAttributeRegistrar.class)
|
||||
protected static class NonspecificFactoryBeanClassAttributeConfiguration {
|
||||
|
||||
}
|
||||
|
||||
protected static class NonspecificFactoryBeanClassAttributeRegistrar
|
||||
implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata meta,
|
||||
BeanDefinitionRegistry registry) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(NonspecificFactoryBean.class);
|
||||
builder.addConstructorArgValue("foo");
|
||||
builder.getBeanDefinition().setAttribute(
|
||||
OnBeanCondition.FACTORY_BEAN_OBJECT_TYPE, ExampleBean.class);
|
||||
registry.registerBeanDefinition("exampleBeanFactoryBean",
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(NonspecificFactoryBeanClassAttributeRegistrar.class)
|
||||
protected static class NonspecificFactoryBeanStringAttributeConfiguration {
|
||||
|
||||
}
|
||||
|
||||
protected static class NonspecificFactoryBeanStringAttributeRegistrar
|
||||
implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata meta,
|
||||
BeanDefinitionRegistry registry) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(NonspecificFactoryBean.class);
|
||||
builder.addConstructorArgValue("foo");
|
||||
builder.getBeanDefinition().setAttribute(
|
||||
OnBeanCondition.FACTORY_BEAN_OBJECT_TYPE,
|
||||
ExampleBean.class.getName());
|
||||
registry.registerBeanDefinition("exampleBeanFactoryBean",
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(FactoryBeanRegistrar.class)
|
||||
protected static class RegisteredFactoryBeanConfiguration {
|
||||
|
||||
}
|
||||
|
||||
protected static class FactoryBeanRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata meta,
|
||||
BeanDefinitionRegistry registry) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(ExampleFactoryBean.class);
|
||||
builder.addConstructorArgValue("foo");
|
||||
registry.registerBeanDefinition("exampleBeanFactoryBean",
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("org/springframework/boot/autoconfigure/condition/factorybean.xml")
|
||||
protected static class FactoryBeanXmlConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ConditionalOnFactoryBean {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ExampleBean.class)
|
||||
public ExampleBean createExampleBean() {
|
||||
return new ExampleBean("direct");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ConditionalOnIgnoredSubclass {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ExampleBean.class, ignored = CustomExampleBean.class)
|
||||
public ExampleBean exampleBean() {
|
||||
return new ExampleBean("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ConditionalOnIgnoredSubclassByName {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ExampleBean.class, ignoredType = "org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBeanTests.CustomExampleBean")
|
||||
public ExampleBean exampleBean() {
|
||||
return new ExampleBean("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class CustomExampleBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public CustomExampleBean customExampleBean() {
|
||||
return new CustomExampleBean();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(annotation = EnableScheduling.class)
|
||||
protected static class OnAnnotationConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(annotation = TestAnnotation.class)
|
||||
protected static class OnAnnotationWithFactoryBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
protected static class FooConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(name = "foo")
|
||||
protected static class HierarchyConsidered {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(name = "foo", search = SearchStrategy.CURRENT)
|
||||
protected static class HierarchyNotConsidered {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ExampleBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public ExampleBean exampleBean() {
|
||||
return new ExampleBean("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ImpliedOnBeanMethod {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ExampleBean exampleBean2() {
|
||||
return new ExampleBean("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation
|
||||
public static class ExampleBean {
|
||||
|
||||
private String value;
|
||||
|
||||
public ExampleBean(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CustomExampleBean extends ExampleBean {
|
||||
|
||||
public CustomExampleBean() {
|
||||
super("custom subclass");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ExampleFactoryBean implements FactoryBean<ExampleBean> {
|
||||
|
||||
public ExampleFactoryBean(String value) {
|
||||
Assert.state(!value.contains("$"), "value should not contain '$'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExampleBean getObject() throws Exception {
|
||||
return new ExampleBean("fromFactory");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return ExampleBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class NonspecificFactoryBean implements FactoryBean<Object> {
|
||||
|
||||
public NonspecificFactoryBean(String value) {
|
||||
Assert.state(!value.contains("$"), "value should not contain '$'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExampleBean getObject() throws Exception {
|
||||
return new ExampleBean("fromFactory");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return ExampleBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface TestAnnotation {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests {@link ConditionalOnMissingBean} with filtered classpath.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@RunWith(ModifiedClassPathRunner.class)
|
||||
@ClassPathExclusions("spring-context-support-*.jar")
|
||||
public class ConditionalOnMissingBeanWithFilteredClasspathTests {
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameOnMissingBeanTypeWithMissingImport() {
|
||||
this.context.register(OnBeanTypeConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class OnBeanTypeConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(type = "org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBeanWithFilteredClasspathTests.TestCacheManager")
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestCacheManager extends CaffeineCacheManager {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnMissingClass}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ConditionalOnMissingClassTests {
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@Test
|
||||
public void testVanillaOnClassCondition() {
|
||||
this.context.register(BasicConfiguration.class, FooConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("bar")).isFalse();
|
||||
assertThat(this.context.getBean("foo")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingOnClassCondition() {
|
||||
this.context.register(MissingConfiguration.class, FooConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("bar")).isTrue();
|
||||
assertThat(this.context.getBean("foo")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingClass("org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClassTests")
|
||||
protected static class BasicConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingClass("FOO")
|
||||
protected static class MissingConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class FooConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.reactive.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext;
|
||||
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnNotWebApplication}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConditionalOnNotWebApplicationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotWebApplicationWithServletContext() {
|
||||
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
|
||||
ctx.register(NotWebApplicationConfiguration.class);
|
||||
ctx.setServletContext(new MockServletContext());
|
||||
ctx.refresh();
|
||||
|
||||
this.context = ctx;
|
||||
assertThat(this.context.getBeansOfType(String.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotWebApplicationWithReactiveContext() {
|
||||
GenericReactiveWebApplicationContext ctx = new GenericReactiveWebApplicationContext();
|
||||
ctx.register(ReactiveApplicationConfig.class,
|
||||
NotWebApplicationConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
assertThat(this.context.getBeansOfType(String.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotWebApplication() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(NotWebApplicationConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
assertThat(this.context.getBeansOfType(String.class))
|
||||
.containsExactly(entry("none", "none"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ReactiveApplicationConfig {
|
||||
|
||||
@Bean
|
||||
public ReactiveWebServerFactory reactiveWebServerFactory() {
|
||||
return new MockReactiveWebServerFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HttpHandler httpHandler() {
|
||||
return (request, response) -> Mono.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnNotWebApplication
|
||||
protected static class NotWebApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
public String none() {
|
||||
return "none";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnProperty}.
|
||||
*
|
||||
* @author Maciej Walkowiak
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class ConditionalOnPropertyTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
private ConfigurableEnvironment environment = new StandardEnvironment();
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allPropertiesAreDefined() {
|
||||
load(MultiplePropertiesRequiredConfiguration.class, "property1=value1",
|
||||
"property2=value2");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notAllPropertiesAreDefined() {
|
||||
load(MultiplePropertiesRequiredConfiguration.class, "property1=value1");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyValueEqualsFalse() {
|
||||
load(MultiplePropertiesRequiredConfiguration.class, "property1=false",
|
||||
"property2=value2");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyValueEqualsFALSE() {
|
||||
load(MultiplePropertiesRequiredConfiguration.class, "property1=FALSE",
|
||||
"property2=value2");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void relaxedName() {
|
||||
load(RelaxedPropertiesRequiredConfiguration.class,
|
||||
"spring.theRelaxedProperty=value1");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prefixWithoutPeriod() throws Exception {
|
||||
load(RelaxedPropertiesRequiredConfigurationWithShortPrefix.class,
|
||||
"spring.property=value1");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
// Enabled by default
|
||||
public void enabledIfNotConfiguredOtherwise() {
|
||||
load(EnabledIfNotConfiguredOtherwiseConfig.class);
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enabledIfNotConfiguredOtherwiseWithConfig() {
|
||||
load(EnabledIfNotConfiguredOtherwiseConfig.class, "simple.myProperty:false");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enabledIfNotConfiguredOtherwiseWithConfigDifferentCase() {
|
||||
load(EnabledIfNotConfiguredOtherwiseConfig.class, "simple.my-property:FALSE");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
// Disabled by default
|
||||
public void disableIfNotConfiguredOtherwise() {
|
||||
load(DisabledIfNotConfiguredOtherwiseConfig.class);
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableIfNotConfiguredOtherwiseWithConfig() {
|
||||
load(DisabledIfNotConfiguredOtherwiseConfig.class, "simple.myProperty:true");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableIfNotConfiguredOtherwiseWithConfigDifferentCase() {
|
||||
load(DisabledIfNotConfiguredOtherwiseConfig.class, "simple.myproperty:TrUe");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleValueIsSet() {
|
||||
load(SimpleValueConfig.class, "simple.myProperty:bar");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void caseInsensitive() {
|
||||
load(SimpleValueConfig.class, "simple.myProperty:BaR");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultValueIsSet() {
|
||||
load(DefaultValueConfig.class, "simple.myProperty:bar");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultValueIsNotSet() {
|
||||
load(DefaultValueConfig.class);
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultValueIsSetDifferentValue() {
|
||||
load(DefaultValueConfig.class, "simple.myProperty:another");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prefix() {
|
||||
load(PrefixValueConfig.class, "simple.myProperty:bar");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void relaxedEnabledByDefault() {
|
||||
load(PrefixValueConfig.class, "simple.myProperty:bar");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multiValuesAllSet() {
|
||||
load(MultiValuesConfig.class, "simple.my-property:bar",
|
||||
"simple.my-another-property:bar");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multiValuesOnlyOneSet() {
|
||||
load(MultiValuesConfig.class, "simple.my-property:bar");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usingValueAttribute() throws Exception {
|
||||
load(ValueAttribute.class, "some.property");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameOrValueMustBeSpecified() throws Exception {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectCause(hasMessage(containsString("The name or "
|
||||
+ "value attribute of @ConditionalOnProperty must be specified")));
|
||||
load(NoNameOrValueAttribute.class, "some.property");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameAndValueMustNotBeSpecified() throws Exception {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectCause(hasMessage(containsString("The name and "
|
||||
+ "value attributes of @ConditionalOnProperty are exclusive")));
|
||||
load(NameAndValueAttribute.class, "some.property");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metaAnnotationConditionMatchesWhenPropertyIsSet() throws Exception {
|
||||
load(MetaAnnotation.class, "my.feature.enabled=true");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metaAnnotationConditionDoesNotMatchWhenPropertyIsNotSet()
|
||||
throws Exception {
|
||||
load(MetaAnnotation.class);
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metaAndDirectAnnotationConditionDoesNotMatchWhenOnlyDirectPropertyIsSet() {
|
||||
load(MetaAnnotationAndDirectAnnotation.class, "my.other.feature.enabled=true");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metaAndDirectAnnotationConditionDoesNotMatchWhenOnlyMetaPropertyIsSet() {
|
||||
load(MetaAnnotationAndDirectAnnotation.class, "my.feature.enabled=true");
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metaAndDirectAnnotationConditionDoesNotMatchWhenNeitherPropertyIsSet() {
|
||||
load(MetaAnnotationAndDirectAnnotation.class);
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metaAndDirectAnnotationConditionMatchesWhenBothPropertiesAreSet() {
|
||||
load(MetaAnnotationAndDirectAnnotation.class, "my.feature.enabled=true",
|
||||
"my.other.feature.enabled=true");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
TestPropertyValues.of(environment).applyTo(this.environment);
|
||||
this.context = new SpringApplicationBuilder(config).environment(this.environment)
|
||||
.web(WebApplicationType.NONE).run();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = { "property1", "property2" })
|
||||
protected static class MultiplePropertiesRequiredConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "spring.", name = "the-relaxed-property")
|
||||
protected static class RelaxedPropertiesRequiredConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "spring", name = "property")
|
||||
protected static class RelaxedPropertiesRequiredConfigurationWithShortPrefix {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
// i.e ${simple.myProperty:true}
|
||||
@ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "true", matchIfMissing = true)
|
||||
static class EnabledIfNotConfiguredOtherwiseConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
// i.e ${simple.myProperty:false}
|
||||
@ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "true", matchIfMissing = false)
|
||||
static class DisabledIfNotConfiguredOtherwiseConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "bar")
|
||||
static class SimpleValueConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "simple.myProperty", havingValue = "bar", matchIfMissing = true)
|
||||
static class DefaultValueConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "bar")
|
||||
static class PrefixValueConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "simple", name = { "my-property",
|
||||
"my-another-property" }, havingValue = "bar")
|
||||
static class MultiValuesConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty("some.property")
|
||||
protected static class ValueAttribute {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty
|
||||
protected static class NoNameOrValueAttribute {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "x", name = "y")
|
||||
protected static class NameAndValueAttribute {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMyFeature
|
||||
protected static class MetaAnnotation {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMyFeature
|
||||
@ConditionalOnProperty(prefix = "my.other.feature", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
protected static class MetaAnnotationAndDirectAnnotation {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@ConditionalOnProperty(prefix = "my.feature", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
public @interface ConditionalOnMyFeature {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnResource}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ConditionalOnResourceTests {
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@Test
|
||||
public void testResourceExists() {
|
||||
this.context.register(BasicConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
assertThat(this.context.getBean("foo")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceExistsWithPlaceholder() {
|
||||
TestPropertyValues.of("schema=schema.sql").applyTo(this.context);
|
||||
this.context.register(PlaceholderConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
assertThat(this.context.getBean("foo")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceNotExists() {
|
||||
this.context.register(MissingConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnResource(resources = "foo")
|
||||
protected static class MissingConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnResource(resources = "schema.sql")
|
||||
protected static class BasicConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnResource(resources = "${schema}")
|
||||
protected static class PlaceholderConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.isA;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnSingleCandidate}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class ConditionalOnSingleCandidateTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateNoCandidate() {
|
||||
load(OnBeanSingleCandidateConfiguration.class);
|
||||
assertThat(this.context.containsBean("baz")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateOneCandidate() {
|
||||
load(FooConfiguration.class, OnBeanSingleCandidateConfiguration.class);
|
||||
assertThat(this.context.containsBean("baz")).isTrue();
|
||||
assertThat(this.context.getBean("baz")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateInAncestorsOneCandidateInCurrent() {
|
||||
load();
|
||||
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
|
||||
child.register(FooConfiguration.class,
|
||||
OnBeanSingleCandidateInAncestorsConfiguration.class);
|
||||
child.setParent(this.context);
|
||||
child.refresh();
|
||||
assertThat(child.containsBean("baz")).isFalse();
|
||||
child.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateInAncestorsOneCandidateInParent() {
|
||||
load(FooConfiguration.class);
|
||||
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
|
||||
child.register(OnBeanSingleCandidateInAncestorsConfiguration.class);
|
||||
child.setParent(this.context);
|
||||
child.refresh();
|
||||
assertThat(child.containsBean("baz")).isTrue();
|
||||
assertThat(child.getBean("baz")).isEqualTo("foo");
|
||||
child.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateInAncestorsOneCandidateInGrandparent() {
|
||||
load(FooConfiguration.class);
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
|
||||
parent.setParent(this.context);
|
||||
parent.refresh();
|
||||
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
|
||||
child.register(OnBeanSingleCandidateInAncestorsConfiguration.class);
|
||||
child.setParent(parent);
|
||||
child.refresh();
|
||||
assertThat(child.containsBean("baz")).isTrue();
|
||||
assertThat(child.getBean("baz")).isEqualTo("foo");
|
||||
child.close();
|
||||
parent.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateMultipleCandidates() {
|
||||
load(FooConfiguration.class, BarConfiguration.class,
|
||||
OnBeanSingleCandidateConfiguration.class);
|
||||
assertThat(this.context.containsBean("baz")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateMultipleCandidatesOnePrimary() {
|
||||
load(FooPrimaryConfiguration.class, BarConfiguration.class,
|
||||
OnBeanSingleCandidateConfiguration.class);
|
||||
assertThat(this.context.containsBean("baz")).isTrue();
|
||||
assertThat(this.context.getBean("baz")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateMultipleCandidatesMultiplePrimary() {
|
||||
load(FooPrimaryConfiguration.class, BarPrimaryConfiguration.class,
|
||||
OnBeanSingleCandidateConfiguration.class);
|
||||
assertThat(this.context.containsBean("baz")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidAnnotationTwoTypes() {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectCause(isA(IllegalArgumentException.class));
|
||||
this.thrown.expectMessage(
|
||||
OnBeanSingleCandidateTwoTypesConfiguration.class.getName());
|
||||
load(OnBeanSingleCandidateTwoTypesConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidAnnotationNoType() {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectCause(isA(IllegalArgumentException.class));
|
||||
this.thrown
|
||||
.expectMessage(OnBeanSingleCandidateNoTypeConfiguration.class.getName());
|
||||
load(OnBeanSingleCandidateNoTypeConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleCandidateMultipleCandidatesInContextHierarchy() {
|
||||
load(FooPrimaryConfiguration.class, BarConfiguration.class);
|
||||
try (AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext()) {
|
||||
child.setParent(this.context);
|
||||
child.register(OnBeanSingleCandidateConfiguration.class);
|
||||
child.refresh();
|
||||
assertThat(child.containsBean("baz")).isTrue();
|
||||
assertThat(child.getBean("baz")).isEqualTo("foo");
|
||||
}
|
||||
}
|
||||
|
||||
private void load(Class<?>... classes) {
|
||||
if (classes.length > 0) {
|
||||
this.context.register(classes);
|
||||
}
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnSingleCandidate(String.class)
|
||||
protected static class OnBeanSingleCandidateConfiguration {
|
||||
|
||||
@Bean
|
||||
public String baz(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnSingleCandidate(value = String.class, search = SearchStrategy.ANCESTORS)
|
||||
protected static class OnBeanSingleCandidateInAncestorsConfiguration {
|
||||
|
||||
@Bean
|
||||
public String baz(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnSingleCandidate(value = String.class, type = "java.lang.String")
|
||||
protected static class OnBeanSingleCandidateTwoTypesConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnSingleCandidate
|
||||
protected static class OnBeanSingleCandidateNoTypeConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class FooConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class FooPrimaryConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class BarConfiguration {
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class BarPrimaryConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public String bar() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext;
|
||||
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConditionalOnWebApplication}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConditionalOnWebApplicationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebApplicationWithServletContext() {
|
||||
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
|
||||
ctx.register(AnyWebApplicationConfiguration.class,
|
||||
ServletWebApplicationConfiguration.class,
|
||||
ReactiveWebApplicationConfiguration.class);
|
||||
ctx.setServletContext(new MockServletContext());
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
assertThat(this.context.getBeansOfType(String.class))
|
||||
.containsExactly(entry("any", "any"), entry("servlet", "servlet"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebApplicationWithReactiveContext() {
|
||||
GenericReactiveWebApplicationContext ctx = new GenericReactiveWebApplicationContext();
|
||||
ctx.register(AnyWebApplicationConfiguration.class,
|
||||
ServletWebApplicationConfiguration.class,
|
||||
ReactiveWebApplicationConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
assertThat(this.context.getBeansOfType(String.class))
|
||||
.containsExactly(entry("any", "any"), entry("reactive", "reactive"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonWebApplication() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AnyWebApplicationConfiguration.class,
|
||||
ServletWebApplicationConfiguration.class,
|
||||
ReactiveWebApplicationConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
assertThat(this.context.getBeansOfType(String.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication
|
||||
protected static class AnyWebApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
public String any() {
|
||||
return "any";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
protected static class ServletWebApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
public String servlet() {
|
||||
return "servlet";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication(type = Type.REACTIVE)
|
||||
protected static class ReactiveWebApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
public String reactive() {
|
||||
return "reactive";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ReactiveWebServerFactory reactiveWebServerFactory() {
|
||||
return new MockReactiveWebServerFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HttpHandler httpHandler() {
|
||||
return (request, response) -> Mono.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link NoneNestedConditions}.
|
||||
*/
|
||||
public class NoneNestedConditionsTests {
|
||||
|
||||
@Test
|
||||
public void neither() throws Exception {
|
||||
AnnotationConfigApplicationContext context = load(Config.class);
|
||||
assertThat(context.containsBean("myBean")).isTrue();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyA() throws Exception {
|
||||
AnnotationConfigApplicationContext context = load(Config.class, "a:a");
|
||||
assertThat(context.containsBean("myBean")).isFalse();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyB() throws Exception {
|
||||
AnnotationConfigApplicationContext context = load(Config.class, "b:b");
|
||||
assertThat(context.containsBean("myBean")).isFalse();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void both() throws Exception {
|
||||
AnnotationConfigApplicationContext context = load(Config.class, "a:a", "b:b");
|
||||
assertThat(context.containsBean("myBean")).isFalse();
|
||||
context.close();
|
||||
}
|
||||
|
||||
private AnnotationConfigApplicationContext load(Class<?> config, String... env) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(env).applyTo(context);
|
||||
context.register(config);
|
||||
context.refresh();
|
||||
return context;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional(NeitherPropertyANorPropertyBCondition.class)
|
||||
public static class Config {
|
||||
|
||||
@Bean
|
||||
public String myBean() {
|
||||
return "myBean";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NeitherPropertyANorPropertyBCondition extends NoneNestedConditions {
|
||||
|
||||
NeitherPropertyANorPropertyBCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty("a")
|
||||
static class HasPropertyA {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty("b")
|
||||
static class HasPropertyB {
|
||||
|
||||
}
|
||||
|
||||
@Conditional(NonSpringBootCondition.class)
|
||||
static class SubClassC {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NonSpringBootCondition implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.OnBeanCondition.BeanTypeDeductionException;
|
||||
import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link OnBeanCondition} when deduction of the bean's type fails
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@RunWith(ModifiedClassPathRunner.class)
|
||||
@ClassPathExclusions("jackson-core-*.jar")
|
||||
public class OnBeanConditionTypeDeductionFailureTests {
|
||||
|
||||
@Test
|
||||
public void conditionalOnMissingBeanWithDeducedTypeThatIsPartiallyMissingFromClassPath() {
|
||||
try {
|
||||
new AnnotationConfigApplicationContext(ImportingConfiguration.class).close();
|
||||
fail("Context refresh was successful");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Throwable beanTypeDeductionException = findNestedCause(ex,
|
||||
BeanTypeDeductionException.class);
|
||||
assertThat(beanTypeDeductionException)
|
||||
.hasMessage("Failed to deduce bean type for "
|
||||
+ OnMissingBeanConfiguration.class.getName()
|
||||
+ ".objectMapper");
|
||||
assertThat(findNestedCause(beanTypeDeductionException,
|
||||
NoClassDefFoundError.class)).isNotNull();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Throwable findNestedCause(Throwable ex, Class<? extends Throwable> target) {
|
||||
Throwable candidate = ex;
|
||||
while (candidate != null) {
|
||||
if (target.isInstance(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
candidate = candidate.getCause();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(OnMissingBeanImportSelector.class)
|
||||
static class ImportingConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class OnMissingBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ObjectMapper objectMapper() {
|
||||
return new ObjectMapper();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class OnMissingBeanImportSelector implements ImportSelector {
|
||||
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
return new String[] { OnMissingBeanConfiguration.class.getName() };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for the {@link AutoConfigurationImportFilter} part of {@link OnClassCondition}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class OnClassConditionAutoConfigurationImportFilterTests {
|
||||
|
||||
private OnClassCondition filter = new OnClassCondition();
|
||||
|
||||
private DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.filter.setBeanClassLoader(getClass().getClassLoader());
|
||||
this.filter.setBeanFactory(this.beanFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeRegistered() throws Exception {
|
||||
assertThat(SpringFactoriesLoader
|
||||
.loadFactories(AutoConfigurationImportFilter.class, null))
|
||||
.hasAtLeastOneElementOfType(OnClassCondition.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchShouldMatchClasses() throws Exception {
|
||||
String[] autoConfigurationClasses = new String[] { "test.match", "test.nomatch" };
|
||||
boolean[] result = this.filter.match(autoConfigurationClasses,
|
||||
getAutoConfigurationMetadata());
|
||||
assertThat(result).containsExactly(true, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchShouldRecordOutcome() throws Exception {
|
||||
String[] autoConfigurationClasses = new String[] { "test.match", "test.nomatch" };
|
||||
this.filter.match(autoConfigurationClasses, getAutoConfigurationMetadata());
|
||||
ConditionEvaluationReport report = ConditionEvaluationReport
|
||||
.get(this.beanFactory);
|
||||
assertThat(report.getConditionAndOutcomesBySource()).hasSize(1)
|
||||
.containsKey("test.nomatch");
|
||||
}
|
||||
|
||||
private AutoConfigurationMetadata getAutoConfigurationMetadata() {
|
||||
AutoConfigurationMetadata metadata = mock(AutoConfigurationMetadata.class);
|
||||
given(metadata.wasProcessed("test.match")).willReturn(true);
|
||||
given(metadata.getSet("test.match", "ConditionalOnClass"))
|
||||
.willReturn(Collections.<String>singleton("java.io.InputStream"));
|
||||
given(metadata.wasProcessed("test.nomatch")).willReturn(true);
|
||||
given(metadata.getSet("test.nomatch", "ConditionalOnClass"))
|
||||
.willReturn(Collections.<String>singleton("java.io.DoesNotExist"));
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link ResourceCondition}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ResourceConditionTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultResourceAndNoExplicitKey() {
|
||||
load(DefaultLocationConfiguration.class);
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownDefaultLocationAndNoExplicitKey() {
|
||||
load(UnknownDefaultLocationConfiguration.class);
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownDefaultLocationAndExplicitKeyToResource() {
|
||||
load(UnknownDefaultLocationConfiguration.class,
|
||||
"spring.foo.test.config=logging.properties");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(environment).applyTo(applicationContext);
|
||||
applicationContext.register(config);
|
||||
applicationContext.refresh();
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional(DefaultLocationResourceCondition.class)
|
||||
static class DefaultLocationConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional(UnknownDefaultLocationResourceCondition.class)
|
||||
static class UnknownDefaultLocationConfiguration {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DefaultLocationResourceCondition extends ResourceCondition {
|
||||
|
||||
DefaultLocationResourceCondition() {
|
||||
super("test", "spring.foo.test.config", "classpath:/logging.properties");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class UnknownDefaultLocationResourceCondition
|
||||
extends ResourceCondition {
|
||||
|
||||
UnknownDefaultLocationResourceCondition() {
|
||||
super("test", "spring.foo.test.config",
|
||||
"classpath:/this-file-does-not-exist.xml");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.condition;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringBootCondition}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class SpringBootConditionTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void sensibleClassException() {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage(
|
||||
"Error processing condition on " + ErrorOnClass.class.getName());
|
||||
new AnnotationConfigApplicationContext(ErrorOnClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sensibleMethodException() throws Exception {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage("Error processing condition on "
|
||||
+ ErrorOnMethod.class.getName() + ".myBean");
|
||||
new AnnotationConfigApplicationContext(ErrorOnMethod.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional(AlwaysThrowsCondition.class)
|
||||
public static class ErrorOnClass {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class ErrorOnMethod {
|
||||
|
||||
@Bean
|
||||
@Conditional(AlwaysThrowsCondition.class)
|
||||
public String myBean() {
|
||||
return "bean";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class AlwaysThrowsCondition extends SpringBootCondition {
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
throw new RuntimeException("Oh no!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.condition.scan;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBeanTests.ExampleBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBeanTests.ExampleFactoryBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Configuration for a factory bean produced by a bean method on a configuration class
|
||||
* found via component scanning.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Configuration
|
||||
public class ScannedFactoryBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public FactoryBean<ExampleBean> exampleBeanFactoryBean() {
|
||||
return new ExampleFactoryBean("foo");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.condition.scan;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBeanTests.ExampleFactoryBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Configuration for a factory bean produced by a bean method with arguments on a
|
||||
* configuration class found via component scanning.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Configuration
|
||||
public class ScannedFactoryBeanWithBeanMethodArgumentsConfiguration {
|
||||
|
||||
@Bean
|
||||
public Foo foo() {
|
||||
return new Foo();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExampleFactoryBean exampleBeanFactoryBean(Foo foo) {
|
||||
return new ExampleFactoryBean("foo");
|
||||
}
|
||||
|
||||
static class Foo {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.context;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConfigurationPropertiesAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConfigurationPropertiesAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processAnnotatedBean() {
|
||||
load(new Class[] { AutoConfig.class, SampleBean.class }, "foo.name:test");
|
||||
assertThat(this.context.getBean(SampleBean.class).getName()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processAnnotatedBeanNoAutoConfig() {
|
||||
load(new Class[] { SampleBean.class }, "foo.name:test");
|
||||
assertThat(this.context.getBean(SampleBean.class).getName()).isEqualTo("default");
|
||||
}
|
||||
|
||||
private void load(Class<?>[] configs, String... environment) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(configs);
|
||||
TestPropertyValues.of(environment).applyTo(this.context);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportAutoConfiguration(ConfigurationPropertiesAutoConfiguration.class)
|
||||
static class AutoConfig {
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties("foo")
|
||||
static class SampleBean {
|
||||
|
||||
private String name = "default";
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.context;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MessageSourceAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest("spring.messages.basename:test/messages")
|
||||
@ImportAutoConfiguration({ MessageSourceAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
@DirtiesContext
|
||||
public class MessageSourceAutoConfigurationIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testMessageSourceFromPropertySourceAnnotation() throws Exception {
|
||||
assertThat(this.context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.context;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MessageSourceAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@ImportAutoConfiguration({ MessageSourceAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
@ActiveProfiles("switch-messages")
|
||||
@DirtiesContext
|
||||
public class MessageSourceAutoConfigurationProfileTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testMessageSourceFromPropertySourceAnnotation() throws Exception {
|
||||
assertThat(this.context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.context;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceResolvable;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MessageSourceAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @author Kedar Joshi
|
||||
*/
|
||||
public class MessageSourceAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(MessageSourceAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void testDefaultMessageSource() {
|
||||
this.contextRunner.run((context) -> assertThat(
|
||||
context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("Foo message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageSourceCreated() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
|
||||
.run((context) -> assertThat(
|
||||
context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodingWorks() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/swedish")
|
||||
.run((context) -> assertThat(
|
||||
context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("Some text with some swedish öäå!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleMessageSourceCreated() {
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"spring.messages.basename:test/messages,test/messages2")
|
||||
.run((context) -> {
|
||||
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("bar");
|
||||
assertThat(context.getMessage("foo-foo", null, "Foo-Foo message",
|
||||
Locale.UK)).isEqualTo("bar-bar");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadEncoding() {
|
||||
// Bad encoding just means the messages are ignored
|
||||
this.contextRunner.withPropertyValues("spring.messages.encoding:rubbish")
|
||||
.run((context) -> assertThat(
|
||||
context.getMessage("foo", null, "blah", Locale.UK))
|
||||
.isEqualTo("blah"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Expected to fail per gh-1075")
|
||||
public void testMessageSourceFromPropertySourceAnnotation() {
|
||||
this.contextRunner.withUserConfiguration(Config.class)
|
||||
.run((context) -> assertThat(
|
||||
context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFallbackDefault() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
|
||||
.run((context) -> assertThat(
|
||||
isFallbackToSystemLocale(context.getBean(MessageSource.class)))
|
||||
.isTrue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFallbackTurnOff() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages",
|
||||
"spring.messages.fallback-to-system-locale:false")
|
||||
.run((context) -> assertThat(
|
||||
isFallbackToSystemLocale(context.getBean(MessageSource.class)))
|
||||
.isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatMessageDefault() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
|
||||
.run((context) -> assertThat(
|
||||
isAlwaysUseMessageFormat(context.getBean(MessageSource.class)))
|
||||
.isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatMessageOn() throws Exception {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages",
|
||||
"spring.messages.always-use-message-format:true")
|
||||
.run((context) -> assertThat(
|
||||
isAlwaysUseMessageFormat(context.getBean(MessageSource.class)))
|
||||
.isTrue());
|
||||
}
|
||||
|
||||
private boolean isFallbackToSystemLocale(MessageSource messageSource) {
|
||||
return (boolean) new DirectFieldAccessor(messageSource)
|
||||
.getPropertyValue("fallbackToSystemLocale");
|
||||
}
|
||||
|
||||
private boolean isAlwaysUseMessageFormat(MessageSource messageSource) {
|
||||
return (boolean) new DirectFieldAccessor(messageSource)
|
||||
.getPropertyValue("alwaysUseMessageFormat");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseCodeAsDefaultMessageDefault() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
|
||||
.run((context) -> assertThat(
|
||||
isUseCodeAsDefaultMessage(context.getBean(MessageSource.class)))
|
||||
.isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseCodeAsDefaultMessageOn() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages",
|
||||
"spring.messages.use-code-as-default-message:true")
|
||||
.run((context) -> assertThat(
|
||||
isUseCodeAsDefaultMessage(context.getBean(MessageSource.class)))
|
||||
.isTrue());
|
||||
}
|
||||
|
||||
private boolean isUseCodeAsDefaultMessage(MessageSource messageSource) {
|
||||
return (boolean) new DirectFieldAccessor(messageSource)
|
||||
.getPropertyValue("useCodeAsDefaultMessage");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existingMessageSourceIsPreferred() {
|
||||
this.contextRunner.withUserConfiguration(CustomMessageSource.class)
|
||||
.run((context) -> assertThat(context.getMessage("foo", null, null, null))
|
||||
.isEqualTo("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existingMessageSourceInParentIsIgnored() {
|
||||
this.contextRunner.run((parent) -> this.contextRunner.withParent(parent)
|
||||
.withPropertyValues("spring.messages.basename:test/messages")
|
||||
.run((context) -> assertThat(
|
||||
context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("bar")));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:/switch-messages.properties")
|
||||
protected static class Config {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class CustomMessageSource {
|
||||
|
||||
@Bean
|
||||
public MessageSource messageSource() {
|
||||
return new MessageSource() {
|
||||
|
||||
@Override
|
||||
public String getMessage(String code, Object[] args,
|
||||
String defaultMessage, Locale locale) {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage(String code, Object[] args, Locale locale)
|
||||
throws NoSuchMessageException {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage(MessageSourceResolvable resolvable,
|
||||
Locale locale) throws NoSuchMessageException {
|
||||
return resolvable.getCodes()[0];
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.context;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link PropertyPlaceholderAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class PropertyPlaceholderAutoConfigurationTests {
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyPlaceholders() throws Exception {
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
PlaceholderConfig.class);
|
||||
TestPropertyValues.of("foo:two").applyTo(this.context);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(PlaceholderConfig.class).getFoo())
|
||||
.isEqualTo("two");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyPlaceholdersOverride() throws Exception {
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
PlaceholderConfig.class, PlaceholdersOverride.class);
|
||||
TestPropertyValues.of("foo:two").applyTo(this.context);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(PlaceholderConfig.class).getFoo())
|
||||
.isEqualTo("spam");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class PlaceholderConfig {
|
||||
|
||||
@Value("${foo:bar}")
|
||||
private String foo;
|
||||
|
||||
public String getFoo() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class PlaceholdersOverride {
|
||||
|
||||
@Bean
|
||||
public static PropertySourcesPlaceholderConfigurer morePlaceholders() {
|
||||
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
|
||||
configurer.setProperties(StringUtils
|
||||
.splitArrayElementsIntoProperties(new String[] { "foo=spam" }, "="));
|
||||
configurer.setLocalOverride(true);
|
||||
configurer.setOrder(0);
|
||||
return configurer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.context.filtersample;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class ExampleConfiguration {
|
||||
|
||||
@Bean
|
||||
public String example() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.context.filtersample;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class ExampleFilteredAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public String anotherExample() {
|
||||
return "fail";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.couchbase;
|
||||
|
||||
import org.junit.After;
|
||||
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
/**
|
||||
* Base class for {@link CouchbaseAutoConfiguration} tests.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public abstract class AbstractCouchbaseAutoConfigurationTests {
|
||||
|
||||
protected AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void load(Class<?> config, String... environment) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(environment).applyTo(context);
|
||||
if (config != null) {
|
||||
context.register(config);
|
||||
}
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
CouchbaseAutoConfiguration.class);
|
||||
context.refresh();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.couchbase;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.CouchbaseBucket;
|
||||
import com.couchbase.client.java.cluster.ClusterInfo;
|
||||
import com.couchbase.client.java.env.CouchbaseEnvironment;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link CouchbaseAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CouchbaseAutoConfigurationIntegrationTests
|
||||
extends AbstractCouchbaseAutoConfigurationTests {
|
||||
|
||||
@Rule
|
||||
public final CouchbaseTestServer couchbase = new CouchbaseTestServer();
|
||||
|
||||
@Test
|
||||
public void defaultConfiguration() {
|
||||
load(null, "spring.couchbase.bootstrapHosts=localhost");
|
||||
assertThat(this.context.getBeansOfType(Cluster.class)).hasSize(1);
|
||||
assertThat(this.context.getBeansOfType(ClusterInfo.class)).hasSize(1);
|
||||
assertThat(this.context.getBeansOfType(CouchbaseEnvironment.class)).hasSize(1);
|
||||
assertThat(this.context.getBeansOfType(Bucket.class)).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customConfiguration() {
|
||||
load(CustomConfiguration.class, "spring.couchbase.bootstrapHosts=localhost");
|
||||
assertThat(this.context.getBeansOfType(Cluster.class)).hasSize(2);
|
||||
assertThat(this.context.getBeansOfType(ClusterInfo.class)).hasSize(1);
|
||||
assertThat(this.context.getBeansOfType(CouchbaseEnvironment.class)).hasSize(1);
|
||||
assertThat(this.context.getBeansOfType(Bucket.class)).hasSize(2);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
public Cluster myCustomCouchbaseCluster() throws Exception {
|
||||
return mock(Cluster.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Bucket myCustomCouchbaseClient() {
|
||||
return mock(CouchbaseBucket.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.couchbase;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.CouchbaseBucket;
|
||||
import com.couchbase.client.java.cluster.ClusterInfo;
|
||||
import com.couchbase.client.java.env.CouchbaseEnvironment;
|
||||
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration.CouchbaseConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CouchbaseAutoConfiguration}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CouchbaseAutoConfigurationTests
|
||||
extends AbstractCouchbaseAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void bootstrapHostsIsRequired() {
|
||||
load(null);
|
||||
assertNoCouchbaseBeans();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapHostsNotRequiredIfCouchbaseConfigurerIsSet() {
|
||||
load(CouchbaseTestConfigurer.class);
|
||||
assertThat(this.context.getBeansOfType(CouchbaseTestConfigurer.class)).hasSize(1);
|
||||
// No beans are going to be created
|
||||
assertNoCouchbaseBeans();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapHostsIgnoredIfCouchbaseConfigurerIsSet() {
|
||||
load(CouchbaseTestConfigurer.class, "spring.couchbase.bootstrapHosts=localhost");
|
||||
assertThat(this.context.getBeansOfType(CouchbaseTestConfigurer.class)).hasSize(1);
|
||||
assertNoCouchbaseBeans();
|
||||
}
|
||||
|
||||
private void assertNoCouchbaseBeans() {
|
||||
// No beans are going to be created
|
||||
assertThat(this.context.getBeansOfType(CouchbaseEnvironment.class)).isEmpty();
|
||||
assertThat(this.context.getBeansOfType(ClusterInfo.class)).isEmpty();
|
||||
assertThat(this.context.getBeansOfType(Cluster.class)).isEmpty();
|
||||
assertThat(this.context.getBeansOfType(Bucket.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeEnvEndpoints() throws Exception {
|
||||
DefaultCouchbaseEnvironment env = customizeEnv(
|
||||
"spring.couchbase.env.endpoints.keyValue=4",
|
||||
"spring.couchbase.env.endpoints.query=5",
|
||||
"spring.couchbase.env.endpoints.view=6");
|
||||
assertThat(env.kvEndpoints()).isEqualTo(4);
|
||||
assertThat(env.queryEndpoints()).isEqualTo(5);
|
||||
assertThat(env.viewEndpoints()).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeEnvTimeouts() throws Exception {
|
||||
DefaultCouchbaseEnvironment env = customizeEnv(
|
||||
"spring.couchbase.env.timeouts.connect=100",
|
||||
"spring.couchbase.env.timeouts.keyValue=200",
|
||||
"spring.couchbase.env.timeouts.query=300",
|
||||
"spring.couchbase.env.timeouts.socket-connect=400",
|
||||
"spring.couchbase.env.timeouts.view=500");
|
||||
assertThat(env.connectTimeout()).isEqualTo(100);
|
||||
assertThat(env.kvTimeout()).isEqualTo(200);
|
||||
assertThat(env.queryTimeout()).isEqualTo(300);
|
||||
assertThat(env.socketConnectTimeout()).isEqualTo(400);
|
||||
assertThat(env.viewTimeout()).isEqualTo(500);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableSslNoEnabledFlag() throws Exception {
|
||||
DefaultCouchbaseEnvironment env = customizeEnv(
|
||||
"spring.couchbase.env.ssl.keyStore=foo",
|
||||
"spring.couchbase.env.ssl.keyStorePassword=secret");
|
||||
assertThat(env.sslEnabled()).isTrue();
|
||||
assertThat(env.sslKeystoreFile()).isEqualTo("foo");
|
||||
assertThat(env.sslKeystorePassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableSslEvenWithKeyStore() throws Exception {
|
||||
DefaultCouchbaseEnvironment env = customizeEnv(
|
||||
"spring.couchbase.env.ssl.enabled=false",
|
||||
"spring.couchbase.env.ssl.keyStore=foo",
|
||||
"spring.couchbase.env.ssl.keyStorePassword=secret");
|
||||
assertThat(env.sslEnabled()).isFalse();
|
||||
assertThat(env.sslKeystoreFile()).isNull();
|
||||
assertThat(env.sslKeystorePassword()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeEnvWithCustomCouchbaseConfiguration() {
|
||||
load(CustomCouchbaseConfiguration.class,
|
||||
"spring.couchbase.bootstrap-hosts=localhost",
|
||||
"spring.couchbase.env.timeouts.connect=100");
|
||||
assertThat(this.context.getBeansOfType(CouchbaseConfiguration.class)).hasSize(1);
|
||||
DefaultCouchbaseEnvironment env = this.context
|
||||
.getBean(DefaultCouchbaseEnvironment.class);
|
||||
assertThat(env.socketConnectTimeout()).isEqualTo(5000);
|
||||
assertThat(env.connectTimeout()).isEqualTo(2000);
|
||||
}
|
||||
|
||||
private DefaultCouchbaseEnvironment customizeEnv(String... environment)
|
||||
throws Exception {
|
||||
load(CouchbaseTestConfigurer.class, environment);
|
||||
CouchbaseProperties properties = this.context.getBean(CouchbaseProperties.class);
|
||||
return new CouchbaseConfiguration(properties).couchbaseEnvironment();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(CouchbaseDataAutoConfiguration.class)
|
||||
static class CustomCouchbaseConfiguration extends CouchbaseConfiguration {
|
||||
|
||||
CustomCouchbaseConfiguration(CouchbaseProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DefaultCouchbaseEnvironment.Builder initializeEnvironmentBuilder(
|
||||
CouchbaseProperties properties) {
|
||||
return super.initializeEnvironmentBuilder(properties)
|
||||
.socketConnectTimeout(5000).connectTimeout(2000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cluster couchbaseCluster() throws Exception {
|
||||
return mock(Cluster.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterInfo couchbaseClusterInfo() {
|
||||
return mock(ClusterInfo.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bucket couchbaseClient() {
|
||||
return mock(CouchbaseBucket.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.couchbase;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.CouchbaseBucket;
|
||||
import com.couchbase.client.java.cluster.ClusterInfo;
|
||||
import com.couchbase.client.java.env.CouchbaseEnvironment;
|
||||
|
||||
import org.springframework.data.couchbase.config.CouchbaseConfigurer;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Test configurer for couchbase that mocks access.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Component
|
||||
public class CouchbaseTestConfigurer implements CouchbaseConfigurer {
|
||||
|
||||
@Override
|
||||
public CouchbaseEnvironment couchbaseEnvironment() throws Exception {
|
||||
return mock(CouchbaseEnvironment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cluster couchbaseCluster() throws Exception {
|
||||
return mock(Cluster.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterInfo couchbaseClusterInfo() {
|
||||
return mock(ClusterInfo.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bucket couchbaseClient() {
|
||||
return mock(CouchbaseBucket.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.couchbase;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.CouchbaseCluster;
|
||||
import com.couchbase.client.java.env.CouchbaseEnvironment;
|
||||
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.AssumptionViolatedException;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
|
||||
/**
|
||||
* {@link TestRule} for working with an optional Couchbase server. Expects a default
|
||||
* {@link Bucket} with no password to be available on localhost.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CouchbaseTestServer implements TestRule {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CouchbaseTestServer.class);
|
||||
|
||||
private CouchbaseEnvironment environment;
|
||||
|
||||
private Cluster cluster;
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
try {
|
||||
this.environment = DefaultCouchbaseEnvironment.create();
|
||||
this.cluster = CouchbaseCluster.create(this.environment, "localhost");
|
||||
testConnection(this.cluster);
|
||||
return new CouchbaseStatement(base, this.environment, this.cluster);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.info("No couchbase server available");
|
||||
return new SkipStatement();
|
||||
}
|
||||
}
|
||||
|
||||
private static void testConnection(Cluster cluster) {
|
||||
Bucket bucket = cluster.openBucket(2, TimeUnit.SECONDS);
|
||||
bucket.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Couchbase environment if any
|
||||
*/
|
||||
public CouchbaseEnvironment getCouchbaseEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cluster if any
|
||||
*/
|
||||
public Cluster getCluster() {
|
||||
return this.cluster;
|
||||
}
|
||||
|
||||
private static class CouchbaseStatement extends Statement {
|
||||
|
||||
private final Statement base;
|
||||
|
||||
private final CouchbaseEnvironment environment;
|
||||
|
||||
private final Cluster cluster;
|
||||
|
||||
CouchbaseStatement(Statement base, CouchbaseEnvironment environment,
|
||||
Cluster cluster) {
|
||||
this.base = base;
|
||||
this.environment = environment;
|
||||
this.cluster = cluster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
try {
|
||||
this.base.evaluate();
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
if ("couchbaseClient".equals(ex.getBeanName())) {
|
||||
throw new AssumptionViolatedException(
|
||||
"Skipping test due to Couchbase error " + ex.getMessage(),
|
||||
ex);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
this.cluster.disconnect();
|
||||
this.environment.shutdownAsync();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.warn("Exception while trying to cleanup couchbase resource",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class SkipStatement extends Statement {
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
throw new AssumptionViolatedException(
|
||||
"Skipping test due to Couchbase not being available");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.couchbase;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link OnBootstrapHostsCondition}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class OnBootstrapHostsConditionTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapHostsNotDefined() {
|
||||
load(TestConfig.class);
|
||||
assertThat(this.context.containsBean("foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapHostsDefinedAsCommaSeparated() {
|
||||
load(TestConfig.class, "spring.couchbase.bootstrap-hosts=value1");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapHostsDefinedAsList() {
|
||||
load(TestConfig.class, "spring.couchbase.bootstrap-hosts[0]=value1");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapHostsDefinedAsCommaSeparatedRelaxed() {
|
||||
load(TestConfig.class, "spring.couchbase.bootstrapHosts=value1");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapHostsDefinedAsListRelaxed() {
|
||||
load(TestConfig.class, "spring.couchbase.bootstrapHosts[0]=value1");
|
||||
assertThat(this.context.containsBean("foo")).isTrue();
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(environment).applyTo(this.context);
|
||||
this.context.register(config);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional(OnBootstrapHostsCondition.class)
|
||||
protected static class TestConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.dao;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link PersistenceExceptionTranslationAutoConfiguration}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class PersistenceExceptionTranslationAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionTranslationPostProcessorUsesCglibByDefault() {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
PersistenceExceptionTranslationAutoConfiguration.class);
|
||||
Map<String, PersistenceExceptionTranslationPostProcessor> beans = this.context
|
||||
.getBeansOfType(PersistenceExceptionTranslationPostProcessor.class);
|
||||
assertThat(beans).hasSize(1);
|
||||
assertThat(beans.values().iterator().next().isProxyTargetClass()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionTranslationPostProcessorCanBeConfiguredToUseJdkProxy() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("spring.aop.proxy-target-class=false")
|
||||
.applyTo(this.context);
|
||||
this.context.register(PersistenceExceptionTranslationAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
Map<String, PersistenceExceptionTranslationPostProcessor> beans = this.context
|
||||
.getBeansOfType(PersistenceExceptionTranslationPostProcessor.class);
|
||||
assertThat(beans).hasSize(1);
|
||||
assertThat(beans.values().iterator().next().isProxyTargetClass()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionTranslationPostProcessorCanBeDisabled() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("spring.dao.exceptiontranslation.enabled=false")
|
||||
.applyTo(this.context);
|
||||
this.context.register(PersistenceExceptionTranslationAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
Map<String, PersistenceExceptionTranslationPostProcessor> beans = this.context
|
||||
.getBeansOfType(PersistenceExceptionTranslationPostProcessor.class);
|
||||
assertThat(beans.entrySet()).isEmpty();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void persistOfNullThrowsIllegalArgumentExceptionWithoutExceptionTranslation() {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class, TestConfiguration.class);
|
||||
this.context.getBean(TestRepository.class).doSomething();
|
||||
}
|
||||
|
||||
@Test(expected = InvalidDataAccessApiUsageException.class)
|
||||
public void persistOfNullThrowsInvalidDataAccessApiUsageExceptionWithExceptionTranslation() {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class, TestConfiguration.class,
|
||||
PersistenceExceptionTranslationAutoConfiguration.class);
|
||||
this.context.getBean(TestRepository.class).doSomething();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public TestRepository testRepository(EntityManagerFactory entityManagerFactory) {
|
||||
return new TestRepository(entityManagerFactory.createEntityManager());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Repository
|
||||
private static class TestRepository {
|
||||
|
||||
private final EntityManager entityManager;
|
||||
|
||||
TestRepository(EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
public void doSomething() {
|
||||
this.entityManager.persist(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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
|
||||
*
|
||||
* http://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.data.alt.cassandra;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.City;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityCassandraRepository extends Repository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.alt.cassandra;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.City;
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
|
||||
public interface ReactiveCityCassandraRepository
|
||||
extends ReactiveCrudRepository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.data.alt.couchbase;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.couchbase.city.City;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
/**
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public interface CityCouchbaseRepository extends Repository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.data.alt.elasticsearch;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.elasticsearch.city.City;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityElasticsearchDbRepository extends Repository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.data.alt.jpa;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.jpa.city.City;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityJpaRepository extends Repository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.alt.ldap;
|
||||
|
||||
import javax.naming.Name;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.ldap.person.Person;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface PersonLdapRepository extends Repository<Person, Name> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.data.alt.mongo;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.mongo.city.City;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityMongoDbRepository extends Repository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.alt.mongo;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.mongo.city.City;
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
|
||||
public interface ReactiveCityMongoDbRepository
|
||||
extends ReactiveCrudRepository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.alt.neo4j;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.neo4j.city.City;
|
||||
import org.springframework.data.neo4j.repository.Neo4jRepository;
|
||||
|
||||
public interface CityNeo4jRepository extends Neo4jRepository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.data.alt.redis;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.redis.city.City;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityRedisRepository extends Repository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.data.alt.solr;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.solr.city.City;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CitySolrRepository extends Repository<City, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.cassandra;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
|
||||
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.City;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.data.cassandra.config.CassandraSessionFactoryBean;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link CassandraDataAutoConfiguration} that require a Cassandra instance.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CassandraDataAutoConfigurationIntegrationTests {
|
||||
|
||||
@Rule
|
||||
public final CassandraTestServer cassandra = new CassandraTestServer();
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasDefaultSchemaActionSet() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
String cityPackage = City.class.getPackage().getName();
|
||||
AutoConfigurationPackages.register(this.context, cityPackage);
|
||||
this.context.register(CassandraAutoConfiguration.class,
|
||||
CassandraDataAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
CassandraSessionFactoryBean bean = this.context
|
||||
.getBean(CassandraSessionFactoryBean.class);
|
||||
assertThat(bean.getSchemaAction()).isEqualTo(SchemaAction.NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasRecreateSchemaActionSet() {
|
||||
createTestKeyspaceIfNotExists();
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
String cityPackage = City.class.getPackage().getName();
|
||||
AutoConfigurationPackages.register(this.context, cityPackage);
|
||||
TestPropertyValues
|
||||
.of("spring.data.cassandra.schemaAction=recreate_drop_unused",
|
||||
"spring.data.cassandra.keyspaceName=boot_test")
|
||||
.applyTo(this.context);
|
||||
this.context.register(CassandraAutoConfiguration.class,
|
||||
CassandraDataAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
CassandraSessionFactoryBean bean = this.context
|
||||
.getBean(CassandraSessionFactoryBean.class);
|
||||
assertThat(bean.getSchemaAction()).isEqualTo(SchemaAction.RECREATE_DROP_UNUSED);
|
||||
}
|
||||
|
||||
private void createTestKeyspaceIfNotExists() {
|
||||
try (Session session = this.cassandra.getCluster().connect()) {
|
||||
session.execute("CREATE KEYSPACE IF NOT EXISTS boot_test"
|
||||
+ " WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.cassandra;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.City;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.cassandra.core.CassandraTemplate;
|
||||
import org.springframework.data.cassandra.core.convert.CassandraCustomConversions;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.core.mapping.SimpleUserTypeResolver;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CassandraDataAutoConfiguration}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Mark Paluch
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CassandraDataAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void templateExists() {
|
||||
load(TestExcludeConfiguration.class);
|
||||
assertThat(this.context.getBeanNamesForType(CassandraTemplate.class).length)
|
||||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityScanShouldSetInitialEntitySet() throws Exception {
|
||||
load(EntityScanConfig.class);
|
||||
CassandraMappingContext mappingContext = this.context
|
||||
.getBean(CassandraMappingContext.class);
|
||||
Set<Class<?>> initialEntitySet = (Set<Class<?>>) ReflectionTestUtils
|
||||
.getField(mappingContext, "initialEntitySet");
|
||||
assertThat(initialEntitySet).containsOnly(City.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userTypeResolverShouldBeSet() throws Exception {
|
||||
load();
|
||||
CassandraMappingContext mappingContext = this.context
|
||||
.getBean(CassandraMappingContext.class);
|
||||
assertThat(ReflectionTestUtils.getField(mappingContext, "userTypeResolver"))
|
||||
.isInstanceOf(SimpleUserTypeResolver.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultConversions() {
|
||||
load();
|
||||
CassandraTemplate template = this.context.getBean(CassandraTemplate.class);
|
||||
assertThat(template.getConverter().getConversionService().canConvert(Person.class,
|
||||
String.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customConversions() {
|
||||
load(CustomConversionConfig.class);
|
||||
CassandraTemplate template = this.context.getBean(CassandraTemplate.class);
|
||||
assertThat(template.getConverter().getConversionService().canConvert(Person.class,
|
||||
String.class)).isTrue();
|
||||
|
||||
}
|
||||
|
||||
public void load(Class<?>... config) {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("spring.data.cassandra.keyspaceName:boot_test")
|
||||
.applyTo(ctx);
|
||||
if (!ObjectUtils.isEmpty(config)) {
|
||||
ctx.register(config);
|
||||
}
|
||||
ctx.register(TestConfiguration.class, CassandraAutoConfiguration.class,
|
||||
CassandraDataAutoConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(excludeFilters = @ComponentScan.Filter(classes = {
|
||||
Session.class }, type = FilterType.ASSIGNABLE_TYPE))
|
||||
static class TestExcludeConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public Session getObject() {
|
||||
return mock(Session.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EntityScan("org.springframework.boot.autoconfigure.data.cassandra.city")
|
||||
static class EntityScanConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomConversionConfig {
|
||||
|
||||
@Bean
|
||||
public CassandraCustomConversions myCassandraCustomConversions() {
|
||||
return new CassandraCustomConversions(
|
||||
Collections.singletonList(new MyConverter()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MyConverter implements Converter<Person, String> {
|
||||
|
||||
@Override
|
||||
public String convert(Person o) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Person {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.cassandra;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.City;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.cassandra.core.ReactiveCassandraTemplate;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.core.mapping.SimpleUserTypeResolver;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CassandraReactiveDataAutoConfiguration}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class CassandraReactiveDataAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void templateExists() {
|
||||
load("spring.data.cassandra.keyspaceName:boot_test");
|
||||
assertThat(this.context.getBeanNamesForType(ReactiveCassandraTemplate.class))
|
||||
.hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityScanShouldSetInitialEntitySet() throws Exception {
|
||||
load(EntityScanConfig.class, "spring.data.cassandra.keyspaceName:boot_test");
|
||||
CassandraMappingContext mappingContext = this.context
|
||||
.getBean(CassandraMappingContext.class);
|
||||
Set<Class<?>> initialEntitySet = (Set<Class<?>>) ReflectionTestUtils
|
||||
.getField(mappingContext, "initialEntitySet");
|
||||
assertThat(initialEntitySet).containsOnly(City.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userTypeResolverShouldBeSet() throws Exception {
|
||||
load("spring.data.cassandra.keyspaceName:boot_test");
|
||||
CassandraMappingContext mappingContext = this.context
|
||||
.getBean(CassandraMappingContext.class);
|
||||
assertThat(ReflectionTestUtils.getField(mappingContext, "userTypeResolver"))
|
||||
.isInstanceOf(SimpleUserTypeResolver.class);
|
||||
}
|
||||
|
||||
private void load(String... environment) {
|
||||
load(null, environment);
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(environment).applyTo(ctx);
|
||||
if (config != null) {
|
||||
ctx.register(config);
|
||||
}
|
||||
ctx.register(TestConfiguration.class, CassandraAutoConfiguration.class,
|
||||
CassandraDataAutoConfiguration.class,
|
||||
CassandraReactiveDataAutoConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public Session session() {
|
||||
return mock(Session.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EntityScan("org.springframework.boot.autoconfigure.data.cassandra.city")
|
||||
static class EntityScanConfig {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.cassandra;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.datastax.driver.core.Session;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.alt.cassandra.ReactiveCityCassandraRepository;
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.City;
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.ReactiveCityRepository;
|
||||
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.cassandra.ReactiveSession;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.repository.config.EnableReactiveCassandraRepositories;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CassandraReactiveRepositoriesAutoConfiguration}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class CassandraReactiveRepositoriesAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultRepositoryConfiguration() {
|
||||
load(TestConfiguration.class);
|
||||
assertThat(this.context.getBean(ReactiveCityRepository.class)).isNotNull();
|
||||
assertThat(this.context.getBean(Cluster.class)).isNotNull();
|
||||
assertThat(getInitialEntitySet()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRepositoryConfiguration() {
|
||||
load(TestExcludeConfiguration.class, EmptyConfiguration.class);
|
||||
assertThat(this.context.getBean(Cluster.class)).isNotNull();
|
||||
assertThat(getInitialEntitySet()).hasSize(1).containsOnly(City.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
|
||||
load(TestExcludeConfiguration.class, CustomizedConfiguration.class);
|
||||
assertThat(this.context.getBean(ReactiveCityCassandraRepository.class))
|
||||
.isNotNull();
|
||||
assertThat(getInitialEntitySet()).hasSize(1).containsOnly(City.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Set<Class<?>> getInitialEntitySet() {
|
||||
CassandraMappingContext mappingContext = this.context
|
||||
.getBean(CassandraMappingContext.class);
|
||||
return (Set<Class<?>>) ReflectionTestUtils.getField(mappingContext,
|
||||
"initialEntitySet");
|
||||
}
|
||||
|
||||
private void load(Class<?>... configurations) {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(configurations);
|
||||
ctx.register(CassandraAutoConfiguration.class,
|
||||
CassandraRepositoriesAutoConfiguration.class,
|
||||
CassandraDataAutoConfiguration.class,
|
||||
CassandraReactiveDataAutoConfiguration.class,
|
||||
CassandraReactiveRepositoriesAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public Session Session() {
|
||||
return mock(Session.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(EmptyDataPackage.class)
|
||||
static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(CassandraReactiveRepositoriesAutoConfigurationTests.class)
|
||||
@EnableReactiveCassandraRepositories(basePackageClasses = ReactiveCityCassandraRepository.class)
|
||||
static class CustomizedConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(excludeFilters = @Filter(classes = {
|
||||
ReactiveSession.class }, type = FilterType.ASSIGNABLE_TYPE))
|
||||
static class TestExcludeConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.cassandra;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.datastax.driver.core.Session;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.alt.cassandra.CityCassandraRepository;
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.City;
|
||||
import org.springframework.boot.autoconfigure.data.cassandra.city.CityRepository;
|
||||
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CassandraRepositoriesAutoConfiguration}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Mark Paluch
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CassandraRepositoriesAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultRepositoryConfiguration() {
|
||||
addConfigurations(TestConfiguration.class);
|
||||
assertThat(this.context.getBean(CityRepository.class)).isNotNull();
|
||||
assertThat(this.context.getBean(Cluster.class)).isNotNull();
|
||||
assertThat(getInitialEntitySet()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRepositoryConfiguration() {
|
||||
addConfigurations(TestExcludeConfiguration.class, EmptyConfiguration.class);
|
||||
assertThat(this.context.getBean(Cluster.class)).isNotNull();
|
||||
assertThat(getInitialEntitySet()).hasSize(1).containsOnly(City.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
|
||||
addConfigurations(TestExcludeConfiguration.class, CustomizedConfiguration.class);
|
||||
assertThat(this.context.getBean(CityCassandraRepository.class)).isNotNull();
|
||||
assertThat(getInitialEntitySet()).hasSize(1).containsOnly(City.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Set<Class<?>> getInitialEntitySet() {
|
||||
CassandraMappingContext mappingContext = this.context
|
||||
.getBean(CassandraMappingContext.class);
|
||||
return (Set<Class<?>>) ReflectionTestUtils.getField(mappingContext,
|
||||
"initialEntitySet");
|
||||
}
|
||||
|
||||
private void addConfigurations(Class<?>... configurations) {
|
||||
this.context.register(configurations);
|
||||
this.context.register(CassandraAutoConfiguration.class,
|
||||
CassandraRepositoriesAutoConfiguration.class,
|
||||
CassandraDataAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public Session session() {
|
||||
return mock(Session.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(EmptyDataPackage.class)
|
||||
static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(CassandraRepositoriesAutoConfigurationTests.class)
|
||||
@EnableCassandraRepositories(basePackageClasses = CityCassandraRepository.class)
|
||||
static class CustomizedConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(excludeFilters = @ComponentScan.Filter(classes = {
|
||||
Session.class }, type = FilterType.ASSIGNABLE_TYPE))
|
||||
static class TestExcludeConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.data.cassandra;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Assume;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
/**
|
||||
* {@link TestRule} for working with an optional Cassandra server.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CassandraTestServer implements TestRule {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CassandraTestServer.class);
|
||||
|
||||
private Cluster cluster;
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
try {
|
||||
this.cluster = newCluster();
|
||||
return new CassandraStatement(base, this.cluster);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.error("No Cassandra server available", ex);
|
||||
return new SkipStatement();
|
||||
}
|
||||
}
|
||||
|
||||
private Cluster newCluster() {
|
||||
Cluster cluster = Cluster.builder().addContactPoint("localhost").build();
|
||||
testCluster(cluster);
|
||||
return cluster;
|
||||
}
|
||||
|
||||
private void testCluster(Cluster cluster) {
|
||||
cluster.connect().close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cluster if any
|
||||
*/
|
||||
public Cluster getCluster() {
|
||||
return this.cluster;
|
||||
}
|
||||
|
||||
private static class CassandraStatement extends Statement {
|
||||
|
||||
private final Statement base;
|
||||
|
||||
private final Cluster cluster;
|
||||
|
||||
CassandraStatement(Statement base, Cluster cluster) {
|
||||
this.base = base;
|
||||
this.cluster = cluster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
try {
|
||||
this.base.evaluate();
|
||||
}
|
||||
finally {
|
||||
this.cluster.closeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class SkipStatement extends Statement {
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
Assume.assumeTrue("Skipping test due to Cassandra not being available",
|
||||
false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.cassandra.city;
|
||||
|
||||
import com.datastax.driver.core.DataType.Name;
|
||||
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraType;
|
||||
import org.springframework.data.cassandra.core.mapping.Column;
|
||||
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.core.mapping.Table;
|
||||
|
||||
@Table
|
||||
public class City {
|
||||
|
||||
@PrimaryKey
|
||||
@CassandraType(type = Name.BIGINT)
|
||||
private Long id;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
|
||||
@Column
|
||||
private String state;
|
||||
|
||||
@Column
|
||||
private String country;
|
||||
|
||||
@Column
|
||||
private String map;
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return this.country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
public void setMap(String map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2012-2015 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
|
||||
*
|
||||
* http://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.data.cassandra.city;
|
||||
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityRepository extends Repository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.cassandra.city;
|
||||
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
|
||||
public interface ReactiveCityRepository extends ReactiveCrudRepository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.couchbase;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties;
|
||||
import org.springframework.boot.autoconfigure.couchbase.CouchbaseTestConfigurer;
|
||||
import org.springframework.boot.autoconfigure.data.couchbase.city.City;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration;
|
||||
import org.springframework.data.couchbase.config.BeanNames;
|
||||
import org.springframework.data.couchbase.config.CouchbaseConfigurer;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseCustomConversions;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
|
||||
import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener;
|
||||
import org.springframework.data.couchbase.core.query.Consistency;
|
||||
import org.springframework.data.couchbase.repository.support.IndexManager;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link CouchbaseDataAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CouchbaseDataAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disabledIfCouchbaseIsNotConfigured() {
|
||||
load(null);
|
||||
assertThat(this.context.getBeansOfType(IndexManager.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customConfiguration() {
|
||||
load(CustomCouchbaseConfiguration.class);
|
||||
CouchbaseTemplate couchbaseTemplate = this.context
|
||||
.getBean(CouchbaseTemplate.class);
|
||||
assertThat(couchbaseTemplate.getDefaultConsistency())
|
||||
.isEqualTo(Consistency.STRONGLY_CONSISTENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validatorIsPresent() {
|
||||
load(CouchbaseTestConfigurer.class);
|
||||
assertThat(this.context.getBeansOfType(ValidatingCouchbaseEventListener.class))
|
||||
.hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoIndexIsDisabledByDefault() {
|
||||
load(CouchbaseTestConfigurer.class);
|
||||
IndexManager indexManager = this.context.getBean(IndexManager.class);
|
||||
assertThat(indexManager.isIgnoreViews()).isTrue();
|
||||
assertThat(indexManager.isIgnoreN1qlPrimary()).isTrue();
|
||||
assertThat(indexManager.isIgnoreN1qlSecondary()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableAutoIndex() {
|
||||
load(CouchbaseTestConfigurer.class, "spring.data.couchbase.auto-index=true");
|
||||
IndexManager indexManager = this.context.getBean(IndexManager.class);
|
||||
assertThat(indexManager.isIgnoreViews()).isFalse();
|
||||
assertThat(indexManager.isIgnoreN1qlPrimary()).isFalse();
|
||||
assertThat(indexManager.isIgnoreN1qlSecondary()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeConsistency() {
|
||||
load(CouchbaseTestConfigurer.class,
|
||||
"spring.data.couchbase.consistency=eventually-consistent");
|
||||
SpringBootCouchbaseDataConfiguration configuration = this.context
|
||||
.getBean(SpringBootCouchbaseDataConfiguration.class);
|
||||
assertThat(configuration.getDefaultConsistency())
|
||||
.isEqualTo(Consistency.EVENTUALLY_CONSISTENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityScanShouldSetInitialEntitySet() throws Exception {
|
||||
load(EntityScanConfig.class);
|
||||
CouchbaseMappingContext mappingContext = this.context
|
||||
.getBean(CouchbaseMappingContext.class);
|
||||
Set<Class<?>> initialEntitySet = (Set<Class<?>>) ReflectionTestUtils
|
||||
.getField(mappingContext, "initialEntitySet");
|
||||
assertThat(initialEntitySet).containsOnly(City.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customConversions() {
|
||||
load(CustomConversionsConfig.class);
|
||||
CouchbaseTemplate template = this.context.getBean(CouchbaseTemplate.class);
|
||||
assertThat(template.getConverter().getConversionService()
|
||||
.canConvert(CouchbaseProperties.class, Boolean.class)).isTrue();
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(environment).applyTo(context);
|
||||
if (config != null) {
|
||||
context.register(config);
|
||||
}
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
ValidationAutoConfiguration.class, CouchbaseAutoConfiguration.class,
|
||||
CouchbaseDataAutoConfiguration.class);
|
||||
context.refresh();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomCouchbaseConfiguration extends AbstractCouchbaseDataConfiguration {
|
||||
|
||||
@Override
|
||||
protected CouchbaseConfigurer couchbaseConfigurer() {
|
||||
return new CouchbaseTestConfigurer();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Consistency getDefaultConsistency() {
|
||||
return Consistency.STRONGLY_CONSISTENT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(CouchbaseTestConfigurer.class)
|
||||
static class CustomConversionsConfig {
|
||||
|
||||
@Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS)
|
||||
public CouchbaseCustomConversions myCustomConversions() {
|
||||
return new CouchbaseCustomConversions(
|
||||
Collections.singletonList(new MyConverter()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EntityScan("org.springframework.boot.autoconfigure.data.couchbase.city")
|
||||
@Import(CustomCouchbaseConfiguration.class)
|
||||
static class EntityScanConfig {
|
||||
|
||||
}
|
||||
|
||||
static class MyConverter implements Converter<CouchbaseProperties, Boolean> {
|
||||
|
||||
@Override
|
||||
public Boolean convert(CouchbaseProperties value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.couchbase;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.couchbase.CouchbaseTestConfigurer;
|
||||
import org.springframework.boot.autoconfigure.data.couchbase.city.City;
|
||||
import org.springframework.boot.autoconfigure.data.couchbase.city.CityRepository;
|
||||
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link CouchbaseRepositoriesAutoConfiguration}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CouchbaseRepositoriesAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void couchbaseNotAvailable() throws Exception {
|
||||
load(null);
|
||||
assertThat(this.context.getBeansOfType(CityRepository.class)).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultRepository() throws Exception {
|
||||
load(DefaultConfiguration.class);
|
||||
assertThat(this.context.getBeansOfType(CityRepository.class)).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableRepository() {
|
||||
load(DefaultConfiguration.class,
|
||||
"spring.data.couchbase.repositories.enabled=false");
|
||||
assertThat(this.context.getBeansOfType(CityRepository.class)).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRepositoryAvailable() throws Exception {
|
||||
load(NoRepositoryConfiguration.class);
|
||||
assertThat(this.context.getBeansOfType(CityRepository.class)).hasSize(0);
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of(environment).applyTo(context);
|
||||
if (config != null) {
|
||||
context.register(config);
|
||||
}
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
CouchbaseAutoConfiguration.class, CouchbaseDataAutoConfiguration.class,
|
||||
CouchbaseRepositoriesAutoConfiguration.class);
|
||||
context.refresh();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
static class CouchbaseNotAvailableConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
@Import(CouchbaseTestConfigurer.class)
|
||||
static class DefaultConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(EmptyDataPackage.class)
|
||||
@Import(CouchbaseTestConfigurer.class)
|
||||
protected static class NoRepositoryConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.data.couchbase.city;
|
||||
|
||||
import com.couchbase.client.java.repository.annotation.Field;
|
||||
import com.couchbase.client.java.repository.annotation.Id;
|
||||
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
@Document
|
||||
public class City {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
@Field
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.data.couchbase.city;
|
||||
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityRepository extends Repository<City, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.elasticsearch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.client.transport.TransportClient;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ElasticsearchAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class ElasticsearchAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useExistingClient() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(CustomConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
ElasticsearchAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBeanNamesForType(Client.class).length).isEqualTo(1);
|
||||
assertThat(this.context.getBean("myClient"))
|
||||
.isSameAs(this.context.getBean(Client.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTransportClient() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
new ElasticsearchNodeTemplate().doWithNode((node) -> {
|
||||
TestPropertyValues
|
||||
.of("spring.data.elasticsearch.cluster-nodes:localhost:"
|
||||
+ node.getTcpPort(),
|
||||
"spring.data.elasticsearch.properties.path.home:target/es/client")
|
||||
.applyTo(this.context);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
ElasticsearchAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
List<DiscoveryNode> connectedNodes = this.context
|
||||
.getBean(TransportClient.class).connectedNodes();
|
||||
assertThat(connectedNodes).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
public Client myClient() {
|
||||
return mock(Client.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.elasticsearch;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ElasticsearchDataAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Artur Konczak
|
||||
*/
|
||||
public class ElasticsearchDataAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void templateBackOffWithNoClient() {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
ElasticsearchDataAutoConfiguration.class);
|
||||
assertThat(this.context.getBeansOfType(ElasticsearchTemplate.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void templateExists() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
new ElasticsearchNodeTemplate().doWithNode((node) -> {
|
||||
TestPropertyValues
|
||||
.of("spring.data.elasticsearch.properties.path.data:target/data",
|
||||
"spring.data.elasticsearch.properties.path.logs:target/logs",
|
||||
"spring.data.elasticsearch.cluster-nodes:localhost:"
|
||||
+ node.getTcpPort())
|
||||
.applyTo(this.context);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
ElasticsearchAutoConfiguration.class,
|
||||
ElasticsearchDataAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertHasSingleBean(ElasticsearchTemplate.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mappingContextExists() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
new ElasticsearchNodeTemplate().doWithNode((node) -> {
|
||||
TestPropertyValues
|
||||
.of("spring.data.elasticsearch.properties.path.data:target/data",
|
||||
"spring.data.elasticsearch.properties.path.logs:target/logs",
|
||||
"spring.data.elasticsearch.cluster-nodes:localhost:"
|
||||
+ node.getTcpPort())
|
||||
.applyTo(this.context);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
ElasticsearchAutoConfiguration.class,
|
||||
ElasticsearchDataAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertHasSingleBean(SimpleElasticsearchMappingContext.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void converterExists() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
new ElasticsearchNodeTemplate().doWithNode((node) -> {
|
||||
TestPropertyValues
|
||||
.of("spring.data.elasticsearch.properties.path.data:target/data",
|
||||
"spring.data.elasticsearch.properties.path.logs:target/logs",
|
||||
"spring.data.elasticsearch.cluster-nodes:localhost:"
|
||||
+ node.getTcpPort())
|
||||
.applyTo(this.context);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
ElasticsearchAutoConfiguration.class,
|
||||
ElasticsearchDataAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertHasSingleBean(ElasticsearchConverter.class);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertHasSingleBean(Class<?> type) {
|
||||
assertThat(this.context.getBeanNamesForType(type)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.elasticsearch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.node.InternalSettingsPreparer;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.node.NodeValidationException;
|
||||
import org.elasticsearch.transport.Netty4Plugin;
|
||||
import org.elasticsearch.transport.Transport;
|
||||
|
||||
/**
|
||||
* Helper class for managing an Elasticsearch {@link Node}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class ElasticsearchNodeTemplate {
|
||||
|
||||
public void doWithNode(Consumer<ElasticsearchNode> consumer) {
|
||||
System.setProperty("es.set.netty.runtime.available.processors", "false");
|
||||
Node node = null;
|
||||
try {
|
||||
node = startNode();
|
||||
consumer.accept(new ElasticsearchNode(node));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
finally {
|
||||
if (node != null) {
|
||||
try {
|
||||
node.close();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Continue
|
||||
}
|
||||
}
|
||||
System.clearProperty("es.set.netty.runtime.available.processors");
|
||||
}
|
||||
}
|
||||
|
||||
private Node startNode() throws NodeValidationException {
|
||||
Node node = new NettyTransportNode();
|
||||
node.start();
|
||||
return node;
|
||||
}
|
||||
|
||||
private static final class NettyTransportNode extends Node {
|
||||
|
||||
private NettyTransportNode() {
|
||||
super(InternalSettingsPreparer.prepareEnvironment(Settings.builder()
|
||||
.put("path.home", "target/es/node").put("transport.type", "netty4")
|
||||
.put("http.enabled", true).put("node.portsfile", true)
|
||||
.put("http.port", 0).put("transport.tcp.port", 0).build(), null),
|
||||
Arrays.asList(Netty4Plugin.class));
|
||||
new File("target/es/node/logs").mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public final class ElasticsearchNode {
|
||||
|
||||
private final Node node;
|
||||
|
||||
private ElasticsearchNode(Node node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public int getTcpPort() {
|
||||
return this.node.injector().getInstance(Transport.class).boundAddress()
|
||||
.publishAddress().getPort();
|
||||
}
|
||||
|
||||
public int getHttpPort() {
|
||||
try {
|
||||
for (String line : Files
|
||||
.readAllLines(Paths.get("target/es/node/logs/http.ports"))) {
|
||||
if (line.startsWith("127.0.0.1")) {
|
||||
return Integer.parseInt(line.substring(line.indexOf(":") + 1));
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("HTTP port not found");
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Failed to read HTTP port", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.data.elasticsearch;
|
||||
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.alt.elasticsearch.CityElasticsearchDbRepository;
|
||||
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchNodeTemplate.ElasticsearchNode;
|
||||
import org.springframework.boot.autoconfigure.data.elasticsearch.city.City;
|
||||
import org.springframework.boot.autoconfigure.data.elasticsearch.city.CityRepository;
|
||||
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ElasticsearchRepositoriesAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class ElasticsearchRepositoriesAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultRepositoryConfiguration() throws Exception {
|
||||
new ElasticsearchNodeTemplate().doWithNode((node) -> {
|
||||
load(TestConfiguration.class, node);
|
||||
assertThat(this.context.getBean(CityRepository.class)).isNotNull();
|
||||
assertThat(this.context.getBean(Client.class)).isNotNull();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRepositoryConfiguration() throws Exception {
|
||||
new ElasticsearchNodeTemplate().doWithNode((node) -> {
|
||||
load(EmptyConfiguration.class, node);
|
||||
assertThat(this.context.getBean(Client.class)).isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
|
||||
new ElasticsearchNodeTemplate().doWithNode((node) -> {
|
||||
load(CustomizedConfiguration.class, node);
|
||||
assertThat(this.context.getBean(CityElasticsearchDbRepository.class))
|
||||
.isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
private void load(Class<?> config, ElasticsearchNode node) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
addElasticsearchProperties(this.context, node);
|
||||
this.context.register(config, ElasticsearchAutoConfiguration.class,
|
||||
ElasticsearchRepositoriesAutoConfiguration.class,
|
||||
ElasticsearchDataAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
private void addElasticsearchProperties(AnnotationConfigApplicationContext context,
|
||||
ElasticsearchNode node) {
|
||||
TestPropertyValues.of("spring.data.elasticsearch.properties.path.home:target",
|
||||
"spring.data.elasticsearch.cluster-nodes:localhost:" + node.getTcpPort())
|
||||
.applyTo(context);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
protected static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(EmptyDataPackage.class)
|
||||
protected static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@TestAutoConfigurationPackage(ElasticsearchRepositoriesAutoConfigurationTests.class)
|
||||
@EnableElasticsearchRepositories(basePackageClasses = CityElasticsearchDbRepository.class)
|
||||
protected static class CustomizedConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.data.elasticsearch.city;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
|
||||
@Document(indexName = "city", type = "city", shards = 1, replicas = 0, refreshInterval = "-1")
|
||||
public class City implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String state;
|
||||
|
||||
private String country;
|
||||
|
||||
private String map;
|
||||
|
||||
protected City() {
|
||||
}
|
||||
|
||||
public City(String name, String country) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return this.country;
|
||||
}
|
||||
|
||||
public String getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + "," + getState() + "," + getCountry();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.data.elasticsearch.city;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityRepository extends Repository<City, Long> {
|
||||
|
||||
Page<City> findAll(Pageable pageable);
|
||||
|
||||
Page<City> findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country,
|
||||
Pageable pageable);
|
||||
|
||||
City findByNameAndCountryAllIgnoringCase(String name, String country);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.data.empty;
|
||||
|
||||
/**
|
||||
* Empty package used with data tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class EmptyDataPackage {
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user