/eureka-client/src/test/java/com/netflix/discovery/EurekaClientLifecycleTest.java

https://github.com/YunaiV/eureka · Java · 187 lines · 155 code · 29 blank · 3 comment · 2 complexity · 71e05daed4268a24327d7c4e03660e45 MD5 · raw file

  1. package com.netflix.discovery;
  2. import javax.ws.rs.core.MediaType;
  3. import java.io.IOException;
  4. import java.util.Collections;
  5. import java.util.List;
  6. import com.google.inject.AbstractModule;
  7. import com.google.inject.Injector;
  8. import com.google.inject.Scopes;
  9. import com.netflix.appinfo.EurekaInstanceConfig;
  10. import com.netflix.appinfo.InstanceInfo;
  11. import com.netflix.appinfo.PropertiesInstanceConfig;
  12. import com.netflix.discovery.shared.Application;
  13. import com.netflix.discovery.shared.Applications;
  14. import com.netflix.discovery.shared.transport.EurekaHttpClient;
  15. import com.netflix.discovery.shared.transport.EurekaHttpResponse;
  16. import com.netflix.discovery.shared.transport.SimpleEurekaHttpServer;
  17. import com.netflix.discovery.shared.transport.jersey.Jersey1DiscoveryClientOptionalArgs;
  18. import com.netflix.discovery.util.InstanceInfoGenerator;
  19. import com.netflix.governator.guice.LifecycleInjector;
  20. import com.netflix.governator.lifecycle.LifecycleManager;
  21. import org.junit.AfterClass;
  22. import org.junit.BeforeClass;
  23. import org.junit.Test;
  24. import static com.netflix.discovery.shared.transport.EurekaHttpResponse.anEurekaHttpResponse;
  25. import static com.netflix.discovery.util.EurekaEntityFunctions.countInstances;
  26. import static java.util.Collections.singletonList;
  27. import static org.hamcrest.CoreMatchers.equalTo;
  28. import static org.hamcrest.CoreMatchers.is;
  29. import static org.junit.Assert.assertThat;
  30. import static org.mockito.Matchers.any;
  31. import static org.mockito.Mockito.atLeast;
  32. import static org.mockito.Mockito.mock;
  33. import static org.mockito.Mockito.timeout;
  34. import static org.mockito.Mockito.times;
  35. import static org.mockito.Mockito.verify;
  36. import static org.mockito.Mockito.when;
  37. public class EurekaClientLifecycleTest {
  38. private static final String MY_APPLICATION_NAME = "MYAPPLICATION";
  39. private static final String MY_INSTANCE_ID = "myInstanceId";
  40. private static final Applications APPLICATIONS = InstanceInfoGenerator.newBuilder(1, 1).build().toApplications();
  41. private static final Applications APPLICATIONS_DELTA = new Applications(APPLICATIONS.getAppsHashCode(), 1L, Collections.<Application>emptyList());
  42. public static final int TIMEOUT_MS = 2 * 1000;
  43. public static final EurekaHttpClient requestHandler = mock(EurekaHttpClient.class);
  44. public static SimpleEurekaHttpServer eurekaHttpServer;
  45. @BeforeClass
  46. public static void setupClass() throws IOException {
  47. eurekaHttpServer = new SimpleEurekaHttpServer(requestHandler);
  48. when(requestHandler.register(any(InstanceInfo.class))).thenReturn(EurekaHttpResponse.status(204));
  49. when(requestHandler.cancel(MY_APPLICATION_NAME, MY_INSTANCE_ID)).thenReturn(EurekaHttpResponse.status(200));
  50. when(requestHandler.sendHeartBeat(MY_APPLICATION_NAME, MY_INSTANCE_ID, null, null)).thenReturn(
  51. anEurekaHttpResponse(200, InstanceInfo.class).build()
  52. );
  53. when(requestHandler.getApplications()).thenReturn(
  54. anEurekaHttpResponse(200, APPLICATIONS).type(MediaType.APPLICATION_JSON_TYPE).build()
  55. );
  56. when(requestHandler.getDelta()).thenReturn(
  57. anEurekaHttpResponse(200, APPLICATIONS_DELTA).type(MediaType.APPLICATION_JSON_TYPE).build()
  58. );
  59. }
  60. @AfterClass
  61. public static void tearDownClass() {
  62. if (eurekaHttpServer != null) {
  63. eurekaHttpServer.shutdown();
  64. }
  65. }
  66. @Test
  67. public void testEurekaClientLifecycle() throws Exception {
  68. Injector injector = LifecycleInjector.builder()
  69. .withModules(
  70. new AbstractModule() {
  71. @Override
  72. protected void configure() {
  73. bind(EurekaInstanceConfig.class).to(LocalEurekaInstanceConfig.class);
  74. bind(EurekaClientConfig.class).to(LocalEurekaClientConfig.class);
  75. bind(AbstractDiscoveryClientOptionalArgs.class).to(Jersey1DiscoveryClientOptionalArgs.class).in(Scopes.SINGLETON);
  76. }
  77. }
  78. )
  79. .build().createInjector();
  80. LifecycleManager lifecycleManager = injector.getInstance(LifecycleManager.class);
  81. lifecycleManager.start();
  82. EurekaClient client = injector.getInstance(EurekaClient.class);
  83. // Check registration
  84. verify(requestHandler, timeout(TIMEOUT_MS).atLeast(1)).register(any(InstanceInfo.class));
  85. // Check registry fetch
  86. verify(requestHandler, timeout(TIMEOUT_MS).times(1)).getApplications();
  87. verify(requestHandler, timeout(TIMEOUT_MS).atLeast(1)).getDelta();
  88. assertThat(countInstances(client.getApplications()), is(equalTo(1)));
  89. // Shutdown container, and check that unregister happens
  90. lifecycleManager.close();
  91. verify(requestHandler, times(1)).cancel(MY_APPLICATION_NAME, MY_INSTANCE_ID);
  92. }
  93. @Test
  94. public void testBackupRegistryInjection() throws Exception {
  95. final BackupRegistry backupRegistry = mock(BackupRegistry.class);
  96. when(backupRegistry.fetchRegistry()).thenReturn(APPLICATIONS);
  97. Injector injector = LifecycleInjector.builder()
  98. .withModules(
  99. new AbstractModule() {
  100. @Override
  101. protected void configure() {
  102. bind(EurekaInstanceConfig.class).to(LocalEurekaInstanceConfig.class);
  103. bind(EurekaClientConfig.class).to(BadServerEurekaClientConfig.class);
  104. bind(BackupRegistry.class).toInstance(backupRegistry);
  105. bind(AbstractDiscoveryClientOptionalArgs.class).to(Jersey1DiscoveryClientOptionalArgs.class).in(Scopes.SINGLETON);
  106. }
  107. }
  108. )
  109. .build().createInjector();
  110. LifecycleManager lifecycleManager = injector.getInstance(LifecycleManager.class);
  111. lifecycleManager.start();
  112. EurekaClient client = injector.getInstance(EurekaClient.class);
  113. verify(backupRegistry, atLeast(1)).fetchRegistry();
  114. assertThat(countInstances(client.getApplications()), is(equalTo(1)));
  115. }
  116. private static class LocalEurekaInstanceConfig extends PropertiesInstanceConfig {
  117. @Override
  118. public String getInstanceId() {
  119. return MY_INSTANCE_ID;
  120. }
  121. @Override
  122. public String getAppname() {
  123. return MY_APPLICATION_NAME;
  124. }
  125. @Override
  126. public int getLeaseRenewalIntervalInSeconds() {
  127. return 1;
  128. }
  129. }
  130. private static class LocalEurekaClientConfig extends DefaultEurekaClientConfig {
  131. @Override
  132. public List<String> getEurekaServerServiceUrls(String myZone) {
  133. return singletonList(eurekaHttpServer.getServiceURI().toString());
  134. }
  135. @Override
  136. public int getInitialInstanceInfoReplicationIntervalSeconds() {
  137. return 0;
  138. }
  139. @Override
  140. public int getInstanceInfoReplicationIntervalSeconds() {
  141. return 1;
  142. }
  143. @Override
  144. public int getRegistryFetchIntervalSeconds() {
  145. return 1;
  146. }
  147. }
  148. private static class BadServerEurekaClientConfig extends LocalEurekaClientConfig {
  149. @Override
  150. public List<String> getEurekaServerServiceUrls(String myZone) {
  151. return singletonList("http://localhost:0/v2/"); // Fail fast on bad port number
  152. }
  153. @Override
  154. public boolean shouldRegisterWithEureka() {
  155. return false;
  156. }
  157. }
  158. }