package com.netflix.eureka; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import com.netflix.appinfo.AmazonInfo; import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.DataCenterInfo; import com.netflix.appinfo.InstanceInfo; import com.netflix.appinfo.LeaseInfo; import com.netflix.appinfo.MyDataCenterInstanceConfig; import com.netflix.config.ConfigurationManager; import com.netflix.discovery.DefaultEurekaClientConfig; import com.netflix.discovery.DiscoveryClient; import com.netflix.discovery.EurekaClient; import com.netflix.discovery.EurekaClientConfig; import com.netflix.discovery.shared.Application; import com.netflix.discovery.shared.Pair; import com.netflix.eureka.cluster.PeerEurekaNodes; import com.netflix.eureka.mock.MockRemoteEurekaServer; import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl; import com.netflix.eureka.resources.DefaultServerCodecs; import com.netflix.eureka.resources.ServerCodecs; import org.junit.After; import org.junit.Before; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsNull.notNullValue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; /** * @author Nitesh Kant */ public class AbstractTester { public static final String REMOTE_REGION_NAME = "us-east-1"; public static final String REMOTE_REGION_APP_NAME = "MYAPP"; public static final String REMOTE_REGION_INSTANCE_1_HOSTNAME = "blah"; public static final String REMOTE_REGION_INSTANCE_2_HOSTNAME = "blah2"; public static final String LOCAL_REGION_APP_NAME = "MYLOCAPP"; public static final String LOCAL_REGION_INSTANCE_1_HOSTNAME = "blahloc"; public static final String LOCAL_REGION_INSTANCE_2_HOSTNAME = "blahloc2"; public static final String REMOTE_ZONE = "us-east-1c"; protected final List<Pair<String, String>> registeredApps = new ArrayList<Pair<String, String>>(); protected final Map<String, Application> remoteRegionApps = new HashMap<String, Application>(); protected final Map<String, Application> remoteRegionAppsDelta = new HashMap<String, Application>(); protected MockRemoteEurekaServer mockRemoteEurekaServer; protected EurekaServerConfig serverConfig; protected EurekaServerContext serverContext; protected EurekaClient client; protected PeerAwareInstanceRegistryImpl registry; @Before public void setUp() throws Exception { ConfigurationManager.getConfigInstance().clearProperty("eureka.remoteRegion.global.appWhiteList"); ConfigurationManager.getConfigInstance().setProperty("eureka.responseCacheAutoExpirationInSeconds", "10"); ConfigurationManager.getConfigInstance().clearProperty("eureka.remoteRegion." + REMOTE_REGION_NAME + ".appWhiteList"); ConfigurationManager.getConfigInstance().setProperty("eureka.deltaRetentionTimerIntervalInMs", "600000"); ConfigurationManager.getConfigInstance().setProperty("eureka.remoteRegion.registryFetchIntervalInSeconds", "5"); populateRemoteRegistryAtStartup(); mockRemoteEurekaServer = newMockRemoteServer(); mockRemoteEurekaServer.start(); ConfigurationManager.getConfigInstance().setProperty("eureka.remoteRegionUrlsWithName", REMOTE_REGION_NAME + ";http://localhost:" + mockRemoteEurekaServer.getPort() + MockRemoteEurekaServer.EUREKA_API_BASE_PATH); serverConfig = spy(new DefaultEurekaServerConfig()); InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); builder.setIPAddr("10.10.101.00"); builder.setHostName("Hosttt"); builder.setAppName("EurekaTestApp-" + UUID.randomUUID()); builder.setLeaseInfo(LeaseInfo.Builder.newBuilder().build()); builder.setDataCenterInfo(getDataCenterInfo()); ConfigurationManager.getConfigInstance().setProperty("eureka.serviceUrl.default", "http://localhost:" + mockRemoteEurekaServer.getPort() + MockRemoteEurekaServer.EUREKA_API_BASE_PATH); DefaultEurekaClientConfig clientConfig = new DefaultEurekaClientConfig(); // setup config in advance, used in initialize converter ApplicationInfoManager applicationInfoManager = new ApplicationInfoManager(new MyDataCenterInstanceConfig(), builder.build()); client = new DiscoveryClient(applicationInfoManager, clientConfig); ServerCodecs serverCodecs = new DefaultServerCodecs(serverConfig); registry = makePeerAwareInstanceRegistry(serverConfig, clientConfig, serverCodecs, client); serverContext = new DefaultEurekaServerContext( serverConfig, serverCodecs, registry, mock(PeerEurekaNodes.class), applicationInfoManager ); serverContext.initialize(); } protected DataCenterInfo getDataCenterInfo() { return new DataCenterInfo() { @Override public Name getName() { return Name.MyOwn; } }; } protected PeerAwareInstanceRegistryImpl makePeerAwareInstanceRegistry(EurekaServerConfig serverConfig, EurekaClientConfig clientConfig, ServerCodecs serverCodecs, EurekaClient eurekaClient) { return new TestPeerAwareInstanceRegistry(serverConfig, clientConfig, serverCodecs, eurekaClient); } protected MockRemoteEurekaServer newMockRemoteServer() { return new MockRemoteEurekaServer(0 /* use ephemeral */, remoteRegionApps, remoteRegionAppsDelta); } @After public void tearDown() throws Exception { for (Pair<String, String> registeredApp : registeredApps) { System.out.println("Canceling application: " + registeredApp.first() + " from local registry."); registry.cancel(registeredApp.first(), registeredApp.second(), false); } serverContext.shutdown(); mockRemoteEurekaServer.stop(); remoteRegionApps.clear(); remoteRegionAppsDelta.clear(); ConfigurationManager.getConfigInstance().clearProperty("eureka.remoteRegionUrls"); ConfigurationManager.getConfigInstance().clearProperty("eureka.deltaRetentionTimerIntervalInMs"); } private static Application createRemoteApps() { Application myapp = new Application(REMOTE_REGION_APP_NAME); InstanceInfo instanceInfo = createRemoteInstance(REMOTE_REGION_INSTANCE_1_HOSTNAME); //instanceInfo.setActionType(InstanceInfo.ActionType.MODIFIED); myapp.addInstance(instanceInfo); return myapp; } private static Application createRemoteAppsDelta() { Application myapp = new Application(REMOTE_REGION_APP_NAME); InstanceInfo instanceInfo = createRemoteInstance(REMOTE_REGION_INSTANCE_1_HOSTNAME); myapp.addInstance(instanceInfo); return myapp; } protected static InstanceInfo createRemoteInstance(String instanceHostName) { InstanceInfo.Builder instanceBuilder = InstanceInfo.Builder.newBuilder(); instanceBuilder.setAppName(REMOTE_REGION_APP_NAME); instanceBuilder.setHostName(instanceHostName); instanceBuilder.setIPAddr("10.10.101.1"); instanceBuilder.setDataCenterInfo(getAmazonInfo(REMOTE_ZONE, instanceHostName)); instanceBuilder.setLeaseInfo(LeaseInfo.Builder.newBuilder().build()); return instanceBuilder.build(); } protected static InstanceInfo createLocalInstance(String hostname) { return createLocalInstanceWithStatus(hostname, InstanceInfo.InstanceStatus.UP); } protected static InstanceInfo createLocalStartingInstance(String hostname) { return createLocalInstanceWithStatus(hostname, InstanceInfo.InstanceStatus.STARTING); } protected static InstanceInfo createLocalOutOfServiceInstance(String hostname) { return createLocalInstanceWithStatus(hostname, InstanceInfo.InstanceStatus.OUT_OF_SERVICE); } private static InstanceInfo createLocalInstanceWithStatus(String hostname, InstanceInfo.InstanceStatus status) { InstanceInfo.Builder instanceBuilder = InstanceInfo.Builder.newBuilder(); instanceBuilder.setAppName(LOCAL_REGION_APP_NAME); instanceBuilder.setHostName(hostname); instanceBuilder.setIPAddr("10.10.101.1"); instanceBuilder.setDataCenterInfo(getAmazonInfo(null, hostname)); instanceBuilder.setLeaseInfo(LeaseInfo.Builder.newBuilder().build()); instanceBuilder.setStatus(status); return instanceBuilder.build(); } private static AmazonInfo getAmazonInfo(@Nullable String availabilityZone, String instanceHostName) { AmazonInfo.Builder azBuilder = AmazonInfo.Builder.newBuilder(); azBuilder.addMetadata(AmazonInfo.MetaDataKey.availabilityZone, null == availabilityZone ? "us-east-1a" : availabilityZone); azBuilder.addMetadata(AmazonInfo.MetaDataKey.instanceId, instanceHostName); azBuilder.addMetadata(AmazonInfo.MetaDataKey.amiId, "XXX"); azBuilder.addMetadata(AmazonInfo.MetaDataKey.instanceType, "XXX"); azBuilder.addMetadata(AmazonInfo.MetaDataKey.localIpv4, "XXX"); azBuilder.addMetadata(AmazonInfo.MetaDataKey.publicIpv4, "XXX"); azBuilder.addMetadata(AmazonInfo.MetaDataKey.publicHostname, instanceHostName); return azBuilder.build(); } private void populateRemoteRegistryAtStartup() { Application myapp = createRemoteApps(); Application myappDelta = createRemoteAppsDelta(); remoteRegionApps.put(REMOTE_REGION_APP_NAME, myapp); remoteRegionAppsDelta.put(REMOTE_REGION_APP_NAME, myappDelta); } private static class TestPeerAwareInstanceRegistry extends PeerAwareInstanceRegistryImpl { public TestPeerAwareInstanceRegistry(EurekaServerConfig serverConfig, EurekaClientConfig clientConfig, ServerCodecs serverCodecs, EurekaClient eurekaClient) { super(serverConfig, clientConfig, serverCodecs, eurekaClient); } @Override public boolean isLeaseExpirationEnabled() { return false; } @Override public InstanceInfo getNextServerFromEureka(String virtualHostname, boolean secure) { return null; } } protected void verifyLocalInstanceStatus(String id, InstanceInfo.InstanceStatus status) { InstanceInfo instanceInfo = registry.getApplication(LOCAL_REGION_APP_NAME).getByInstanceId(id); assertThat("InstanceInfo with id " + id + " not found", instanceInfo, is(notNullValue())); assertThat("Invalid InstanceInfo state", instanceInfo.getStatus(), is(equalTo(status))); } protected void registerInstanceLocally(InstanceInfo remoteInstance) { registry.register(remoteInstance, 10000000, false); registeredApps.add(new Pair<String, String>(LOCAL_REGION_APP_NAME, LOCAL_REGION_APP_NAME)); } }