Skip to content

Commit

Permalink
Allow disabling the under the hood use of JerseyClient with Eureka Cl…
Browse files Browse the repository at this point in the history
…ient. Fixes gh-4185.
  • Loading branch information
OlgaMaciaszek committed Jul 8, 2024
1 parent aa0670b commit b23c587
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 37 deletions.
2 changes: 2 additions & 0 deletions docs/modules/ROOT/pages/spring-cloud-netflix.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ The following example shows the dependencies you need to add:
</dependencies>
----

If you have `JerseyClient` on the classpath but do not wish to use it in your `EuerekaClient`, make sure to set `eureka.client.jersey.enabled` to `false`.

=== Alternatives to the Native Netflix EurekaClient

You need not use the raw Netflix `EurekaClient`.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018-2022 the original author or authors.
* Copyright 2018-2024 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.
Expand Down Expand Up @@ -33,9 +33,9 @@

import static org.assertj.core.api.Assertions.assertThat;

abstract class BaseCertTest {
abstract class BaseCertTests {

private static final Log log = LogFactory.getLog(BaseCertTest.class);
private static final Log log = LogFactory.getLog(BaseCertTests.class);

protected static final String KEY_STORE_PASSWORD = "test-key-store-password";

Expand All @@ -53,7 +53,7 @@ abstract class BaseCertTest {

protected static File wrongClientCert;

protected BaseCertTest() {
protected BaseCertTests() {
}

@SuppressWarnings("rawtypes")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018-2022 the original author or authors.
* Copyright 2018-2024 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.
Expand Down Expand Up @@ -27,7 +27,7 @@
* already shutdown.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({ EurekaClientTest.class, RestTemplateEurekaClientTest.class })
@Suite.SuiteClasses({ EurekaClientTests.class, RestTemplateEurekaClientTests.class })
public class EurekaClientSuite {

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018-2022 the original author or authors.
* Copyright 2018-2024 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.
Expand Down Expand Up @@ -27,21 +27,21 @@

import static org.assertj.core.api.Assertions.assertThat;

public class EurekaClientTest extends BaseCertTest {
public class EurekaClientTests extends BaseCertTests {

private static final Log log = LogFactory.getLog(EurekaClientTest.class);
private static final Log log = LogFactory.getLog(EurekaClientTests.class);

static EurekaServerRunner server;

static EurekaClientRunner service;

@BeforeAll
public static void setupAll() {
server = startEurekaServer(EurekaClientTest.TestEurekaServer.class);
service = startService(server, EurekaClientTest.TestApp.class);
server = startEurekaServer(EurekaClientTests.TestEurekaServer.class);
service = startService(server, EurekaClientTests.TestApp.class);
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
log.info("Successfully asserted that Jersey will be used");
waitForRegistration(() -> new EurekaClientTest().createEurekaClient());
waitForRegistration(() -> new EurekaClientTests().createEurekaClient());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018-2022 the original author or authors.
* Copyright 2018-2024 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.
Expand Down Expand Up @@ -38,22 +38,22 @@

import static org.assertj.core.api.Assertions.assertThat;

public class RestTemplateEurekaClientTest extends BaseCertTest {
public class RestTemplateEurekaClientTests extends BaseCertTests {

private static final Log log = LogFactory.getLog(RestTemplateEurekaClientTest.class);
private static final Log log = LogFactory.getLog(RestTemplateEurekaClientTests.class);

private static EurekaServerRunner server;

private static EurekaClientRunner service;

@BeforeAll
public static void setupAll() {
server = startEurekaServer(RestTemplateEurekaClientTest.RestTemplateTestEurekaServer.class);
service = startService(server, RestTemplateEurekaClientTest.RestTemplateTestApp.class);
server = startEurekaServer(RestTemplateEurekaClientTests.RestTemplateTestEurekaServer.class);
service = startService(server, RestTemplateEurekaClientTests.RestTemplateTestApp.class);
// Will use RestTemplate
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
log.info("Successfully asserted that RestTemplate will be used");
waitForRegistration(() -> new RestTemplateEurekaClientTest().createEurekaClient());
waitForRegistration(() -> new RestTemplateEurekaClientTests().createEurekaClient());
}

@AfterAll
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
Expand All @@ -45,12 +47,14 @@
import org.springframework.cloud.netflix.eureka.http.WebClientDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.WebClientTransportClientFactories;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

/**
* @author Daniel Lavoie
* @author Armin Krezovic
* @author Olga Maciaszek-Sharma
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(RestTemplateTimeoutProperties.class)
Expand All @@ -66,7 +70,7 @@ public TlsProperties tlsProperties() {

@Bean
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
@ConditionalOnMissingClass("org.glassfish.jersey.client.JerseyClient")
@Conditional(JerseyClientNotPresentOrNotEnabledCondition.class)
@ConditionalOnMissingBean(value = { AbstractDiscoveryClientOptionalArgs.class }, search = SearchStrategy.CURRENT)
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
havingValue = "false")
Expand All @@ -82,7 +86,7 @@ public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOption

@Bean
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
@ConditionalOnMissingClass("org.glassfish.jersey.client.JerseyClient")
@Conditional(JerseyClientNotPresentOrNotEnabledCondition.class)
@ConditionalOnMissingBean(value = { TransportClientFactories.class }, search = SearchStrategy.CURRENT)
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
havingValue = "false")
Expand All @@ -108,7 +112,7 @@ private static void setupTLS(AbstractDiscoveryClientOptionalArgs<?> args, TlsPro
}

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(name = "org.glassfish.jersey.client.JerseyClient")
@Conditional(JerseyClientPresentAndEnabledCondition.class)
@ConditionalOnBean(value = AbstractDiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT)
static class DiscoveryClientOptionalArgsTlsConfiguration {

Expand All @@ -120,7 +124,7 @@ static class DiscoveryClientOptionalArgsTlsConfiguration {

}

@ConditionalOnMissingClass("org.glassfish.jersey.client.JerseyClient")
@Conditional(JerseyClientNotPresentOrNotEnabledCondition.class)
@ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient")
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", havingValue = "true")
protected static class WebClientConfiguration {
Expand Down Expand Up @@ -151,8 +155,8 @@ public WebClientTransportClientFactories webClientTransportClientFactories(
}

@Configuration
@ConditionalOnMissingClass({ "org.glassfish.jersey.client.JerseyClient",
"org.springframework.web.reactive.function.client.WebClient" })
@Conditional(JerseyClientNotPresentOrNotEnabledCondition.class)
@ConditionalOnMissingClass("org.springframework.web.reactive.function.client.WebClient")
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", havingValue = "true")
protected static class WebClientNotFoundConfiguration {

Expand All @@ -164,4 +168,40 @@ public WebClientNotFoundConfiguration() {

}

static class JerseyClientPresentAndEnabledCondition extends AllNestedConditions {

JerseyClientPresentAndEnabledCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}

@ConditionalOnClass(name = "org.glassfish.jersey.client.JerseyClient")
static class OnJerseyClientPresent {

}

@ConditionalOnProperty(value = "eureka.client.jersey.enabled", matchIfMissing = true)
static class OnJerseyClientEnabled {

}

}

static class JerseyClientNotPresentOrNotEnabledCondition extends AnyNestedCondition {

JerseyClientNotPresentOrNotEnabledCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}

@ConditionalOnMissingClass("org.glassfish.jersey.client.JerseyClient")
static class OnJerseyClientMissing {

}

@ConditionalOnProperty(value = "eureka.client.jersey.enabled", havingValue = "false")
static class OnJerseyClientDisabled {

}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,10 @@ class ErrorHandler extends DefaultResponseErrorHandler {
@Override
protected boolean hasError(HttpStatusCode statusCode) {
/**
* When the Eureka server restarts and a client tries to sent a heartbeat the
* server will respond with a 404. By default RestTemplate will throw an
* When the Eureka server restarts and a client tries to send a heartbeat the
* server will respond with a 404. By default, RestTemplate will throw an
* exception in this case. What we want is to return the 404 to the upstream
* code so it will send another registration request to the server.
* code, so it will send another registration request to the server.
*/
if (statusCode.is4xxClientError()) {
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2013-2023 the original author or authors.
* Copyright 2013-2024 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.
Expand Down Expand Up @@ -59,7 +59,7 @@
* @author Ryan Baxter
*/
@Testcontainers
public class EurekaConfigServerBootstrapperIT {
public class EurekaConfigServerBootstrapperIntegrationTests {

public static final DockerImageName MOCKSERVER_IMAGE = DockerImageName.parse("mockserver/mockserver")
.withTag("mockserver-" + MockServerClient.class.getPackage().getImplementationVersion());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 the original author or authors.
* Copyright 2017-2024 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.
Expand Down Expand Up @@ -37,7 +37,7 @@
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "jersey-client-*", "jersey-core-*", "jersey-apache-client4-*", "spring-webflux-*" })
@SpringBootTest(classes = EurekaSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class EurekaHttpClientsOptionalArgsConfigurationNoWebfluxTest {
public class EurekaHttpClientsOptionalArgsConfigurationNoWebFluxTests {

@Test
public void contextFailsWithoutWebClient() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 the original author or authors.
* Copyright 2017-2024 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.
Expand Down Expand Up @@ -36,7 +36,7 @@
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "jersey-client-*", "jersey-core-*", "jersey-apache-client4-*" })
@SpringBootTest(classes = EurekaSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class EurekaHttpClientsOptionalArgsConfigurationTest {
public class EurekaHttpClientsOptionalArgsConfigurationTests {

@Test
public void contextLoadsWithRestTemplate() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2017-2024 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
*
* https://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.cloud.netflix.eureka.config;

import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
import org.junit.jupiter.api.Test;

import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Tests for Jersey client setup in DiscoveryClientOptionalArgsConfiguration.
*
* @author Olga Maciaszek-Sharma
*/
public class JerseyClientOptionalArgsConfigurationTests {

@SuppressWarnings("OptionalGetWithoutIsPresent")
@Test
void shouldCreateRestTemplateDiscoveryClientOptionalArgsWhenJerseyClientDisabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DiscoveryClientOptionalArgsConfiguration.class))
.withPropertyValues("eureka.client.jersey.enabled=false").run(context -> {
assertThat(context).hasSingleBean(AbstractDiscoveryClientOptionalArgs.class);
assertThat(context.getBeansOfType(AbstractDiscoveryClientOptionalArgs.class).values().stream()
.findFirst().get()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
assertThat(context).hasSingleBean(RestTemplateDiscoveryClientOptionalArgs.class);
});
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 the original author or authors.
* Copyright 2017-2024 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.
Expand Down Expand Up @@ -32,7 +32,7 @@
*/
@DirtiesContext
@SpringBootTest(classes = EurekaSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
class JerseyOptionalArgsConfigurationTest {
class JerseyOptionalArgsConfigurationApplicationTests {

@Autowired
private AbstractDiscoveryClientOptionalArgs optionalArgs;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 the original author or authors.
* Copyright 2017-2024 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.
Expand All @@ -24,7 +24,7 @@
/**
* @author Daniel Lavoie
*/
class RestTemplateTransportClientFactoryTest {
class RestTemplateTransportClientFactoryTests {

private RestTemplateTransportClientFactory transportClientFatory;

Expand Down

0 comments on commit b23c587

Please sign in to comment.