diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml index 5bb22665d7..6e79790e0f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml @@ -234,11 +234,6 @@ kafka-clients true - - org.apache.logging.log4j - log4j-core - true - org.apache.tomcat.embed tomcat-embed-core @@ -488,7 +483,7 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-to-slf4j test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java index bc646e623c..5551c7df88 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java @@ -16,12 +16,10 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import java.util.Collections; - import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.spi.LoggerContext; import org.springframework.boot.actuate.autoconfigure.metrics.Log4J2MetricsAutoConfiguration.Log4JCoreLoggerContextCondition; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -44,7 +42,8 @@ import org.springframework.core.type.AnnotatedTypeMetadata; */ @Configuration @AutoConfigureAfter(MetricsAutoConfiguration.class) -@ConditionalOnClass({ Log4j2Metrics.class, LoggerContext.class, LogManager.class }) +@ConditionalOnClass(value = { Log4j2Metrics.class, + LogManager.class }, name = "org.apache.logging.log4j.core.LoggerContext") @ConditionalOnBean(MeterRegistry.class) @Conditional(Log4JCoreLoggerContextCondition.class) public class Log4J2MetricsAutoConfiguration { @@ -52,8 +51,7 @@ public class Log4J2MetricsAutoConfiguration { @Bean @ConditionalOnMissingBean public Log4j2Metrics log4j2Metrics() { - return new Log4j2Metrics(Collections.emptyList(), - (LoggerContext) LogManager.getContext(false)); + return new Log4j2Metrics(); } static class Log4JCoreLoggerContextCondition extends SpringBootCondition { @@ -61,14 +59,19 @@ public class Log4J2MetricsAutoConfiguration { @Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { - org.apache.logging.log4j.spi.LoggerContext loggerContext = LogManager - .getContext(false); - if (loggerContext instanceof LoggerContext) { - return ConditionOutcome.match( - "LoggerContext was an instance of org.apache.logging.log4j.spi.LoggerContext"); + LoggerContext loggerContext = LogManager.getContext(false); + try { + if (Class.forName("org.apache.logging.log4j.core.LoggerContext") + .isInstance(loggerContext)) { + return ConditionOutcome.match( + "LoggerContext was an instance of org.apache.logging.log4j.core.LoggerContext"); + } + } + catch (Throwable ex) { + // Continue with no match } return ConditionOutcome.noMatch( - "Logger context was not an instance of org.apache.logging.log4j.spi.LoggerContext"); + "Logger context was not an instance of org.apache.logging.log4j.core.LoggerContext"); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java similarity index 74% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java index a450b3733b..6521af77fe 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java @@ -17,11 +17,15 @@ package org.springframework.boot.actuate.autoconfigure.metrics; import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; -import org.junit.jupiter.api.Test; +import org.apache.logging.log4j.LogManager; +import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.runner.classpath.ClassPathOverrides; +import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -32,7 +36,9 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Andy Wilkinson */ -public class Log4J2MetricsAutoConfigurationTests { +@RunWith(ModifiedClassPathRunner.class) +@ClassPathOverrides("org.apache.logging.log4j:log4j-core:2.11.1") +public class Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .with(MetricsRun.simple()).withConfiguration( @@ -40,12 +46,16 @@ public class Log4J2MetricsAutoConfigurationTests { @Test public void autoConfiguresLog4J2Metrics() { + assertThat(LogManager.getContext().getClass().getName()) + .isEqualTo("org.apache.logging.log4j.core.LoggerContext"); this.contextRunner .run((context) -> assertThat(context).hasSingleBean(Log4j2Metrics.class)); } @Test public void allowsCustomLog4J2MetricsToBeUsed() { + assertThat(LogManager.getContext().getClass().getName()) + .isEqualTo("org.apache.logging.log4j.core.LoggerContext"); this.contextRunner.withUserConfiguration(CustomLog4J2MetricsConfiguration.class) .run((context) -> assertThat(context).hasSingleBean(Log4j2Metrics.class) .hasBean("customLog4J2Metrics")); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java index d1fb3209a5..4f78a3efc2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java @@ -17,15 +17,13 @@ package org.springframework.boot.actuate.autoconfigure.metrics; import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.slf4j.SLF4JLoggerContext; +import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; -import org.springframework.boot.testsupport.runner.classpath.ClassPathOverrides; -import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -34,10 +32,6 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Andy Wilkinson */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathOverrides({ "org.apache.logging.log4j:log4j-to-slf4j:2.11.1", - "org.apache.logging.log4j:log4j-core:2.11.1" }) -@ClassPathExclusions("log4j-slf4j-impl-*.jar") public class Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() @@ -46,6 +40,7 @@ public class Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests { @Test public void backsOffWhenLoggerContextIsBackedBySlf4j() { + assertThat(LogManager.getContext()).isInstanceOf(SLF4JLoggerContext.class); this.contextRunner.run( (context) -> assertThat(context).doesNotHaveBean(Log4j2Metrics.class)); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/log4j2-test.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/log4j2-test.xml deleted file mode 100644 index 8c0f7f4652..0000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/log4j2-test.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - %xwEx - %5p - - - - - - - - - - - - diff --git a/spring-boot-project/spring-boot-actuator/pom.xml b/spring-boot-project/spring-boot-actuator/pom.xml index 476bf80c91..2e7a6ac1af 100644 --- a/spring-boot-project/spring-boot-actuator/pom.xml +++ b/spring-boot-project/spring-boot-actuator/pom.xml @@ -294,23 +294,18 @@ test - javax.xml.bind - jaxb-api + ch.qos.logback + logback-classic test - org.apache.logging.log4j - log4j-slf4j-impl - test - - - org.apache.logging.log4j - log4j-api + javax.xml.bind + jaxb-api test org.apache.logging.log4j - log4j-core + log4j-to-slf4j test diff --git a/spring-boot-project/spring-boot-autoconfigure/pom.xml b/spring-boot-project/spring-boot-autoconfigure/pom.xml index 02a879739b..eb446dedb1 100755 --- a/spring-boot-project/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-autoconfigure/pom.xml @@ -767,7 +767,7 @@ org.apache.logging.log4j - log4j-core + log4j-to-slf4j test @@ -790,11 +790,6 @@ neo4j-ogm-embedded-driver test - - org.slf4j - log4j-over-slf4j - test - org.springframework spring-test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchAutoConfigurationTests.java index 463225fc3c..f27902e55b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchAutoConfigurationTests.java @@ -13,7 +13,6 @@ * 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; @@ -22,10 +21,12 @@ import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.cluster.node.DiscoveryNode; import org.junit.After; -import org.junit.jupiter.api.Test; +import org.junit.ClassRule; +import org.junit.Test; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.testsupport.testcontainers.ElasticsearchContainer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -41,6 +42,9 @@ import static org.mockito.Mockito.mock; */ public class ElasticsearchAutoConfigurationTests { + @ClassRule + public static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(); + private AnnotationConfigApplicationContext context; @After @@ -65,19 +69,17 @@ public class ElasticsearchAutoConfigurationTests { @Test public void createTransportClient() { 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 connectedNodes = this.context - .getBean(TransportClient.class).connectedNodes(); - assertThat(connectedNodes).hasSize(1); - }); + TestPropertyValues + .of("spring.data.elasticsearch.cluster-nodes:localhost:" + + elasticsearch.getMappedTransportPort(), + "spring.data.elasticsearch.cluster-name:docker-cluster") + .applyTo(this.context); + this.context.register(PropertyPlaceholderAutoConfiguration.class, + ElasticsearchAutoConfiguration.class); + this.context.refresh(); + List connectedNodes = this.context.getBean(TransportClient.class) + .connectedNodes(); + assertThat(connectedNodes).hasSize(1); } @Configuration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfigurationTests.java index 5fded2443f..b020a764b2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfigurationTests.java @@ -17,10 +17,12 @@ package org.springframework.boot.autoconfigure.data.elasticsearch; import org.junit.After; -import org.junit.jupiter.api.Test; +import org.junit.ClassRule; +import org.junit.Test; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.testsupport.testcontainers.ElasticsearchContainer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; @@ -36,6 +38,9 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class ElasticsearchDataAutoConfigurationTests { + @ClassRule + public static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(); + private AnnotationConfigApplicationContext context; @After @@ -55,55 +60,46 @@ public class ElasticsearchDataAutoConfigurationTests { @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); - }); + TestPropertyValues + .of("spring.data.elasticsearch.cluster-nodes:localhost:" + + elasticsearch.getMappedTransportPort(), + "spring.data.elasticsearch.cluster-name:docker-cluster") + .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); - }); + TestPropertyValues + .of("spring.data.elasticsearch.cluster-nodes:localhost:" + + elasticsearch.getMappedTransportPort(), + "spring.data.elasticsearch.cluster-name:docker-cluster") + .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); - }); + TestPropertyValues + .of("spring.data.elasticsearch.cluster-nodes:localhost:" + + elasticsearch.getMappedTransportPort(), + "spring.data.elasticsearch.cluster-name:docker-cluster") + .applyTo(this.context); + this.context.register(PropertyPlaceholderAutoConfiguration.class, + ElasticsearchAutoConfiguration.class, + ElasticsearchDataAutoConfiguration.class); + this.context.refresh(); + assertHasSingleBean(ElasticsearchConverter.class); } private void assertHasSingleBean(Class type) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchNodeTemplate.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchNodeTemplate.java deleted file mode 100644 index 26324550c1..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchNodeTemplate.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2012-2018 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 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); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java index 1c4a5965d5..8bc54b69cb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java @@ -18,19 +18,17 @@ package org.springframework.boot.autoconfigure.data.elasticsearch; import org.elasticsearch.client.Client; import org.junit.After; +import org.junit.ClassRule; import org.junit.Test; -import org.junit.runner.RunWith; 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.boot.testsupport.runner.classpath.ClassPathOverrides; -import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; +import org.springframework.boot.testsupport.testcontainers.ElasticsearchContainer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -43,10 +41,11 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Phillip Webb * @author Andy Wilkinson */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathOverrides("org.apache.logging.log4j:log4j-core:2.10.0") public class ElasticsearchRepositoriesAutoConfigurationTests { + @ClassRule + public static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(); + private AnnotationConfigApplicationContext context; @After @@ -56,34 +55,27 @@ public class ElasticsearchRepositoriesAutoConfigurationTests { @Test public void testDefaultRepositoryConfiguration() { - new ElasticsearchNodeTemplate().doWithNode((node) -> { - load(TestConfiguration.class, node); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - assertThat(this.context.getBean(Client.class)).isNotNull(); - }); + load(TestConfiguration.class); + assertThat(this.context.getBean(CityRepository.class)).isNotNull(); + assertThat(this.context.getBean(Client.class)).isNotNull(); } @Test public void testNoRepositoryConfiguration() { - new ElasticsearchNodeTemplate().doWithNode((node) -> { - load(EmptyConfiguration.class, node); - assertThat(this.context.getBean(Client.class)).isNotNull(); - }); + load(EmptyConfiguration.class); + 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(); - }); + load(CustomizedConfiguration.class); + assertThat(this.context.getBean(CityElasticsearchDbRepository.class)).isNotNull(); } - private void load(Class config, ElasticsearchNode node) { + private void load(Class config) { this.context = new AnnotationConfigApplicationContext(); - addElasticsearchProperties(this.context, node); + addElasticsearchProperties(this.context); this.context.register(config, ElasticsearchAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, @@ -91,11 +83,11 @@ public class ElasticsearchRepositoriesAutoConfigurationTests { 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); + private void addElasticsearchProperties(AnnotationConfigApplicationContext context) { + TestPropertyValues.of( + "spring.data.elasticsearch.cluster-nodes:localhost:" + + elasticsearch.getMappedTransportPort(), + "spring.data.elasticsearch.cluster-name:docker-cluster").applyTo(context); } @Configuration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/jest/JestAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/jest/JestAutoConfigurationTests.java index 10136b5e94..5f87d1a41f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/jest/JestAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/jest/JestAutoConfigurationTests.java @@ -27,18 +27,14 @@ import io.searchbox.client.JestResult; import io.searchbox.client.http.JestHttpClient; import io.searchbox.core.Get; import io.searchbox.core.Index; -import org.junit.After; -import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchNodeTemplate; import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.testsupport.runner.classpath.ClassPathOverrides; -import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; +import org.springframework.boot.testsupport.testcontainers.ElasticsearchContainer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -52,24 +48,15 @@ import static org.mockito.Mockito.mock; * @author Stephane Nicoll * @author Andy Wilkinson */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathOverrides("org.apache.logging.log4j:log4j-core:2.10.0") public class JestAutoConfigurationTests { + @ClassRule + public static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(); + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(GsonAutoConfiguration.class, JestAutoConfiguration.class)); - @Before - public void preventElasticsearchFromConfiguringNetty() { - System.setProperty("es.set.netty.runtime.available.processors", "false"); - } - - @After - public void close() { - System.clearProperty("es.set.netty.runtime.available.processors"); - } - @Test public void jestClientOnLocalhostByDefault() { this.contextRunner @@ -122,9 +109,9 @@ public class JestAutoConfigurationTests { @Test public void jestCanCommunicateWithElasticsearchInstance() { - new ElasticsearchNodeTemplate().doWithNode((node) -> this.contextRunner + this.contextRunner .withPropertyValues("spring.elasticsearch.jest.uris=http://localhost:" - + node.getHttpPort()) + + elasticsearch.getMappedPort()) .run((context) -> { JestClient client = context.getBean(JestClient.class); Map source = new HashMap<>(); @@ -136,7 +123,7 @@ public class JestAutoConfigurationTests { Get getRequest = new Get.Builder("foo", "1").build(); assertThat(execute(client, getRequest).getResponseCode()) .isEqualTo(200); - })); + }); } private JestResult execute(JestClient client, Action action) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/rest/RestClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/rest/RestClientAutoConfigurationTests.java index 280f65de61..391e1df09c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/rest/RestClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/rest/RestClientAutoConfigurationTests.java @@ -25,11 +25,12 @@ import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; -import org.junit.jupiter.api.Test; +import org.junit.ClassRule; +import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchNodeTemplate; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.testcontainers.ElasticsearchContainer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.ReflectionUtils; @@ -44,6 +45,9 @@ import static org.mockito.Mockito.mock; */ public class RestClientAutoConfigurationTests { + @ClassRule + public static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(); + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class)); @@ -77,9 +81,9 @@ public class RestClientAutoConfigurationTests { @Test public void restClientCanQueryElasticsearchNode() { - new ElasticsearchNodeTemplate().doWithNode((node) -> this.contextRunner + this.contextRunner .withPropertyValues("spring.elasticsearch.rest.uris=http://localhost:" - + node.getHttpPort()) + + RestClientAutoConfigurationTests.elasticsearch.getMappedPort()) .run((context) -> { RestHighLevelClient client = context .getBean(RestHighLevelClient.class); @@ -92,7 +96,7 @@ public class RestClientAutoConfigurationTests { GetRequest getRequest = new GetRequest("foo", "bar", "1"); assertThat(client.get(getRequest, RequestOptions.DEFAULT).isExists()) .isTrue(); - })); + }); } @Configuration diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Container.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Container.java index 3c2f5dea47..9057b6a76e 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Container.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Container.java @@ -77,6 +77,10 @@ class Container implements TestRule { return this.container.getMappedPort(this.port); } + protected GenericContainer getContainer() { + return this.container; + } + private static class SkipStatement extends Statement { @Override diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/ElasticsearchContainer.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/ElasticsearchContainer.java new file mode 100644 index 0000000000..742a53dc78 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/ElasticsearchContainer.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-2018 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.testsupport.testcontainers; + +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +/** + * A {@link Container} for Elasticsearch. + * + * @author Andy Wilkinson + */ +public class ElasticsearchContainer extends Container { + + public ElasticsearchContainer() { + super("elasticsearch:6.4.3", 9200, (container) -> container.addExposedPort(9300)); + } + + public int getMappedTransportPort() { + return getContainer().getMappedPort(9300); + } + + @Override + public Statement apply(Statement base, Description description) { + Statement wrapped = super.apply(base, description); + return new Statement() { + + @Override + public void evaluate() throws Throwable { + System.setProperty("es.set.netty.runtime.available.processors", "false"); + try { + wrapped.evaluate(); + } + finally { + System.clearProperty("es.set.netty.runtime.available.processors"); + } + } + + }; + + } + +}