diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java index 29776c7b91..ed06189099 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java @@ -224,8 +224,8 @@ private void setupJmxPort(EurekaInstanceConfigBean instance, Integer jmxPort) { } @Bean - public EurekaServiceRegistry eurekaServiceRegistry() { - return new EurekaServiceRegistry(); + public EurekaServiceRegistry eurekaServiceRegistry(EurekaInstanceConfigBean eurekaInstanceConfigBean) { + return new EurekaServiceRegistry(eurekaInstanceConfigBean); } // @Bean diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java index 430f53cc36..94278023d1 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java @@ -269,6 +269,12 @@ public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, Envi */ private boolean preferIpAddress = false; + /** + * If true the EurekaClient will not be forced to initialize when the InstanceRegistry + * bean is created. + */ + private boolean skipForcedClientInitialization; + /** * Initial status to register with remote Eureka server. */ @@ -547,6 +553,14 @@ public void setPreferIpAddress(boolean preferIpAddress) { this.preferIpAddress = preferIpAddress; } + public boolean isSkipForcedClientInitialization() { + return skipForcedClientInitialization; + } + + public void setSkipForcedClientInitialization(boolean skipForcedClientInitialization) { + this.skipForcedClientInitialization = skipForcedClientInitialization; + } + public InstanceStatus getInitialStatus() { return initialStatus; } @@ -597,6 +611,7 @@ public boolean equals(Object o) { && Objects.equals(namespace, that.namespace) && Objects.equals(hostname, that.hostname) && preferIpAddress == that.preferIpAddress && Objects.equals(initialStatus, that.initialStatus) && Arrays.equals(defaultAddressResolutionOrder, that.defaultAddressResolutionOrder) + && skipForcedClientInitialization == that.skipForcedClientInitialization && Objects.equals(environment, that.environment); } @@ -607,7 +622,8 @@ public int hashCode() { leaseExpirationDurationInSeconds, virtualHostName, instanceId, secureVirtualHostName, aSGName, metadataMap, dataCenterInfo, ipAddress, statusPageUrlPath, statusPageUrl, homePageUrlPath, homePageUrl, healthCheckUrlPath, healthCheckUrl, secureHealthCheckUrl, namespace, hostname, preferIpAddress, - initialStatus, Arrays.hashCode(defaultAddressResolutionOrder), environment); + skipForcedClientInitialization, initialStatus, Arrays.hashCode(defaultAddressResolutionOrder), + environment); } @Override @@ -631,6 +647,7 @@ public String toString() { .append("', ").append("healthCheckUrl='").append(healthCheckUrl).append("', ") .append("secureHealthCheckUrl='").append(secureHealthCheckUrl).append("', ").append("namespace='") .append(namespace).append("', ").append("hostname='").append(hostname).append("', ") + .append("skipForcedClientInitialization=").append(skipForcedClientInitialization).append(", ") .append("preferIpAddress=").append(preferIpAddress).append(", ").append("initialStatus=") .append(initialStatus).append(", ").append("defaultAddressResolutionOrder=") .append(Arrays.toString(defaultAddressResolutionOrder)).append(", ").append("environment=") diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaServiceRegistry.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaServiceRegistry.java index cc15667f44..7412418fd0 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaServiceRegistry.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaServiceRegistry.java @@ -23,6 +23,8 @@ import org.apache.commons.logging.LogFactory; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.cloud.netflix.eureka.CloudEurekaClient; +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UNKNOWN; @@ -33,6 +35,12 @@ public class EurekaServiceRegistry implements ServiceRegistry(null)).build(); + + registry.register(registration); + + verifyNoInteractions(eurekaClient); + } + + @Test + void eurekaClientDoesForceInitialization() { + EurekaServiceRegistry registry = new EurekaServiceRegistry(eurekaInstanceConfigBean); + + CloudEurekaClient eurekaClient = mock(CloudEurekaClient.class); + ApplicationInfoManager applicationInfoManager = mock(ApplicationInfoManager.class); + + when(applicationInfoManager.getInfo()).thenReturn(mock(InstanceInfo.class)); + + EurekaRegistration registration = EurekaRegistration + .builder(new EurekaInstanceConfigBean(new InetUtils(new InetUtilsProperties()))).with(eurekaClient) + .with(applicationInfoManager).with(new EurekaClientConfigBean(), mock(ApplicationEventPublisher.class)) + .with(new SimpleObjectProvider<>(null)).build(); + + registry.register(registration); + + verify(eurekaClient).getApplications(); + } + } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java index ec8f135dbe..8278004719 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java @@ -88,6 +88,7 @@ import org.springframework.cloud.client.actuator.HasFeatures; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.cloud.netflix.eureka.EurekaConstants; +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; @@ -207,8 +208,12 @@ public Jersey3DiscoveryClientOptionalArgs jersey3DiscoveryClientOptionalArgs() { @Bean public PeerAwareInstanceRegistry peerAwareInstanceRegistry(ServerCodecs serverCodecs, - EurekaServerHttpClientFactory eurekaServerHttpClientFactory) { - this.eurekaClient.getApplications(); // force initialization + EurekaServerHttpClientFactory eurekaServerHttpClientFactory, + EurekaInstanceConfigBean eurekaInstanceConfigBean) { + if (!eurekaInstanceConfigBean.isSkipForcedClientInitialization()) { + this.eurekaClient.getApplications(); // force initialization + } + return new InstanceRegistry(this.eurekaServerConfig, this.eurekaClientConfig, serverCodecs, this.eurekaClient, eurekaServerHttpClientFactory, this.instanceRegistryProperties.getExpectedNumberOfClientsSendingRenews(), diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfigurationTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfigurationTests.java new file mode 100644 index 0000000000..3bf3bf2fde --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfigurationTests.java @@ -0,0 +1,87 @@ +/* + * Copyright 2013-2022 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.server; + +import com.netflix.discovery.EurekaClient; +import com.netflix.discovery.EurekaClientConfig; +import com.netflix.eureka.EurekaServerConfig; +import com.netflix.eureka.resources.ServerCodecs; +import com.netflix.eureka.transport.EurekaServerHttpClientFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class EurekaServerAutoConfigurationTests { + + @Mock + private EurekaServerConfig eurekaServerConfig; + + @Mock + private EurekaClientConfig eurekaClientConfig; + + @Mock + private EurekaClient eurekaClient; + + @Mock + private InstanceRegistryProperties instanceRegistryProperties; + + @Mock + private ServerCodecs serverCodecs; + + @Mock + private EurekaServerHttpClientFactory eurekaServerHttpClientFactory; + + @Mock + private EurekaInstanceConfigBean eurekaInstanceConfigBean; + + @InjectMocks + private EurekaServerAutoConfiguration eurekaServerAutoConfiguration; + + @BeforeEach + void setup() { + when(eurekaServerConfig.getDeltaRetentionTimerIntervalInMs()).thenReturn(1L); + } + + @Test + void shouldForceEurekaClientInit() { + eurekaServerAutoConfiguration.peerAwareInstanceRegistry(serverCodecs, eurekaServerHttpClientFactory, + eurekaInstanceConfigBean); + + verify(eurekaClient).getApplications(); + } + + @Test + void shouldNotForceEurekaClientInit() { + when(eurekaInstanceConfigBean.isSkipForcedClientInitialization()).thenReturn(true); + + eurekaServerAutoConfiguration.peerAwareInstanceRegistry(serverCodecs, eurekaServerHttpClientFactory, + eurekaInstanceConfigBean); + + verify(eurekaClient, never()).getApplications(); + } + +}