diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 406ef0e12..fa99ce0e8 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -2021,6 +2021,8 @@ info: url: https://github.com/spring-cloud-samples ---- +To enable the health check request to accept all certificates when using HTTPs set `sidecar.accept-all-ssl-certificates` to `true. + [[retrying-failed-requests]] == Retrying Failed Requests diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java index 19e1d1f13..6646b7871 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java @@ -16,22 +16,26 @@ package org.springframework.cloud.netflix.sidecar; -import java.net.URI; -import java.util.Map; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; import org.springframework.web.client.RestTemplate; +import java.net.URI; +import java.util.Map; + /** * @author Spencer Gibb + * @author Fabrizio Di Napoli */ public class LocalApplicationHealthIndicator extends AbstractHealthIndicator { @Autowired private SidecarProperties properties; + @Autowired + private RestTemplate restTemplate; + @SuppressWarnings("unchecked") @Override protected void doHealthCheck(Health.Builder builder) throws Exception { @@ -40,12 +44,13 @@ public class LocalApplicationHealthIndicator extends AbstractHealthIndicator { builder.up(); return; } - Map map = new RestTemplate().getForObject(uri, Map.class); + + Map map = restTemplate.getForObject(uri, Map.class); Object status = map.get("status"); - if (status != null && status instanceof String) { + if (status instanceof String) { builder.status(status.toString()); } - else if (status != null && status instanceof Map) { + else if (status instanceof Map) { Map statusMap = (Map) status; Object code = statusMap.get("code"); if (code != null) { @@ -63,5 +68,4 @@ public class LocalApplicationHealthIndicator extends AbstractHealthIndicator { private Health.Builder getWarning(Health.Builder builder) { return builder.unknown().withDetail("warning", "no status field in response"); } - } diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java index 096d0cc09..b4015881b 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java @@ -16,6 +16,11 @@ package org.springframework.cloud.netflix.sidecar; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceId; import org.springframework.beans.factory.annotation.Autowired; @@ -33,10 +38,12 @@ import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvi import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.util.StringUtils; import com.netflix.appinfo.HealthCheckHandler; import com.netflix.discovery.EurekaClientConfig; +import org.springframework.web.client.RestTemplate; import java.util.Map; @@ -54,6 +61,7 @@ import java.util.Map; * * @author Spencer Gibb * @author Ryan Baxter + * @author Fabrizio Di Napoli * * @see EurekaInstanceConfigBeanConfiguration */ @@ -153,7 +161,25 @@ public class SidecarConfiguration { final LocalApplicationHealthIndicator healthIndicator) { return new LocalApplicationHealthCheckHandler(healthIndicator); } + } + @Bean + @ConditionalOnMissingClass("org.apache.http.client.HttpClient") + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + @Bean + @ConditionalOnClass(HttpClient.class) + @ConditionalOnProperty(value = "sidecar.accept-all-ssl-certificates") + public RestTemplate sslRestTemplate() { + CloseableHttpClient httpClient = HttpClients.custom() + .setSSLHostnameVerifier(new NoopHostnameVerifier()) + .build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); + requestFactory.setHttpClient(httpClient); + + return new RestTemplate(requestFactory); } @Bean diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java index 4f8aa8e55..1104be691 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java @@ -27,6 +27,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; /** * @author Spencer Gibb * @author Gregor Zurowski + * @author Fabrizio Di Napoli */ @ConfigurationProperties("sidecar") public class SidecarProperties { @@ -43,6 +44,8 @@ public class SidecarProperties { private String ipAddress; + private boolean acceptAllSslCertificates; + public URI getHealthUri() { return healthUri; } @@ -83,6 +86,14 @@ public class SidecarProperties { this.ipAddress = ipAddress; } + public boolean acceptAllSslCertificates() { + return acceptAllSslCertificates; + } + + public void setAcceptAllSslCertificates(boolean acceptAllSslCertificates) { + this.acceptAllSslCertificates = acceptAllSslCertificates; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -92,12 +103,13 @@ public class SidecarProperties { Objects.equals(homePageUri, that.homePageUri) && port == that.port && Objects.equals(hostname, that.hostname) && - Objects.equals(ipAddress, that.ipAddress); + Objects.equals(ipAddress, that.ipAddress) && + Objects.equals(acceptAllSslCertificates, that.acceptAllSslCertificates); } @Override public int hashCode() { - return Objects.hash(healthUri, homePageUri, port, hostname, ipAddress); + return Objects.hash(healthUri, homePageUri, port, hostname, ipAddress, acceptAllSslCertificates); } @Override @@ -107,7 +119,8 @@ public class SidecarProperties { .append("homePageUri=").append(homePageUri).append(", ") .append("port=").append(port).append(", ") .append("hostname='").append(hostname).append("', ") - .append("ipAddress='").append(ipAddress).append("'}") + .append("ipAddress='").append(ipAddress).append("', ") + .append("acceptAllSslCertificates='").append(acceptAllSslCertificates).append("'}") .toString(); } diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java index 2d8da11a7..5401f635f 100644 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java +++ b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.netflix.sidecar; +import static org.junit.Assert.assertNull; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +27,7 @@ import org.springframework.test.context.junit4.SpringRunner; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; +import org.springframework.web.client.RestTemplate; public class SidecarApplicationTests { @@ -128,4 +130,16 @@ public class SidecarApplicationTests { assertThat(this.config.getHealthCheckUrl(), equalTo("http://mhhost2:0/foo/health")); } } + + @RunWith(SpringRunner.class) + @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, value = {"sidecar.accept-all-ssl-certificates=false"}) + public static class AcceptAllSslCertificatesContext { + @Autowired + RestTemplate restTemplate; + + @Test + public void testUseRestTemplateWhenHttpClientIsNotAvailable() { + assertNull(restTemplate.getRequestFactory()); + } + } } diff --git a/spring-cloud-netflix-sidecar/src/test/resources/application.yml b/spring-cloud-netflix-sidecar/src/test/resources/application.yml index d6dac53b5..5a78e0959 100644 --- a/spring-cloud-netflix-sidecar/src/test/resources/application.yml +++ b/spring-cloud-netflix-sidecar/src/test/resources/application.yml @@ -7,6 +7,7 @@ spring: sidecar: port: 8000 health-uri: http://localhost:8000/src/test/resources/health.json + accept-all-ssl-certificates: true eureka: instance: