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:
Phillip Webb
2017-09-19 14:29:46 -07:00
parent 0419d42b7c
commit 0ba4830b4f
4023 changed files with 0 additions and 0 deletions

View File

@@ -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 {
}

View File

@@ -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());
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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");
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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();
}

View File

@@ -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")));
}
}

View File

@@ -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()));
}
}

View File

@@ -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() });
}
}

View File

@@ -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 {
}
}

View File

@@ -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");
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}
}

View File

@@ -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> {
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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");
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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";
}
}
}

View File

@@ -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";
}
}
}

View File

@@ -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";
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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";
}
}
}

View File

@@ -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";
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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";
}
}
}

View File

@@ -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";
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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() };
}
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}
}
}

View File

@@ -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!");
}
}
}

View File

@@ -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");
}
}

View File

@@ -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 {
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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];
}
};
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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");
}
}
}

View File

@@ -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";
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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 };");
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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;
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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;
}

View File

@@ -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> {
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}

View File

@@ -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