diff --git a/build.gradle b/build.gradle index b120502..e9fa553 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { ext { - springBootVersion = '2.7.18' + springBootVersion = '3.3.13' } repositories { mavenCentral() @@ -34,17 +34,14 @@ dependencies { implementation('org.springframework.boot:spring-boot-starter-actuator') implementation('org.springframework.boot:spring-boot-starter-thymeleaf') implementation('com.fasterxml.jackson.dataformat:jackson-dataformat-yaml') - implementation('org.apache.httpcomponents:httpclient') + implementation('org.apache.httpcomponents.client5:httpclient5') implementation('org.springframework.data:spring-data-commons') compileOnly('org.projectlombok:lombok') runtimeOnly('org.webjars:webjars-locator-core') - runtimeOnly('org.webjars:bootstrap:5.3.3') + runtimeOnly('org.webjars:bootstrap:5.3.7') runtimeOnly('org.springframework.boot:spring-boot-devtools') - testImplementation('junit:junit') - testImplementation('org.assertj:assertj-core') - testImplementation('org.mockito:mockito-core') testImplementation('org.springframework.boot:spring-boot-starter-test') testCompileOnly('org.projectlombok:lombok') @@ -55,3 +52,7 @@ dependencies { bootRun { systemProperties System.properties } + +test { + useJUnitPlatform() +} diff --git a/src/main/java/com/epages/readiness/RestTemplateConfiguration.java b/src/main/java/com/epages/readiness/RestTemplateConfiguration.java index d4e9133..96775be 100644 --- a/src/main/java/com/epages/readiness/RestTemplateConfiguration.java +++ b/src/main/java/com/epages/readiness/RestTemplateConfiguration.java @@ -5,12 +5,14 @@ import javax.net.ssl.SSLContext; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.ssl.SSLContexts; -import org.apache.http.ssl.TrustStrategy; +import org.apache.hc.client5.http.classic.HttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; +import org.apache.hc.core5.ssl.SSLContexts; +import org.apache.hc.core5.ssl.TrustStrategy; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,9 +38,13 @@ public HttpClient insecureHttpClient(@Value("${spring.application.name}") String // http://stackoverflow.com/a/41618092/1393467 TrustStrategy trustStrategy = (X509Certificate[] chain, String authType) -> true; SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, trustStrategy).build(); - return configure(HttpClients.custom(), userAgent) - .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext)) - .build(); + + return configure( + HttpClients.custom(), + userAgent, + SSLConnectionSocketFactoryBuilder.create() + .setSslContext(sslContext).build() + ).build(); } @Bean("httpClient") @@ -48,18 +54,29 @@ public HttpClient secureHttpClient(@Value("${spring.application.name}") String u } private HttpClientBuilder configure(HttpClientBuilder builder, String userAgent) { + return configure(builder, userAgent, null); + } + + private HttpClientBuilder configure(HttpClientBuilder builder, String userAgent, SSLConnectionSocketFactory sslSocketFactory) { + + PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create() + .setMaxConnTotal(settings.getServices().size()) + .setMaxConnPerRoute(settings.getServices().size()); + + if (sslSocketFactory != null) { + connectionManagerBuilder.setSSLSocketFactory(sslSocketFactory); + } + return builder .setUserAgent(userAgent) .disableAutomaticRetries() - .setMaxConnTotal(settings.getServices().size()) - .setMaxConnPerRoute(settings.getServices().size()); + .setConnectionManager(connectionManagerBuilder.build()); } @Bean public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) { HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); factory.setConnectTimeout(settings.getConnectionTimeout()); - factory.setReadTimeout(settings.getReadTimeout()); factory.setConnectionRequestTimeout(settings.getConnectionRequestTimeout()); return factory; } diff --git a/src/test/java/com/epages/readiness/CommandLineRunnerTest.java b/src/test/java/com/epages/readiness/CommandLineRunnerTest.java index 77850cf..487337f 100644 --- a/src/test/java/com/epages/readiness/CommandLineRunnerTest.java +++ b/src/test/java/com/epages/readiness/CommandLineRunnerTest.java @@ -1,21 +1,21 @@ package com.epages.readiness; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import static org.assertj.core.api.BDDAssertions.then; import static org.mockito.BDDMockito.willReturn; import static org.mockito.Mockito.verify; @ReadinessApplicationTest(activeProfiles = {"test", "cli", "insecure"}, configurations = {ReadinessApplication.class, CommandLineRunnerTest.MockReadinessClientConfiguration.class}) -@RunWith(SpringRunner.class) -public class CommandLineRunnerTest { +@ExtendWith(SpringExtension.class) +class CommandLineRunnerTest { @Autowired(required = false) private CommandLineRunner commandLineRunner; @@ -24,13 +24,13 @@ public class CommandLineRunnerTest { private ReadinessClient mockReadinessClient; @Test - public void should_create_command_line_runner() { + void should_create_command_line_runner() { then(commandLineRunner).isNotNull(); verify(mockReadinessClient).getReadiness(); } @TestConfiguration - public static class MockReadinessClientConfiguration implements InitializingBean { + static class MockReadinessClientConfiguration implements InitializingBean { @MockBean private ReadinessClient mockReadinessClient; diff --git a/src/test/java/com/epages/readiness/HealthClientTest.java b/src/test/java/com/epages/readiness/HealthClientTest.java index 4e3d9ec..95bc2c6 100644 --- a/src/test/java/com/epages/readiness/HealthClientTest.java +++ b/src/test/java/com/epages/readiness/HealthClientTest.java @@ -8,21 +8,22 @@ import java.util.List; import java.util.Map; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import com.epages.readiness.HealthResponse.ChildStatus; @ReadinessApplicationTest -@RunWith(SpringRunner.class) -public class HealthClientTest { +@ExtendWith(SpringExtension.class) +class HealthClientTest { - @Rule + @RegisterExtension @Autowired - public MockRestTemplateRule mockRestTemplateRule; + private MockRestTemplateExtension mockRestTemplateExtension; @Autowired private ReadinessSettings settings; @@ -31,9 +32,9 @@ public class HealthClientTest { private HealthClient healthClient; @Test - public void should_get_health() { + void should_get_health() { // GIVEN - HealthRequest request = settings.getServices().get(0); + HealthRequest request = settings.getServices().getFirst(); // WHEN HealthResponse healthResponse = healthClient.getHealth(request); @@ -43,11 +44,11 @@ public void should_get_health() { } @Test - public void should_get_children_status() { + void should_get_children_status() { // GIVEN HealthResponse healthResponse = HealthResponse.builder() .status(DOWN) - .request(settings.getServices().get(0)) + .request(settings.getServices().getFirst()) .details(Map.of( "foo", Map.of("status", UP), "bar", Map.of("status", UNKNOWN) @@ -65,7 +66,7 @@ public void should_get_children_status() { } @Test - public void should_handle_exception() { + void should_handle_exception() { // GIVEN HealthRequest request = new HealthRequest("exception", "https://host.invalid/EXCEPTION"); diff --git a/src/test/java/com/epages/readiness/HealthResponseTest.java b/src/test/java/com/epages/readiness/HealthResponseTest.java index 6712d7d..8df7c79 100644 --- a/src/test/java/com/epages/readiness/HealthResponseTest.java +++ b/src/test/java/com/epages/readiness/HealthResponseTest.java @@ -1,20 +1,19 @@ package com.epages.readiness; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.boot.actuate.health.Status.UP; -import org.junit.Test; +import org.junit.jupiter.api.Test; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; -public class HealthResponseTest { +class HealthResponseTest { @Test @SneakyThrows - public void should_deserialize_json() { + void should_deserialize_json() { // GIVEN ObjectMapper objectMapper = new ObjectMapper(); //language=JSON @@ -50,7 +49,7 @@ public void should_deserialize_json() { // THEN then(healthResponse.getStatus()).isEqualTo(UP); - then(healthResponse.getChildrenStatus().stream().map(HealthResponse.ChildStatus::getName).collect(toList())).containsOnly("db", "hystrix", "rabbit", "refreshScope"); - then(healthResponse.getChildrenStatus().stream().map(s -> s.getStatus().getCode()).collect(toList())).containsOnly("UP", "UP", "UP", "UP"); + then(healthResponse.getChildrenStatus().stream().map(HealthResponse.ChildStatus::getName).toList()).containsOnly("db", "hystrix", "rabbit", "refreshScope"); + then(healthResponse.getChildrenStatus().stream().map(s -> s.getStatus().getCode()).toList()).containsOnly("UP", "UP", "UP", "UP"); } } diff --git a/src/test/java/com/epages/readiness/MockRestTemplateRule.java b/src/test/java/com/epages/readiness/MockRestTemplateExtension.java similarity index 67% rename from src/test/java/com/epages/readiness/MockRestTemplateRule.java rename to src/test/java/com/epages/readiness/MockRestTemplateExtension.java index d27dba6..64ad90f 100644 --- a/src/test/java/com/epages/readiness/MockRestTemplateRule.java +++ b/src/test/java/com/epages/readiness/MockRestTemplateExtension.java @@ -5,7 +5,8 @@ import java.net.URI; -import org.junit.rules.ExternalResource; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @@ -13,12 +14,13 @@ @Component @RequiredArgsConstructor -public class MockRestTemplateRule extends ExternalResource { +public class MockRestTemplateExtension implements BeforeEachCallback { private final RestTemplate mockRestTemplate; @Override - protected void before() { + public void beforeEach(ExtensionContext context) { willAnswer(new MockRestTemplateAnswer()).given(mockRestTemplate).getForObject(any(URI.class), any()); } + } diff --git a/src/test/java/com/epages/readiness/ReadinessClientTest.java b/src/test/java/com/epages/readiness/ReadinessClientTest.java index 8b215e5..58effe8 100644 --- a/src/test/java/com/epages/readiness/ReadinessClientTest.java +++ b/src/test/java/com/epages/readiness/ReadinessClientTest.java @@ -3,19 +3,19 @@ import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.boot.actuate.health.Status.DOWN; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; @ReadinessApplicationTest -@RunWith(SpringRunner.class) -public class ReadinessClientTest { +@ExtendWith(SpringExtension.class) +class ReadinessClientTest { - @Rule + @RegisterExtension @Autowired - public MockRestTemplateRule mockRestTemplateRule; + private MockRestTemplateExtension mockRestTemplateExtension; @Autowired private ReadinessClient readinessClient; @@ -24,7 +24,7 @@ public class ReadinessClientTest { private ReadinessSettings settings; @Test - public void should_retrieve_health_checks() { + void should_retrieve_health_checks() { // WHEN ReadinessResponse response = readinessClient.getReadiness(); diff --git a/src/test/java/com/epages/readiness/ReadinessControllerTest.java b/src/test/java/com/epages/readiness/ReadinessControllerTest.java index 1b4a71f..4bc78e1 100644 --- a/src/test/java/com/epages/readiness/ReadinessControllerTest.java +++ b/src/test/java/com/epages/readiness/ReadinessControllerTest.java @@ -1,12 +1,12 @@ package com.epages.readiness; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; @@ -23,8 +23,8 @@ @WebMvcTest(ReadinessController.class) @ActiveProfiles({"test", "dashboard"}) -@RunWith(SpringRunner.class) -public class ReadinessControllerTest { +@ExtendWith(SpringExtension.class) +class ReadinessControllerTest { @MockBean private ReadinessClient mockReadinessClient; @@ -34,7 +34,7 @@ public class ReadinessControllerTest { @Test @SneakyThrows - public void should_render_dashboard_using_custom_sorting() { + void should_render_dashboard_using_custom_sorting() { // GIVEN givenReadinessResponse(); @@ -53,7 +53,7 @@ public void should_render_dashboard_using_custom_sorting() { @Test @SneakyThrows - public void should_render_dashboard_using_default_sorting() { + void should_render_dashboard_using_default_sorting() { // GIVEN givenReadinessResponse(); diff --git a/src/test/java/com/epages/readiness/ReadinessResponseTest.java b/src/test/java/com/epages/readiness/ReadinessResponseTest.java index 9e17dc0..8431a53 100644 --- a/src/test/java/com/epages/readiness/ReadinessResponseTest.java +++ b/src/test/java/com/epages/readiness/ReadinessResponseTest.java @@ -6,25 +6,24 @@ import static org.springframework.boot.actuate.health.Status.UNKNOWN; import static org.springframework.boot.actuate.health.Status.UP; -import java.util.List; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.health.SimpleStatusAggregator; import org.springframework.boot.actuate.health.Status; -public class ReadinessResponseTest { +class ReadinessResponseTest { private SimpleStatusAggregator healthAggregator; - @Before - public void setup() { + @BeforeEach + void setup() { healthAggregator = new SimpleStatusAggregator( DOWN, OUT_OF_SERVICE, UNKNOWN, new Status("DEGRADED"), UP ); } @Test - public void should_handle_degraded() { + void should_handle_degraded() { // GIVEN HealthResponse up = HealthResponse.builder() .request(new HealthRequest("A", "http://a")) diff --git a/src/test/java/com/epages/readiness/sort/SortCompareTest.java b/src/test/java/com/epages/readiness/sort/SortCompareTest.java index 0102e02..3c632ea 100644 --- a/src/test/java/com/epages/readiness/sort/SortCompareTest.java +++ b/src/test/java/com/epages/readiness/sort/SortCompareTest.java @@ -3,8 +3,8 @@ import com.epages.readiness.HealthRequest; import com.epages.readiness.HealthResponse; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; @@ -19,17 +19,17 @@ import static org.springframework.data.domain.Sort.Direction.ASC; import static org.springframework.data.domain.Sort.Direction.DESC; -public class SortCompareTest { +class SortCompareTest { private SortCompare sortCompare; - @Before - public void setup() { + @BeforeEach + void setup() { sortCompare = new SortConfiguration().sortCompare(); } @Test - public void should_sort_health_responses() { + void should_sort_health_responses() { // GIVEN Sort sort = Sort.by( new Order(ASC, "status"), new Order(DESC, "totalTimeMillis"), new Order(ASC, "service")