Skip to content

Commit

Permalink
Introduce skipForcedClientInitialization property.
Browse files Browse the repository at this point in the history
Fixes gh-4152
  • Loading branch information
Robert Bleyl committed May 2, 2023
1 parent ccb0f5c commit 870aaba
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}

Expand All @@ -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
Expand All @@ -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=")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.logging.LogFactory;

import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;

import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UNKNOWN;

Expand All @@ -33,6 +34,12 @@ public class EurekaServiceRegistry implements ServiceRegistry<EurekaRegistration

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

private final EurekaInstanceConfigBean eurekaInstanceConfigBean;

public EurekaServiceRegistry(EurekaInstanceConfigBean eurekaInstanceConfigBean) {
this.eurekaInstanceConfigBean = eurekaInstanceConfigBean;
}

@Override
public void register(EurekaRegistration reg) {
maybeInitializeClient(reg);
Expand All @@ -51,7 +58,10 @@ public void register(EurekaRegistration reg) {
private void maybeInitializeClient(EurekaRegistration reg) {
// force initialization of possibly scoped proxies
reg.getApplicationInfoManager().getInfo();
reg.getEurekaClient().getApplications();

if (!eurekaInstanceConfigBean.isSkipForcedClientInitialization()) {
reg.getEurekaClient().getApplications();
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.InstanceInfo;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;
import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
Expand All @@ -34,18 +38,23 @@
import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UNKNOWN;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

/**
* @author Spencer Gibb
* @author Tim Ysewyn
*/
@ExtendWith(MockitoExtension.class)
class EurekaServiceRegistryTests {

@Mock
private EurekaInstanceConfigBean eurekaInstanceConfigBean;

@Test
void eurekaClientNotShutdownInDeregister() {
EurekaServiceRegistry registry = new EurekaServiceRegistry();
EurekaServiceRegistry registry = new EurekaServiceRegistry(eurekaInstanceConfigBean);

CloudEurekaClient eurekaClient = mock(CloudEurekaClient.class);
ApplicationInfoManager applicationInfoManager = mock(ApplicationInfoManager.class);
Expand All @@ -65,7 +74,7 @@ void eurekaClientNotShutdownInDeregister() {
@SuppressWarnings("unchecked")
@Test
void eurekaClientGetStatus() {
EurekaServiceRegistry registry = new EurekaServiceRegistry();
EurekaServiceRegistry registry = new EurekaServiceRegistry(eurekaInstanceConfigBean);

EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(new InetUtils(new InetUtilsProperties()));
config.setAppname("myapp");
Expand Down Expand Up @@ -102,16 +111,14 @@ void eurekaClientGetStatus() {
@SuppressWarnings("unchecked")
@Test
void eurekaClientGetStatusNoInstance() {
EurekaServiceRegistry registry = new EurekaServiceRegistry();
EurekaServiceRegistry registry = new EurekaServiceRegistry(eurekaInstanceConfigBean);

EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(new InetUtils(new InetUtilsProperties()));
config.setAppname("myapp");
config.setInstanceId("1234");

CloudEurekaClient eurekaClient = mock(CloudEurekaClient.class);

when(eurekaClient.getInstanceInfo("myapp", "1234")).thenReturn(null);

ApplicationInfoManager applicationInfoManager = mock(ApplicationInfoManager.class);
when(applicationInfoManager.getInfo()).thenReturn(mock(InstanceInfo.class));

Expand All @@ -130,4 +137,43 @@ void eurekaClientGetStatusNoInstance() {
assertThat(map).hasSize(1).containsEntry("status", UNKNOWN.toString());
}

@Test
void eurekaClientDoesNotForceInitialization() {
when(eurekaInstanceConfigBean.isSkipForcedClientInitialization()).thenReturn(true);
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);

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();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,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;
Expand Down Expand Up @@ -198,8 +199,12 @@ public Jersey3EurekaServerHttpClientFactory jersey3EurekaServerHttpClientFactory

@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(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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();
}
}

0 comments on commit 870aaba

Please sign in to comment.