├── .github └── workflows │ ├── nebula-ci.yml │ ├── nebula-publish.yml │ └── nebula-snapshot.yml ├── .gitignore ├── .netflixoss ├── CHANGELOG.md ├── LICENSE ├── OSSMETADATA ├── README.md ├── build.gradle ├── codequality └── checkstyle.xml ├── eureka-client-archaius2 ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ ├── appinfo │ │ ├── Archaius2AmazonInfoConfig.java │ │ ├── Ec2EurekaArchaius2InstanceConfig.java │ │ ├── EurekaArchaius2InstanceConfig.java │ │ └── providers │ │ │ ├── AmazonInfoProviderFactory.java │ │ │ ├── Archaius2VipAddressResolver.java │ │ │ ├── CompositeInstanceConfigFactory.java │ │ │ ├── CustomAmazonInfoProviderInstanceConfigFactory.java │ │ │ └── EurekaInstanceConfigFactory.java │ │ └── discovery │ │ ├── EurekaArchaius2ClientConfig.java │ │ ├── guice │ │ ├── EurekaClientModule.java │ │ └── InternalEurekaClientModule.java │ │ ├── internal │ │ └── util │ │ │ └── InternalPrefixedConfig.java │ │ └── shared │ │ └── transport │ │ └── EurekaArchaius2TransportConfig.java │ └── test │ └── java │ └── com │ └── netflix │ ├── appinfo │ └── Ec2EurekaArchaius2InstanceConfigTest.java │ └── discovery │ ├── guice │ ├── Ec2EurekaClientModuleTest.java │ ├── EurekaClientModuleConfigurationTest.java │ └── NonEc2EurekaClientModuleTest.java │ └── internal │ └── util │ └── InternalPrefixedConfigTest.java ├── eureka-client-jersey2 ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── discovery │ │ ├── Jersey2DiscoveryClientOptionalArgs.java │ │ ├── guice │ │ └── Jersey2EurekaModule.java │ │ └── shared │ │ └── transport │ │ └── jersey2 │ │ ├── AbstractJersey2EurekaHttpClient.java │ │ ├── EurekaIdentityHeaderFilter.java │ │ ├── EurekaJersey2Client.java │ │ ├── EurekaJersey2ClientImpl.java │ │ ├── Jersey2ApplicationClient.java │ │ ├── Jersey2ApplicationClientFactory.java │ │ ├── Jersey2EurekaIdentityHeaderFilter.java │ │ └── Jersey2TransportClientFactories.java │ └── test │ └── java │ └── com │ └── netflix │ └── discovery │ ├── guice │ └── Jersey2EurekaModuleTest.java │ └── shared │ └── transport │ └── jersey2 │ └── AbstractJersey2EurekaHttpClientTest.java ├── eureka-client ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ ├── appinfo │ │ ├── AbstractEurekaIdentity.java │ │ ├── AbstractInstanceConfig.java │ │ ├── AmazonInfo.java │ │ ├── AmazonInfoConfig.java │ │ ├── ApplicationInfoManager.java │ │ ├── Archaius1AmazonInfoConfig.java │ │ ├── CloudInstanceConfig.java │ │ ├── DataCenterInfo.java │ │ ├── EurekaAccept.java │ │ ├── EurekaClientIdentity.java │ │ ├── EurekaInstanceConfig.java │ │ ├── HealthCheckCallback.java │ │ ├── HealthCheckCallbackToHandlerBridge.java │ │ ├── HealthCheckHandler.java │ │ ├── HealthCheckResource.java │ │ ├── InstanceInfo.java │ │ ├── LeaseInfo.java │ │ ├── MyDataCenterInfo.java │ │ ├── MyDataCenterInstanceConfig.java │ │ ├── PropertiesInstanceConfig.java │ │ ├── PropertyBasedAmazonInfoConfigConstants.java │ │ ├── PropertyBasedInstanceConfigConstants.java │ │ ├── RefreshableAmazonInfoProvider.java │ │ ├── RefreshableInstanceConfig.java │ │ ├── UniqueIdentifier.java │ │ └── providers │ │ │ ├── Archaius1VipAddressResolver.java │ │ │ ├── CloudInstanceConfigProvider.java │ │ │ ├── EurekaConfigBasedInstanceInfoProvider.java │ │ │ ├── MyDataCenterInstanceConfigProvider.java │ │ │ └── VipAddressResolver.java │ │ └── discovery │ │ ├── AbstractAzToRegionMapper.java │ │ ├── AbstractDiscoveryClientOptionalArgs.java │ │ ├── AzToRegionMapper.java │ │ ├── BackupRegistry.java │ │ ├── CacheRefreshedEvent.java │ │ ├── CommonConstants.java │ │ ├── DNSBasedAzToRegionMapper.java │ │ ├── DefaultEurekaClientConfig.java │ │ ├── DiscoveryClient.java │ │ ├── DiscoveryEvent.java │ │ ├── DiscoveryManager.java │ │ ├── EurekaClient.java │ │ ├── EurekaClientConfig.java │ │ ├── EurekaClientNames.java │ │ ├── EurekaEvent.java │ │ ├── EurekaEventListener.java │ │ ├── EurekaIdentityHeaderFilter.java │ │ ├── EurekaNamespace.java │ │ ├── EurekaUpStatusResolver.java │ │ ├── InstanceInfoReplicator.java │ │ ├── InstanceRegionChecker.java │ │ ├── InternalEurekaStatusModule.java │ │ ├── NotImplementedRegistryImpl.java │ │ ├── PreRegistrationHandler.java │ │ ├── PropertyBasedAzToRegionMapper.java │ │ ├── PropertyBasedClientConfigConstants.java │ │ ├── StatusChangeEvent.java │ │ ├── TimedSupervisorTask.java │ │ ├── converters │ │ ├── Auto.java │ │ ├── Converters.java │ │ ├── EntityBodyConverter.java │ │ ├── EnumLookup.java │ │ ├── EurekaJacksonCodec.java │ │ ├── JsonXStream.java │ │ ├── KeyFormatter.java │ │ ├── XmlXStream.java │ │ ├── jackson │ │ │ ├── AbstractEurekaJacksonCodec.java │ │ │ ├── DataCenterTypeInfoResolver.java │ │ │ ├── EurekaJacksonJsonModifiers.java │ │ │ ├── EurekaJacksonXmlModifiers.java │ │ │ ├── EurekaJsonJacksonCodec.java │ │ │ ├── EurekaXmlJacksonCodec.java │ │ │ ├── builder │ │ │ │ ├── ApplicationsJacksonBuilder.java │ │ │ │ ├── ApplicationsXmlJacksonBuilder.java │ │ │ │ └── StringInterningAmazonInfoBuilder.java │ │ │ ├── mixin │ │ │ │ ├── ApplicationXmlMixIn.java │ │ │ │ ├── ApplicationsJsonMixIn.java │ │ │ │ ├── ApplicationsXmlMixIn.java │ │ │ │ ├── DataCenterInfoXmlMixIn.java │ │ │ │ ├── InstanceInfoJsonMixIn.java │ │ │ │ ├── MiniInstanceInfoMixIn.java │ │ │ │ └── PortWrapperXmlMixIn.java │ │ │ └── serializer │ │ │ │ ├── ApplicationXmlDeserializer.java │ │ │ │ ├── ApplicationsJsonBeanSerializer.java │ │ │ │ ├── ApplicationsXmlBeanSerializer.java │ │ │ │ ├── InstanceInfoJsonBeanSerializer.java │ │ │ │ ├── InstanceInfoXmlBeanSerializer.java │ │ │ │ └── PortWrapperXmlDeserializer.java │ │ └── wrappers │ │ │ ├── CodecWrapper.java │ │ │ ├── CodecWrapperBase.java │ │ │ ├── CodecWrappers.java │ │ │ ├── DecoderWrapper.java │ │ │ └── EncoderWrapper.java │ │ ├── endpoint │ │ ├── DnsResolver.java │ │ └── EndpointUtils.java │ │ ├── guice │ │ └── EurekaModule.java │ │ ├── internal │ │ └── util │ │ │ ├── AmazonInfoUtils.java │ │ │ └── Archaius1Utils.java │ │ ├── provider │ │ ├── DiscoveryJerseyProvider.java │ │ ├── ISerializer.java │ │ └── Serializer.java │ │ ├── providers │ │ └── DefaultEurekaClientConfigProvider.java │ │ ├── shared │ │ ├── Application.java │ │ ├── Applications.java │ │ ├── LookupService.java │ │ ├── MonitoredConnectionManager.java │ │ ├── NamedConnectionPool.java │ │ ├── Pair.java │ │ ├── dns │ │ │ ├── DnsService.java │ │ │ └── DnsServiceImpl.java │ │ ├── resolver │ │ │ ├── AsyncResolver.java │ │ │ ├── ClosableResolver.java │ │ │ ├── ClusterResolver.java │ │ │ ├── ClusterResolverException.java │ │ │ ├── ClusterResolverFactory.java │ │ │ ├── DefaultEndpoint.java │ │ │ ├── DnsClusterResolver.java │ │ │ ├── EndpointRandomizer.java │ │ │ ├── EurekaEndpoint.java │ │ │ ├── LegacyClusterResolver.java │ │ │ ├── README.md │ │ │ ├── ReloadingClusterResolver.java │ │ │ ├── ResolverUtils.java │ │ │ ├── StaticClusterResolver.java │ │ │ └── aws │ │ │ │ ├── ApplicationsResolver.java │ │ │ │ ├── AwsEndpoint.java │ │ │ │ ├── ConfigClusterResolver.java │ │ │ │ ├── DnsTxtRecordClusterResolver.java │ │ │ │ ├── EurekaHttpResolver.java │ │ │ │ └── ZoneAffinityClusterResolver.java │ │ └── transport │ │ │ ├── DefaultEurekaTransportConfig.java │ │ │ ├── EurekaClientFactoryBuilder.java │ │ │ ├── EurekaHttpClient.java │ │ │ ├── EurekaHttpClientFactory.java │ │ │ ├── EurekaHttpClients.java │ │ │ ├── EurekaHttpResponse.java │ │ │ ├── EurekaTransportConfig.java │ │ │ ├── PropertyBasedTransportConfigConstants.java │ │ │ ├── README.md │ │ │ ├── TransportClientFactory.java │ │ │ ├── TransportException.java │ │ │ ├── TransportUtils.java │ │ │ ├── decorator │ │ │ ├── EurekaHttpClientDecorator.java │ │ │ ├── MetricsCollectingEurekaHttpClient.java │ │ │ ├── RedirectingEurekaHttpClient.java │ │ │ ├── RetryableEurekaHttpClient.java │ │ │ ├── ServerStatusEvaluator.java │ │ │ ├── ServerStatusEvaluators.java │ │ │ └── SessionedEurekaHttpClient.java │ │ │ └── jersey │ │ │ ├── AbstractJerseyEurekaHttpClient.java │ │ │ ├── ApacheHttpClientConnectionCleaner.java │ │ │ ├── EurekaJerseyClient.java │ │ │ ├── EurekaJerseyClientImpl.java │ │ │ ├── Jersey1DiscoveryClientOptionalArgs.java │ │ │ ├── Jersey1TransportClientFactories.java │ │ │ ├── JerseyApplicationClient.java │ │ │ ├── JerseyEurekaHttpClientFactory.java │ │ │ ├── SSLSocketFactoryAdapter.java │ │ │ └── TransportClientFactories.java │ │ └── util │ │ ├── DeserializerStringCache.java │ │ ├── DiscoveryBuildInfo.java │ │ ├── EurekaEntityComparators.java │ │ ├── EurekaEntityFunctions.java │ │ ├── EurekaEntityTransformers.java │ │ ├── EurekaUtils.java │ │ ├── ExceptionsMetric.java │ │ ├── RateLimiter.java │ │ ├── ServoUtil.java │ │ ├── StringCache.java │ │ ├── StringUtil.java │ │ ├── SystemUtil.java │ │ └── ThresholdLevelsMetric.java │ └── test │ └── java │ └── com │ └── netflix │ ├── appinfo │ ├── AmazonInfoTest.java │ ├── ApplicationInfoManagerTest.java │ ├── CloudInstanceConfigTest.java │ ├── InstanceInfoTest.java │ └── RefreshableAmazonInfoProviderTest.java │ └── discovery │ ├── AbstractDiscoveryClientTester.java │ ├── BackUpRegistryTest.java │ ├── BaseDiscoveryClientTester.java │ ├── DiscoveryClientCloseJerseyThreadTest.java │ ├── DiscoveryClientDisableRegistryTest.java │ ├── DiscoveryClientEventBusTest.java │ ├── DiscoveryClientHealthTest.java │ ├── DiscoveryClientRedirectTest.java │ ├── DiscoveryClientRegisterUpdateTest.java │ ├── DiscoveryClientRegistryTest.java │ ├── DiscoveryClientStatsInitFailedTest.java │ ├── DiscoveryClientStatsTest.java │ ├── EurekaClientLifecycleServerFailureTest.java │ ├── EurekaClientLifecycleTest.java │ ├── EurekaEventListenerTest.java │ ├── InstanceInfoReplicatorTest.java │ ├── InstanceRegionCheckerTest.java │ ├── Jersey1DiscoveryClientOptionalArgsTest.java │ ├── MockBackupRegistry.java │ ├── MockRemoteEurekaServer.java │ ├── TimedSupervisorTaskTest.java │ ├── converters │ ├── CodecLoadTester.java │ ├── EnumLookupTest.java │ ├── EurekaCodecCompatibilityTest.java │ ├── EurekaJacksonCodecIntegrationTest.java │ ├── EurekaJacksonCodecTest.java │ ├── EurekaJsonAndXmlJacksonCodecTest.java │ ├── JsonXStreamTest.java │ ├── StringCacheTest.java │ ├── XmlXStreamTest.java │ ├── jackson │ │ └── builder │ │ │ └── StringInterningAmazonInfoBuilderTest.java │ └── wrappers │ │ └── CodecWrappersTest.java │ ├── guice │ └── EurekaModuleTest.java │ ├── provider │ └── DiscoveryJerseyProviderTest.java │ ├── providers │ └── DefaultEurekaClientConfigProviderTest.java │ ├── shared │ ├── ApplicationsTest.java │ ├── resolver │ │ ├── AsyncResolverTest.java │ │ ├── ReloadingClusterResolverTest.java │ │ ├── ResolverUtilsTest.java │ │ ├── StaticClusterResolverTest.java │ │ └── aws │ │ │ ├── ApplicationsResolverTest.java │ │ │ ├── ConfigClusterResolverTest.java │ │ │ ├── EurekaHttpResolverTest.java │ │ │ ├── SampleCluster.java │ │ │ ├── TestEurekaHttpResolver.java │ │ │ └── ZoneAffinityClusterResolverTest.java │ └── transport │ │ ├── EurekaHttpClientsTest.java │ │ ├── decorator │ │ ├── RedirectingEurekaHttpClientTest.java │ │ ├── RetryableEurekaHttpClientTest.java │ │ └── SessionedEurekaHttpClientTest.java │ │ └── jersey │ │ ├── JerseyApplicationClientTest.java │ │ └── UnexpectedContentTypeTest.java │ └── util │ ├── DeserializerStringCacheTest.java │ ├── DiscoveryBuildInfoTest.java │ ├── EurekaEntityFunctionsTest.java │ ├── EurekaUtilsTest.java │ └── RateLimiterTest.java ├── eureka-core-jersey2 ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── eureka │ │ ├── Jersey2EurekaBootStrap.java │ │ ├── cluster │ │ └── Jersey2PeerEurekaNodes.java │ │ ├── resources │ │ └── EurekaServerContextBinder.java │ │ └── transport │ │ ├── Jersey2DynamicGZIPContentEncodingFilter.java │ │ └── Jersey2ReplicationClient.java │ └── test │ └── java │ └── com │ └── netflix │ └── eureka │ └── transport │ └── Jersey2ReplicationClientTest.java ├── eureka-core ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── eureka │ │ ├── DefaultEurekaServerConfig.java │ │ ├── DefaultEurekaServerContext.java │ │ ├── EurekaBootStrap.java │ │ ├── EurekaServerConfig.java │ │ ├── EurekaServerContext.java │ │ ├── EurekaServerContextHolder.java │ │ ├── EurekaServerIdentity.java │ │ ├── GzipEncodingEnforcingFilter.java │ │ ├── Names.java │ │ ├── RateLimitingFilter.java │ │ ├── ServerRequestAuthFilter.java │ │ ├── StatusFilter.java │ │ ├── V1AwareInstanceInfoConverter.java │ │ ├── Version.java │ │ ├── aws │ │ ├── AsgClient.java │ │ ├── AwsAsgUtil.java │ │ ├── AwsBinder.java │ │ ├── AwsBinderDelegate.java │ │ ├── AwsBindingStrategy.java │ │ ├── EIPManager.java │ │ ├── ElasticNetworkInterfaceBinder.java │ │ └── Route53Binder.java │ │ ├── cluster │ │ ├── AsgReplicationTask.java │ │ ├── DynamicGZIPContentEncodingFilter.java │ │ ├── HttpReplicationClient.java │ │ ├── InstanceReplicationTask.java │ │ ├── PeerEurekaNode.java │ │ ├── PeerEurekaNodes.java │ │ ├── ReplicationTask.java │ │ ├── ReplicationTaskProcessor.java │ │ └── protocol │ │ │ ├── ReplicationInstance.java │ │ │ ├── ReplicationInstanceResponse.java │ │ │ ├── ReplicationList.java │ │ │ └── ReplicationListResponse.java │ │ ├── lease │ │ ├── Lease.java │ │ └── LeaseManager.java │ │ ├── registry │ │ ├── AbstractInstanceRegistry.java │ │ ├── AwsInstanceRegistry.java │ │ ├── InstanceRegistry.java │ │ ├── Key.java │ │ ├── PeerAwareInstanceRegistry.java │ │ ├── PeerAwareInstanceRegistryImpl.java │ │ ├── RemoteRegionRegistry.java │ │ ├── ResponseCache.java │ │ ├── ResponseCacheImpl.java │ │ └── rule │ │ │ ├── AlwaysMatchInstanceStatusRule.java │ │ │ ├── AsgEnabledRule.java │ │ │ ├── DownOrStartingRule.java │ │ │ ├── FirstMatchWinsCompositeRule.java │ │ │ ├── InstanceStatusOverrideRule.java │ │ │ ├── LeaseExistsRule.java │ │ │ ├── OverrideExistsRule.java │ │ │ └── StatusOverrideResult.java │ │ ├── resources │ │ ├── ASGResource.java │ │ ├── AbstractVIPResource.java │ │ ├── ApplicationResource.java │ │ ├── ApplicationsResource.java │ │ ├── CurrentRequestVersion.java │ │ ├── DefaultServerCodecs.java │ │ ├── InstanceResource.java │ │ ├── InstancesResource.java │ │ ├── PeerReplicationResource.java │ │ ├── SecureVIPResource.java │ │ ├── ServerCodecs.java │ │ ├── ServerInfoResource.java │ │ ├── StatusResource.java │ │ └── VIPResource.java │ │ ├── transport │ │ ├── EurekaServerHttpClients.java │ │ ├── JerseyRemoteRegionClientFactory.java │ │ └── JerseyReplicationClient.java │ │ └── util │ │ ├── EurekaMonitors.java │ │ ├── MeasuredRate.java │ │ ├── ServoControl.java │ │ ├── StatusInfo.java │ │ ├── StatusUtil.java │ │ └── batcher │ │ ├── AcceptorExecutor.java │ │ ├── TaskDispatcher.java │ │ ├── TaskDispatchers.java │ │ ├── TaskExecutors.java │ │ ├── TaskHolder.java │ │ ├── TaskProcessor.java │ │ └── TrafficShaper.java │ └── test │ └── java │ └── com │ └── netflix │ └── eureka │ ├── AbstractTester.java │ ├── DefaultEurekaServerConfigTest.java │ ├── GzipEncodingEnforcingFilterTest.java │ ├── RateLimitingFilterTest.java │ ├── RemoteRegionSoftDependencyTest.java │ ├── aws │ └── EIPManagerTest.java │ ├── cluster │ ├── JerseyReplicationClientTest.java │ ├── PeerEurekaNodeTest.java │ ├── PeerEurekaNodesTest.java │ ├── ReplicationTaskProcessorTest.java │ ├── TestableHttpReplicationClient.java │ ├── TestableInstanceReplicationTask.java │ └── protocol │ │ └── JacksonEncodingTest.java │ ├── mock │ └── MockRemoteEurekaServer.java │ ├── registry │ ├── AwsInstanceRegistryTest.java │ ├── InstanceRegistryTest.java │ ├── ResponseCacheTest.java │ └── TimeConsumingInstanceRegistryTest.java │ ├── resources │ ├── AbstractVIPResourceTest.java │ ├── ApplicationResourceTest.java │ ├── ApplicationsResourceTest.java │ ├── InstanceResourceTest.java │ ├── PeerReplicationResourceTest.java │ └── ReplicationConcurrencyTest.java │ ├── test │ └── async │ │ └── executor │ │ ├── AsyncExecutorException.java │ │ ├── AsyncResult.java │ │ ├── AsyncSequentialExecutor.java │ │ ├── Backoff.java │ │ ├── ConcreteAsyncResult.java │ │ ├── SequentialEvents.java │ │ └── SingleEvent.java │ └── util │ ├── AwsAsgUtilTest.java │ ├── StatusUtilTest.java │ └── batcher │ ├── AcceptorExecutorTest.java │ ├── RecordingProcessor.java │ ├── TaskDispatchersTest.java │ └── TaskExecutorsTest.java ├── eureka-examples ├── README.md ├── build.gradle ├── conf │ ├── log4j.properties │ ├── sample-eureka-client.properties │ └── sample-eureka-service.properties └── src │ └── main │ └── java │ └── com │ └── netflix │ └── eureka │ ├── ExampleEurekaClient.java │ ├── ExampleEurekaGovernatedService.java │ ├── ExampleEurekaService.java │ └── ExampleServiceBase.java ├── eureka-resources └── src │ └── main │ └── resources │ ├── css │ ├── jquery-ui-1.7.2.custom.css │ └── main.css │ ├── js │ ├── jquery-1.11.1.js │ ├── jquery-ui-1.7.2.custom.min.js │ └── jquery.dataTables.js │ └── jsp │ ├── header.jsp │ ├── lastN.jsp │ ├── navbar.jsp │ └── status.jsp ├── eureka-server-governator ├── README.md ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── eureka │ │ ├── EurekaContextListener.java │ │ ├── EurekaInjectorCreator.java │ │ └── guice │ │ ├── Ec2EurekaServerModule.java │ │ └── LocalDevEurekaServerModule.java │ ├── resources │ ├── eureka-client.properties │ ├── eureka-server.properties │ └── log4j.properties │ └── webapp │ └── WEB-INF │ └── web.xml ├── eureka-server ├── build.gradle ├── runclient.sh ├── runservice.sh └── src │ ├── main │ ├── resources │ │ ├── eureka-client.properties │ │ ├── eureka-server.properties │ │ └── log4j.properties │ └── webapp │ │ └── WEB-INF │ │ └── web.xml │ └── test │ └── java │ └── com │ └── netflix │ └── eureka │ └── resources │ └── EurekaClientServerRestIntegrationTest.java ├── eureka-test-utils ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── discovery │ │ ├── junit │ │ └── resource │ │ │ ├── DiscoveryClientResource.java │ │ │ └── SimpleEurekaHttpServerResource.java │ │ ├── shared │ │ └── transport │ │ │ ├── ClusterSampleData.java │ │ │ ├── EurekaHttpClientCompatibilityTestSuite.java │ │ │ ├── EurekaHttpRequest.java │ │ │ ├── EurekaTransportEventListener.java │ │ │ └── SimpleEurekaHttpServer.java │ │ └── util │ │ ├── ApplicationFunctions.java │ │ ├── DiagnosticClient.java │ │ └── InstanceInfoGenerator.java │ └── test │ └── java │ └── com │ └── netflix │ └── discovery │ ├── shared │ └── transport │ │ └── SimpleEurekaHttpServerTest.java │ └── util │ └── InstanceInfoGeneratorTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── eureka_architecture.png └── logo │ ├── eureka-logo-150.png │ ├── eureka-logo-2624.png │ ├── eureka-logo-300.png │ ├── eureka-logo-600.png │ └── eureka-logo.ai └── settings.gradle /.github/workflows/nebula-ci.yml: -------------------------------------------------------------------------------- 1 | name: "CI" 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | tags-ignore: 7 | - '*' 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | # test against JDK 8 16 | java: [ 8 ] 17 | name: CI with Java ${{ matrix.java }} 18 | steps: 19 | - uses: actions/checkout@v1 20 | - name: Setup jdk 21 | uses: actions/setup-java@v1 22 | with: 23 | java-version: ${{ matrix.java }} 24 | - uses: actions/cache@v1 25 | id: gradle-cache 26 | with: 27 | path: ~/.gradle/caches 28 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle/dependency-locks/*.lockfile') }} 29 | restore-keys: | 30 | - ${{ runner.os }}-gradle- 31 | - uses: actions/cache@v1 32 | id: gradle-wrapper-cache 33 | with: 34 | path: ~/.gradle/wrapper 35 | key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }} 36 | restore-keys: | 37 | - ${{ runner.os }}-gradlewrapper- 38 | - name: Build with Gradle 39 | run: ./gradlew --info --stacktrace build 40 | env: 41 | CI_NAME: github_actions 42 | CI_BUILD_NUMBER: ${{ github.sha }} 43 | CI_BUILD_URL: 'https://github.com/${{ github.repository }}' 44 | CI_BRANCH: ${{ github.ref }} 45 | COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | -------------------------------------------------------------------------------- /.github/workflows/nebula-publish.yml: -------------------------------------------------------------------------------- 1 | name: "Publish candidate/release to NetflixOSS and Maven Central" 2 | on: 3 | push: 4 | tags: 5 | - v*.*.* 6 | - v*.*.*-rc.* 7 | release: 8 | types: 9 | - published 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Setup jdk 8 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: 1.8 20 | - uses: actions/cache@v1 21 | id: gradle-cache 22 | with: 23 | path: ~/.gradle/caches 24 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle/dependency-locks/*.lockfile') }} 25 | restore-keys: | 26 | - ${{ runner.os }}-gradle- 27 | - uses: actions/cache@v1 28 | id: gradle-wrapper-cache 29 | with: 30 | path: ~/.gradle/wrapper 31 | key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }} 32 | restore-keys: | 33 | - ${{ runner.os }}-gradlewrapper- 34 | - name: Publish candidate 35 | if: contains(github.ref, '-rc.') 36 | run: ./gradlew --info --stacktrace -Prelease.useLastTag=true candidate 37 | env: 38 | NETFLIX_OSS_SIGNING_KEY: ${{ secrets.ORG_SIGNING_KEY }} 39 | NETFLIX_OSS_SIGNING_PASSWORD: ${{ secrets.ORG_SIGNING_PASSWORD }} 40 | NETFLIX_OSS_REPO_USERNAME: ${{ secrets.ORG_NETFLIXOSS_USERNAME }} 41 | NETFLIX_OSS_REPO_PASSWORD: ${{ secrets.ORG_NETFLIXOSS_PASSWORD }} 42 | - name: Publish release 43 | if: (!contains(github.ref, '-rc.')) 44 | run: ./gradlew --info -Prelease.useLastTag=true final 45 | env: 46 | NETFLIX_OSS_SONATYPE_USERNAME: ${{ secrets.ORG_SONATYPE_USERNAME }} 47 | NETFLIX_OSS_SONATYPE_PASSWORD: ${{ secrets.ORG_SONATYPE_PASSWORD }} 48 | NETFLIX_OSS_SIGNING_KEY: ${{ secrets.ORG_SIGNING_KEY }} 49 | NETFLIX_OSS_SIGNING_PASSWORD: ${{ secrets.ORG_SIGNING_PASSWORD }} 50 | NETFLIX_OSS_REPO_USERNAME: ${{ secrets.ORG_NETFLIXOSS_USERNAME }} 51 | NETFLIX_OSS_REPO_PASSWORD: ${{ secrets.ORG_NETFLIXOSS_PASSWORD }} 52 | -------------------------------------------------------------------------------- /.github/workflows/nebula-snapshot.yml: -------------------------------------------------------------------------------- 1 | name: "Publish snapshot to NetflixOSS and Maven Central" 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | fetch-depth: 0 15 | - name: Set up JDK 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: 8 19 | - uses: actions/cache@v2 20 | id: gradle-cache 21 | with: 22 | path: | 23 | ~/.gradle/caches 24 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 25 | - uses: actions/cache@v2 26 | id: gradle-wrapper-cache 27 | with: 28 | path: | 29 | ~/.gradle/wrapper 30 | key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }} 31 | - name: Build 32 | run: ./gradlew build snapshot 33 | env: 34 | NETFLIX_OSS_SIGNING_KEY: ${{ secrets.ORG_SIGNING_KEY }} 35 | NETFLIX_OSS_SIGNING_PASSWORD: ${{ secrets.ORG_SIGNING_PASSWORD }} 36 | NETFLIX_OSS_REPO_USERNAME: ${{ secrets.ORG_NETFLIXOSS_USERNAME }} 37 | NETFLIX_OSS_REPO_PASSWORD: ${{ secrets.ORG_NETFLIXOSS_PASSWORD }} 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.jar 19 | *.rar 20 | *.tar 21 | *.zip 22 | 23 | # Logs and databases # 24 | ###################### 25 | *.log 26 | 27 | # OS generated files # 28 | ###################### 29 | .DS_Store* 30 | ehthumbs.db 31 | Icon? 32 | Thumbs.db 33 | 34 | # Editor Files # 35 | ################ 36 | *~ 37 | *.swp 38 | 39 | # Gradle Files # 40 | ################ 41 | .gradle 42 | .m2 43 | 44 | # Build output directies 45 | /target 46 | */target 47 | /build 48 | */build 49 | /bin 50 | */bin 51 | classes 52 | 53 | # 54 | # # IntelliJ specific files/directories 55 | 56 | # IntelliJ specific files/directories 57 | out 58 | .idea 59 | *.ipr 60 | *.iws 61 | *.iml 62 | atlassian-ide-plugin.xml 63 | 64 | # Eclipse specific files/directories 65 | .classpath 66 | .project 67 | .settings 68 | .metadata 69 | 70 | # NetBeans specific files/directories 71 | .nbattrs 72 | 73 | # publishing secrets 74 | secrets/signing-key 75 | -------------------------------------------------------------------------------- /.netflixoss: -------------------------------------------------------------------------------- 1 | jdk=1.8 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/eureka/015400c60d3dc730c3fc4871e9b586d3805cce0d/CHANGELOG.md -------------------------------------------------------------------------------- /OSSMETADATA: -------------------------------------------------------------------------------- 1 | osslifecycle=active 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Eureka 2 | ====== 3 | [![build](https://github.com/Netflix/eureka/actions/workflows/nebula-snapshot.yml/badge.svg)](https://github.com/Netflix/eureka/actions/workflows/nebula-snapshot.yml) 4 | 5 | Eureka is a RESTful (Representational State Transfer) service that is primarily used in the AWS cloud for the purpose of 6 | discovery, load balancing and failover of middle-tier servers. It plays a critical role in Netflix mid-tier infra. 7 | 8 | Building 9 | -------- 10 | The build requires `java8` because of some required libraries that are `java8` (`servo`), but the source and target 11 | compatibility are still set to `1.7`. Note that tags should be checked out to perform a build. 12 | 13 | Contributing 14 | ------------ 15 | For any non-trivial change (or a large LoC-wise change), please open an issue first to make sure there's alignment on 16 | the scope, the approach, and the viability. 17 | 18 | Support 19 | ---------- 20 | Community-driven mostly, feel free to open an issue with your question, the maintainers are looking over these 21 | periodically. Issues with the most minimal repro possible have the highest chance of being answered. 22 | 23 | 24 | Documentation 25 | -------------- 26 | Please see [wiki](https://github.com/Netflix/eureka/wiki) for detailed documentation. 27 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | maven { 5 | url "https://plugins.gradle.org/m2" 6 | } 7 | } 8 | 9 | dependencies { 10 | classpath 'com.netflix.nebula:gradle-extra-configurations-plugin:2.2.+' 11 | } 12 | } 13 | 14 | plugins { 15 | id 'nebula.netflixoss' version '9.1.0' 16 | id 'org.gretty' version '2.1.0' 17 | } 18 | 19 | idea { 20 | project { 21 | languageLevel = '1.8' 22 | } 23 | } 24 | 25 | if (JavaVersion.current().isJava8Compatible()) { 26 | allprojects { 27 | tasks.withType(Javadoc) { 28 | options.addStringOption('Xdoclint:none', '-quiet') 29 | } 30 | } 31 | } 32 | 33 | allprojects { 34 | ext { 35 | githubProjectName = 'eureka' 36 | 37 | awsVersion = '1.11.277' 38 | servletVersion = '2.5' 39 | jerseyVersion = '1.19.1' 40 | jettisonVersion = '1.5.4' 41 | apacheHttpClientVersion = '4.5.3' 42 | commonsConfigurationVersion = '1.10' 43 | jsr305Version = '3.0.2' 44 | guiceVersion = '4.1.0' 45 | servoVersion = '0.12.21' 46 | governatorVersion = '1.17.5' 47 | archaiusVersion = '0.7.6' 48 | jacksonVersion = '2.10.5' 49 | jacksonDatabindVersion = '2.10.5.1' 50 | woodstoxVersion = '5.2.1' 51 | 52 | // test deps 53 | jetty_version = '7.2.0.v20101020' 54 | junit_version = '4.11' 55 | mockitoVersion = '3.4.0' 56 | mockserverVersion = '3.9.2' 57 | } 58 | } 59 | 60 | subprojects { 61 | apply plugin: 'nebula.netflixoss' 62 | apply plugin: 'java' 63 | 64 | group = "com.netflix.${githubProjectName}" 65 | 66 | sourceCompatibility = 1.8 67 | targetCompatibility = 1.8 68 | 69 | repositories { 70 | mavenCentral() 71 | } 72 | 73 | test { 74 | forkEvery = 1 75 | // setting this property prevents java from grabbing focus when running the tests under osx 76 | systemProperty 'java.awt.headless', 'true' 77 | } 78 | 79 | jar { 80 | manifest { 81 | attributes('Build-Time-ISO-8601': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")) 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /eureka-client-archaius2/README.md: -------------------------------------------------------------------------------- 1 | This is a version of eureka-client that has been ported to use Archaius 2.x as the backing configuration system. Please note that this client is still work in progress. This client is also only java8 compatible (as Archaius 2.x is only java8 compatible). -------------------------------------------------------------------------------- /eureka-client-archaius2/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'nebula.test-jar' 2 | 3 | def archaius2Version = '2.1.7' 4 | 5 | sourceSets { 6 | test { 7 | resources.srcDir file('src/main/resources') 8 | } 9 | } 10 | 11 | dependencies { 12 | compile project(':eureka-client') 13 | 14 | // archaius2 15 | compile "com.netflix.archaius:archaius2-core:${archaius2Version}" 16 | compile "com.netflix.archaius:archaius2-api:${archaius2Version}" 17 | 18 | testCompile project(':eureka-test-utils') 19 | 20 | testCompile "junit:junit:${junit_version}" 21 | testCompile 'org.mortbay.jetty:jetty:6.1H.22' 22 | testCompile "org.mockito:mockito-core:${mockitoVersion}" 23 | testCompile "org.mock-server:mockserver-netty:${mockserverVersion}" 24 | testCompile "com.netflix.archaius:archaius2-guice:${archaius2Version}" 25 | testCompile "com.netflix.governator:governator:${governatorVersion}" 26 | } 27 | -------------------------------------------------------------------------------- /eureka-client-archaius2/src/main/java/com/netflix/appinfo/providers/AmazonInfoProviderFactory.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo.providers; 2 | 3 | import com.netflix.appinfo.AmazonInfo; 4 | 5 | import javax.inject.Provider; 6 | 7 | public interface AmazonInfoProviderFactory { 8 | Provider get(); 9 | } 10 | -------------------------------------------------------------------------------- /eureka-client-archaius2/src/main/java/com/netflix/appinfo/providers/Archaius2VipAddressResolver.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo.providers; 2 | 3 | import com.netflix.archaius.api.Config; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.inject.Inject; 8 | import javax.inject.Singleton; 9 | import java.util.regex.Matcher; 10 | import java.util.regex.Pattern; 11 | 12 | @Singleton 13 | public class Archaius2VipAddressResolver implements VipAddressResolver { 14 | 15 | private static final Logger logger = LoggerFactory.getLogger(Archaius2VipAddressResolver.class); 16 | 17 | private static final Pattern VIP_ATTRIBUTES_PATTERN = Pattern.compile("\\$\\{(.*?)\\}"); 18 | 19 | private final Config config; 20 | 21 | @Inject 22 | public Archaius2VipAddressResolver(Config config) { 23 | this.config = config; 24 | } 25 | 26 | @Override 27 | public String resolveDeploymentContextBasedVipAddresses(String vipAddressMacro) { 28 | if (vipAddressMacro == null) { 29 | return null; 30 | } 31 | 32 | String result = vipAddressMacro; 33 | 34 | Matcher matcher = VIP_ATTRIBUTES_PATTERN.matcher(result); 35 | while (matcher.find()) { 36 | String key = matcher.group(1); 37 | String value = config.getString(key, ""); 38 | 39 | logger.debug("att:{}", matcher.group()); 40 | logger.debug(", att key:{}", key); 41 | logger.debug(", att value:{}", value); 42 | logger.debug(""); 43 | result = result.replaceAll("\\$\\{" + key + "\\}", value); 44 | matcher = VIP_ATTRIBUTES_PATTERN.matcher(result); 45 | } 46 | 47 | return result; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /eureka-client-archaius2/src/main/java/com/netflix/appinfo/providers/CustomAmazonInfoProviderInstanceConfigFactory.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo.providers; 2 | 3 | import com.netflix.appinfo.AmazonInfo; 4 | import com.netflix.appinfo.Ec2EurekaArchaius2InstanceConfig; 5 | import com.netflix.appinfo.EurekaInstanceConfig; 6 | import com.netflix.archaius.api.Config; 7 | import com.netflix.discovery.CommonConstants; 8 | import com.netflix.discovery.DiscoveryManager; 9 | 10 | import com.google.inject.Inject; 11 | import javax.inject.Named; 12 | import javax.inject.Provider; 13 | import javax.inject.Singleton; 14 | 15 | @Singleton 16 | public class CustomAmazonInfoProviderInstanceConfigFactory implements EurekaInstanceConfigFactory { 17 | 18 | private final Config configInstance; 19 | private final Provider amazonInfoProvider; 20 | private EurekaInstanceConfig eurekaInstanceConfig; 21 | 22 | @Inject(optional = true) 23 | @Named(CommonConstants.INSTANCE_CONFIG_NAMESPACE_KEY) 24 | String instanceConfigNamespace; 25 | 26 | String getInstanceConfigNamespace() { 27 | return instanceConfigNamespace == null ? "eureka" : instanceConfigNamespace; 28 | } 29 | 30 | @Inject 31 | public CustomAmazonInfoProviderInstanceConfigFactory(Config configInstance, AmazonInfoProviderFactory amazonInfoProviderFactory) { 32 | this.configInstance = configInstance; 33 | this.amazonInfoProvider = amazonInfoProviderFactory.get(); 34 | } 35 | 36 | @Override 37 | public EurekaInstanceConfig get() { 38 | if (eurekaInstanceConfig == null) { 39 | eurekaInstanceConfig = new Ec2EurekaArchaius2InstanceConfig(configInstance, amazonInfoProvider, getInstanceConfigNamespace()); 40 | 41 | // Copied from CompositeInstanceConfigFactory.get 42 | DiscoveryManager.getInstance().setEurekaInstanceConfig(eurekaInstanceConfig); 43 | } 44 | 45 | return eurekaInstanceConfig; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /eureka-client-archaius2/src/main/java/com/netflix/appinfo/providers/EurekaInstanceConfigFactory.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo.providers; 2 | 3 | import com.netflix.appinfo.EurekaInstanceConfig; 4 | 5 | /** 6 | * An equivalent {@link javax.inject.Provider} interface for {@link com.netflix.appinfo.EurekaInstanceConfig}. 7 | * 8 | * Why define this {@link com.netflix.appinfo.providers.EurekaInstanceConfigFactory} instead 9 | * of using {@link javax.inject.Provider} instead? Provider does not work due to the fact that 10 | * Guice treats Providers specially. 11 | * 12 | * @author David Liu 13 | */ 14 | public interface EurekaInstanceConfigFactory { 15 | 16 | EurekaInstanceConfig get(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /eureka-client-archaius2/src/test/java/com/netflix/discovery/internal/util/InternalPrefixedConfigTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.internal.util; 2 | 3 | import com.netflix.archaius.api.Config; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.mockito.Mockito; 7 | 8 | /** 9 | * @author David Liu 10 | */ 11 | public class InternalPrefixedConfigTest { 12 | 13 | @Test 14 | public void testPrefixes() { 15 | Config configInstance = Mockito.mock(Config.class); 16 | 17 | InternalPrefixedConfig config = new InternalPrefixedConfig(configInstance); 18 | Assert.assertEquals("", config.getNamespace()); 19 | 20 | config = new InternalPrefixedConfig(configInstance, "foo"); 21 | Assert.assertEquals("foo.", config.getNamespace()); 22 | 23 | config = new InternalPrefixedConfig(configInstance, "foo", "bar"); 24 | Assert.assertEquals("foo.bar.", config.getNamespace()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /eureka-client-jersey2/README.md: -------------------------------------------------------------------------------- 1 | Please note that this jersey2 compatible Eureka client (eureka-client-jersey2) is created and maintained by the community. Netflix does not currently use this library internally. -------------------------------------------------------------------------------- /eureka-client-jersey2/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'nebula.test-jar' 18 | 19 | configurations.all { 20 | // jersey1 21 | exclude group: 'com.sun.jersey' 22 | exclude group: 'com.sun.jersey.contribs' 23 | exclude module: 'jsr311-api' 24 | } 25 | 26 | dependencies { 27 | compile project(':eureka-client') 28 | compile 'org.glassfish.jersey.core:jersey-client:2.23.1' 29 | compile 'org.glassfish.jersey.connectors:jersey-apache-connector:2.23.1' 30 | 31 | testCompile (project(':eureka-test-utils')) { 32 | // exclude all transitives to avoid bringing in jersey1 eureka-core 33 | transitive = false 34 | } 35 | // bring in jersey2 compatible eureka-core-jersey2 directly 36 | testCompile project(':eureka-core-jersey2') 37 | 38 | testCompile "junit:junit:${junit_version}" 39 | testCompile "org.mockito:mockito-core:${mockitoVersion}" 40 | testCompile "com.netflix.governator:governator:${governatorVersion}" 41 | } 42 | -------------------------------------------------------------------------------- /eureka-client-jersey2/src/main/java/com/netflix/discovery/Jersey2DiscoveryClientOptionalArgs.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import javax.ws.rs.client.ClientRequestFilter; 4 | 5 | /** 6 | * Jersey2 implementation of DiscoveryClientOptionalArgs that supports supplying {@link ClientRequestFilter} 7 | */ 8 | public class Jersey2DiscoveryClientOptionalArgs extends AbstractDiscoveryClientOptionalArgs { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /eureka-client-jersey2/src/main/java/com/netflix/discovery/shared/transport/jersey2/EurekaIdentityHeaderFilter.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport.jersey2; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.ws.rs.client.ClientRequestContext; 6 | import javax.ws.rs.client.ClientRequestFilter; 7 | 8 | import com.netflix.appinfo.AbstractEurekaIdentity; 9 | 10 | public class EurekaIdentityHeaderFilter implements ClientRequestFilter { 11 | 12 | private final AbstractEurekaIdentity authInfo; 13 | 14 | public EurekaIdentityHeaderFilter(AbstractEurekaIdentity authInfo) { 15 | this.authInfo = authInfo; 16 | } 17 | 18 | @Override 19 | public void filter(ClientRequestContext requestContext) throws IOException { 20 | if (authInfo != null) { 21 | requestContext.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_NAME_HEADER_KEY, authInfo.getName()); 22 | requestContext.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_VERSION_HEADER_KEY, authInfo.getVersion()); 23 | 24 | if (authInfo.getId() != null) { 25 | requestContext.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_ID_HEADER_KEY, authInfo.getId()); 26 | } 27 | } 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /eureka-client-jersey2/src/main/java/com/netflix/discovery/shared/transport/jersey2/EurekaJersey2Client.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport.jersey2; 2 | 3 | import javax.ws.rs.client.Client; 4 | 5 | /** 6 | * @author David Liu 7 | */ 8 | public interface EurekaJersey2Client { 9 | 10 | Client getClient(); 11 | 12 | /** 13 | * Clean up resources. 14 | */ 15 | void destroyResources(); 16 | } 17 | -------------------------------------------------------------------------------- /eureka-client-jersey2/src/main/java/com/netflix/discovery/shared/transport/jersey2/Jersey2ApplicationClient.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport.jersey2; 2 | 3 | import javax.ws.rs.client.Client; 4 | import javax.ws.rs.client.Invocation.Builder; 5 | import javax.ws.rs.core.MultivaluedMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * A version of Jersey2 {@link com.netflix.discovery.shared.transport.EurekaHttpClient} to be used by applications. 11 | * 12 | * @author David Liu 13 | */ 14 | public class Jersey2ApplicationClient extends AbstractJersey2EurekaHttpClient { 15 | 16 | private final MultivaluedMap additionalHeaders; 17 | 18 | public Jersey2ApplicationClient(Client jerseyClient, String serviceUrl, MultivaluedMap additionalHeaders) { 19 | super(jerseyClient, serviceUrl); 20 | this.additionalHeaders = additionalHeaders; 21 | } 22 | 23 | @Override 24 | protected void addExtraHeaders(Builder webResource) { 25 | if (additionalHeaders != null) { 26 | for (Map.Entry> entry: additionalHeaders.entrySet()) { 27 | webResource.header(entry.getKey(), entry.getValue()); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /eureka-client-jersey2/src/main/java/com/netflix/discovery/shared/transport/jersey2/Jersey2EurekaIdentityHeaderFilter.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport.jersey2; 2 | 3 | import com.netflix.appinfo.AbstractEurekaIdentity; 4 | 5 | import javax.ws.rs.client.ClientRequestContext; 6 | import javax.ws.rs.client.ClientRequestFilter; 7 | import java.io.IOException; 8 | 9 | public class Jersey2EurekaIdentityHeaderFilter implements ClientRequestFilter { 10 | 11 | private final AbstractEurekaIdentity authInfo; 12 | 13 | public Jersey2EurekaIdentityHeaderFilter(AbstractEurekaIdentity authInfo) { 14 | this.authInfo = authInfo; 15 | } 16 | 17 | @Override 18 | public void filter(ClientRequestContext requestContext) throws IOException { 19 | if (authInfo != null) { 20 | 21 | requestContext.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_NAME_HEADER_KEY, authInfo.getName()); 22 | requestContext.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_VERSION_HEADER_KEY, authInfo.getVersion()); 23 | 24 | if (authInfo.getId() != null) { 25 | requestContext.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_ID_HEADER_KEY, authInfo.getId()); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /eureka-client/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'nebula.test-jar' 2 | 3 | configurations.all { 4 | // jersey2 5 | exclude group: 'org.glassfish.jersey' 6 | } 7 | 8 | dependencies { 9 | compile "com.netflix.netflix-commons:netflix-eventbus:0.3.0" 10 | compile 'com.thoughtworks.xstream:xstream:1.4.19' 11 | compile "com.netflix.archaius:archaius-core:${archaiusVersion}" 12 | compile 'javax.ws.rs:jsr311-api:1.1.1' 13 | compile "com.netflix.servo:servo-core:${servoVersion}" 14 | compile "com.sun.jersey:jersey-core:${jerseyVersion}" 15 | compile "com.sun.jersey:jersey-client:${jerseyVersion}" 16 | compile "com.sun.jersey.contribs:jersey-apache-client4:${jerseyVersion}" 17 | compile "org.apache.httpcomponents:httpclient:${apacheHttpClientVersion}" 18 | compile "com.google.code.findbugs:jsr305:${jsr305Version}" 19 | compile "commons-configuration:commons-configuration:${commonsConfigurationVersion}" 20 | compile "com.google.inject:guice:${guiceVersion}" 21 | 22 | compile "com.github.vlsi.compactmap:compactmap:2.0" 23 | 24 | compile "com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}" 25 | compile "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" 26 | compile "com.fasterxml.jackson.core:jackson-databind:${jacksonDatabindVersion}" 27 | 28 | // Eureka client uses JSON encoding by default 29 | compileOnly "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jacksonVersion}" 30 | // Prefered jackson Stax serializer. Default Oracle has issues (adds empty namespace) and is slower 31 | compileOnly "com.fasterxml.woodstox:woodstox-core:${woodstoxVersion}" 32 | 33 | runtimeOnly "org.codehaus.jettison:jettison:${jettisonVersion}" 34 | 35 | testCompile project(':eureka-test-utils') 36 | testCompile "junit:junit:${junit_version}" 37 | testCompile 'org.mortbay.jetty:jetty:6.1H.22' 38 | testCompile "org.mockito:mockito-inline:${mockitoVersion}" 39 | testCompile "org.mock-server:mockserver-netty:${mockserverVersion}" 40 | testCompile "com.netflix.governator:governator:${governatorVersion}" 41 | testCompile "com.github.tomakehurst:wiremock-jre8:2.25.1" 42 | testCompile "org.assertj:assertj-core:3.11.1" 43 | testCompile "javax.servlet:javax.servlet-api:4.0.1" 44 | } 45 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/AbstractEurekaIdentity.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | public abstract class AbstractEurekaIdentity { 6 | public static final String PREFIX = "DiscoveryIdentity-"; 7 | 8 | public static final String AUTH_NAME_HEADER_KEY = PREFIX + "Name"; 9 | public static final String AUTH_VERSION_HEADER_KEY = PREFIX + "Version"; 10 | public static final String AUTH_ID_HEADER_KEY = PREFIX + "Id"; 11 | 12 | public abstract String getName(); 13 | 14 | public abstract String getVersion(); 15 | 16 | @Nullable 17 | public abstract String getId(); 18 | } 19 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/AmazonInfoConfig.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | /** 4 | * Config related to loading of amazon metadata from the EC2 metadata url. 5 | * 6 | * @author David Liu 7 | */ 8 | public interface AmazonInfoConfig { 9 | 10 | /** 11 | * @return the config namespace 12 | */ 13 | String getNamespace(); 14 | 15 | /** 16 | * @return whether errors reading from the ec2 metadata url should be logged 17 | */ 18 | boolean shouldLogAmazonMetadataErrors(); 19 | 20 | /** 21 | * @return the read timeout when connecting to the metadata url 22 | */ 23 | int getReadTimeout(); 24 | 25 | /** 26 | * @return the connect timeout when connecting to the metadata url 27 | */ 28 | int getConnectTimeout(); 29 | 30 | /** 31 | * @return the number of retries when unable to read a value from the metadata url 32 | */ 33 | int getNumRetries(); 34 | 35 | /** 36 | * When creating an AmazonInfo via {@link com.netflix.appinfo.AmazonInfo.Builder#autoBuild(String)}, 37 | * a fail fast mechanism exist based on the below configuration. 38 | * If enabled (default to true), the {@link com.netflix.appinfo.AmazonInfo.Builder#autoBuild(String)} 39 | * method will exit early after failing to load the value for the first metadata key (instanceId), 40 | * after the expected number of retries as defined by {@link #getNumRetries()}. 41 | * 42 | * @return whether autoloading should fail fast if loading has failed for the first field (after all retries) 43 | */ 44 | boolean shouldFailFastOnFirstLoad(); 45 | 46 | /** 47 | * When AmazonInfo is specified, setting this to false allows progress on building the AmazonInfo even if 48 | * the instanceId of the environment is not able to be validated. 49 | * 50 | * @return whether to progress with AmazonInfo construction if the instanceId cannot be validated. 51 | */ 52 | boolean shouldValidateInstanceId(); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/Archaius1AmazonInfoConfig.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | import com.netflix.config.DynamicPropertyFactory; 4 | import com.netflix.discovery.CommonConstants; 5 | import com.netflix.discovery.internal.util.Archaius1Utils; 6 | 7 | import static com.netflix.appinfo.PropertyBasedAmazonInfoConfigConstants.*; 8 | 9 | /** 10 | * @author David Liu 11 | */ 12 | public class Archaius1AmazonInfoConfig implements AmazonInfoConfig { 13 | 14 | private final DynamicPropertyFactory configInstance; 15 | private final String namespace; 16 | 17 | public Archaius1AmazonInfoConfig(String namespace) { 18 | this.namespace = namespace.endsWith(".") 19 | ? namespace 20 | : namespace + "."; 21 | 22 | this.configInstance = Archaius1Utils.initConfig(CommonConstants.CONFIG_FILE_NAME); 23 | } 24 | 25 | 26 | @Override 27 | public String getNamespace() { 28 | return namespace; 29 | } 30 | 31 | @Override 32 | public boolean shouldLogAmazonMetadataErrors() { 33 | return configInstance.getBooleanProperty(namespace + LOG_METADATA_ERROR_KEY, false).get(); 34 | } 35 | 36 | @Override 37 | public int getReadTimeout() { 38 | return configInstance.getIntProperty(namespace + READ_TIMEOUT_KEY, Values.DEFAULT_READ_TIMEOUT).get(); 39 | } 40 | 41 | @Override 42 | public int getConnectTimeout() { 43 | return configInstance.getIntProperty(namespace + CONNECT_TIMEOUT_KEY, Values.DEFAULT_CONNECT_TIMEOUT).get(); 44 | } 45 | 46 | @Override 47 | public int getNumRetries() { 48 | return configInstance.getIntProperty(namespace + NUM_RETRIES_KEY, Values.DEFAULT_NUM_RETRIES).get(); 49 | } 50 | 51 | @Override 52 | public boolean shouldFailFastOnFirstLoad() { 53 | return configInstance.getBooleanProperty(namespace + FAIL_FAST_ON_FIRST_LOAD_KEY, true).get(); 54 | } 55 | 56 | @Override 57 | public boolean shouldValidateInstanceId() { 58 | return configInstance.getBooleanProperty(namespace + SHOULD_VALIDATE_INSTANCE_ID_KEY, true).get(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/DataCenterInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.appinfo; 18 | 19 | import com.fasterxml.jackson.annotation.JsonRootName; 20 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 21 | import com.fasterxml.jackson.annotation.JsonTypeInfo.As; 22 | import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; 23 | import com.netflix.discovery.converters.jackson.DataCenterTypeInfoResolver; 24 | 25 | /** 26 | * A simple interface for indicating which datacenter a particular instance belongs. 27 | * 28 | * @author Karthik Ranganathan 29 | * 30 | */ 31 | @JsonRootName("dataCenterInfo") 32 | @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "@class") 33 | @JsonTypeIdResolver(DataCenterTypeInfoResolver.class) 34 | public interface DataCenterInfo { 35 | enum Name {Netflix, Amazon, MyOwn} 36 | 37 | Name getName(); 38 | } 39 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/EurekaClientIdentity.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | /** 4 | * This class holds metadata information related to eureka client auth with the eureka server 5 | */ 6 | public class EurekaClientIdentity extends AbstractEurekaIdentity { 7 | public static final String DEFAULT_CLIENT_NAME = "DefaultClient"; 8 | 9 | private final String clientVersion = "1.4"; 10 | private final String id; 11 | private final String clientName; 12 | 13 | public EurekaClientIdentity(String id) { 14 | this(id, DEFAULT_CLIENT_NAME); 15 | } 16 | 17 | public EurekaClientIdentity(String id, String clientName) { 18 | this.id = id; 19 | this.clientName = clientName; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return clientName; 25 | } 26 | 27 | @Override 28 | public String getVersion() { 29 | return clientVersion; 30 | } 31 | 32 | @Override 33 | public String getId() { 34 | return id; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/HealthCheckCallbackToHandlerBridge.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | /** 4 | * @author Nitesh Kant 5 | */ 6 | @SuppressWarnings("deprecation") 7 | public class HealthCheckCallbackToHandlerBridge implements HealthCheckHandler { 8 | 9 | private final HealthCheckCallback callback; 10 | 11 | public HealthCheckCallbackToHandlerBridge() { 12 | callback = null; 13 | } 14 | 15 | public HealthCheckCallbackToHandlerBridge(HealthCheckCallback callback) { 16 | this.callback = callback; 17 | } 18 | 19 | @Override 20 | public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus currentStatus) { 21 | if (null == callback || InstanceInfo.InstanceStatus.STARTING == currentStatus 22 | || InstanceInfo.InstanceStatus.OUT_OF_SERVICE == currentStatus) { // Do not go to healthcheck handler if the status is starting or OOS. 23 | return currentStatus; 24 | } 25 | 26 | return callback.isHealthy() ? InstanceInfo.InstanceStatus.UP : InstanceInfo.InstanceStatus.DOWN; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/HealthCheckHandler.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | /** 4 | * This provides a more granular healthcheck contract than the existing {@link HealthCheckCallback} 5 | * 6 | * @author Nitesh Kant 7 | */ 8 | public interface HealthCheckHandler { 9 | 10 | InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus currentStatus); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/MyDataCenterInfo.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | /** 7 | * @author Tomasz Bak 8 | */ 9 | public class MyDataCenterInfo implements DataCenterInfo { 10 | 11 | private final Name name; 12 | 13 | @JsonCreator 14 | public MyDataCenterInfo(@JsonProperty("name") Name name) { 15 | this.name = name; 16 | } 17 | 18 | @Override 19 | public Name getName() { 20 | return name; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/MyDataCenterInstanceConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.appinfo; 17 | 18 | import com.google.inject.ProvidedBy; 19 | import com.netflix.appinfo.providers.MyDataCenterInstanceConfigProvider; 20 | 21 | import javax.inject.Singleton; 22 | 23 | /** 24 | * An {@link InstanceInfo} configuration for the non-AWS datacenter. 25 | * 26 | * @author Karthik Ranganathan 27 | * 28 | */ 29 | @Singleton 30 | @ProvidedBy(MyDataCenterInstanceConfigProvider.class) 31 | public class MyDataCenterInstanceConfig extends PropertiesInstanceConfig implements EurekaInstanceConfig { 32 | 33 | public MyDataCenterInstanceConfig() { 34 | } 35 | 36 | public MyDataCenterInstanceConfig(String namespace) { 37 | super(namespace); 38 | } 39 | 40 | public MyDataCenterInstanceConfig(String namespace, DataCenterInfo dataCenterInfo) { 41 | super(namespace, dataCenterInfo); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/PropertyBasedAmazonInfoConfigConstants.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | /** 4 | * @author David Liu 5 | */ 6 | final class PropertyBasedAmazonInfoConfigConstants { 7 | 8 | static final String LOG_METADATA_ERROR_KEY = "logAmazonMetadataErrors"; 9 | static final String READ_TIMEOUT_KEY = "mt.read_timeout"; 10 | static final String CONNECT_TIMEOUT_KEY = "mt.connect_timeout"; 11 | static final String NUM_RETRIES_KEY = "mt.num_retries"; 12 | static final String FAIL_FAST_ON_FIRST_LOAD_KEY = "mt.fail_fast_on_first_load"; 13 | 14 | static final String SHOULD_VALIDATE_INSTANCE_ID_KEY = "validateInstanceId"; 15 | 16 | 17 | static class Values { 18 | static final int DEFAULT_READ_TIMEOUT = 5000; 19 | static final int DEFAULT_CONNECT_TIMEOUT = 2000; 20 | static final int DEFAULT_NUM_RETRIES = 3; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/RefreshableInstanceConfig.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | public interface RefreshableInstanceConfig { 4 | 5 | /** 6 | * resolve the default address 7 | * 8 | * @param refresh 9 | * @return 10 | */ 11 | String resolveDefaultAddress(boolean refresh); 12 | } 13 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/UniqueIdentifier.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo; 2 | 3 | /** 4 | * Generally indicates the unique identifier of a {@link com.netflix.appinfo.DataCenterInfo}, if applicable. 5 | * 6 | * @author rthomas@atlassian.com 7 | */ 8 | public interface UniqueIdentifier { 9 | String getId(); 10 | } 11 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/providers/Archaius1VipAddressResolver.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo.providers; 2 | 3 | import com.netflix.config.DynamicPropertyFactory; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.util.regex.Matcher; 8 | import java.util.regex.Pattern; 9 | 10 | public class Archaius1VipAddressResolver implements VipAddressResolver { 11 | 12 | private static final Logger logger = LoggerFactory.getLogger(Archaius1VipAddressResolver.class); 13 | 14 | private static final Pattern VIP_ATTRIBUTES_PATTERN = Pattern.compile("\\$\\{(.*?)\\}"); 15 | 16 | @Override 17 | public String resolveDeploymentContextBasedVipAddresses(String vipAddressMacro) { 18 | if (vipAddressMacro == null) { 19 | return null; 20 | } 21 | 22 | String result = vipAddressMacro; 23 | 24 | Matcher matcher = VIP_ATTRIBUTES_PATTERN.matcher(result); 25 | while (matcher.find()) { 26 | String key = matcher.group(1); 27 | String value = DynamicPropertyFactory.getInstance().getStringProperty(key, "").get(); 28 | 29 | logger.debug("att:{}", matcher.group()); 30 | logger.debug(", att key:{}", key); 31 | logger.debug(", att value:{}", value); 32 | logger.debug(""); 33 | result = result.replaceAll("\\$\\{" + key + "\\}", value); 34 | matcher = VIP_ATTRIBUTES_PATTERN.matcher(result); 35 | } 36 | 37 | return result; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/providers/CloudInstanceConfigProvider.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo.providers; 2 | 3 | import javax.inject.Provider; 4 | 5 | import com.google.inject.Inject; 6 | import com.netflix.appinfo.CloudInstanceConfig; 7 | import com.netflix.discovery.DiscoveryManager; 8 | import com.netflix.discovery.EurekaNamespace; 9 | 10 | /** 11 | * This provider is necessary because the namespace is optional. 12 | * @author elandau 13 | */ 14 | public class CloudInstanceConfigProvider implements Provider { 15 | @Inject(optional = true) 16 | @EurekaNamespace 17 | private String namespace; 18 | 19 | private CloudInstanceConfig config; 20 | 21 | @Override 22 | public synchronized CloudInstanceConfig get() { 23 | if (config == null) { 24 | if (namespace == null) { 25 | config = new CloudInstanceConfig(); 26 | } else { 27 | config = new CloudInstanceConfig(namespace); 28 | } 29 | 30 | // TODO: Remove this when DiscoveryManager is finally no longer used 31 | DiscoveryManager.getInstance().setEurekaInstanceConfig(config); 32 | } 33 | return config; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/providers/MyDataCenterInstanceConfigProvider.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo.providers; 2 | 3 | import javax.inject.Provider; 4 | 5 | import com.google.inject.Inject; 6 | import com.netflix.appinfo.EurekaInstanceConfig; 7 | import com.netflix.appinfo.MyDataCenterInstanceConfig; 8 | import com.netflix.discovery.DiscoveryManager; 9 | import com.netflix.discovery.EurekaNamespace; 10 | 11 | public class MyDataCenterInstanceConfigProvider implements Provider { 12 | @Inject(optional = true) 13 | @EurekaNamespace 14 | private String namespace; 15 | 16 | private MyDataCenterInstanceConfig config; 17 | 18 | @Override 19 | public synchronized MyDataCenterInstanceConfig get() { 20 | if (config == null) { 21 | if (namespace == null) { 22 | config = new MyDataCenterInstanceConfig(); 23 | } else { 24 | config = new MyDataCenterInstanceConfig(namespace); 25 | } 26 | 27 | // TODO: Remove this when DiscoveryManager is finally no longer used 28 | DiscoveryManager.getInstance().setEurekaInstanceConfig(config); 29 | } 30 | return config; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/appinfo/providers/VipAddressResolver.java: -------------------------------------------------------------------------------- 1 | package com.netflix.appinfo.providers; 2 | 3 | /** 4 | * This only really exist for legacy support 5 | */ 6 | public interface VipAddressResolver { 7 | 8 | /** 9 | * Convert VIPAddress by substituting environment variables if necessary. 10 | * 11 | * @param vipAddressMacro the macro for which the interpolation needs to be made. 12 | * @return a string representing the final VIPAddress after substitution. 13 | */ 14 | String resolveDeploymentContextBasedVipAddresses(String vipAddressMacro); 15 | } 16 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/AzToRegionMapper.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | /** 4 | * An interface that contains a contract of mapping availability zone to region mapping. An implementation will always 5 | * know before hand which zone to region mapping will be queried from the mapper, this will aid caching of this 6 | * information before hand. 7 | * 8 | * @author Nitesh Kant 9 | */ 10 | public interface AzToRegionMapper { 11 | 12 | /** 13 | * Returns the region for the passed availability zone. 14 | * 15 | * @param availabilityZone Availability zone for which the region is to be retrieved. 16 | * 17 | * @return The region for the passed zone. 18 | */ 19 | String getRegionForAvailabilityZone(String availabilityZone); 20 | 21 | /** 22 | * Update the regions that this mapper knows about. 23 | * 24 | * @param regionsToFetch Regions to fetch. This should be the super set of all regions that this mapper should know. 25 | */ 26 | void setRegionsToFetch(String[] regionsToFetch); 27 | 28 | /** 29 | * Updates the mappings it has if they depend on an external source. 30 | */ 31 | void refreshMapping(); 32 | } 33 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/BackupRegistry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery; 18 | 19 | import com.google.inject.ImplementedBy; 20 | import com.netflix.discovery.shared.Applications; 21 | 22 | /** 23 | * A simple contract for eureka clients to fallback for getting 24 | * registry information in case eureka clients are unable to retrieve this 25 | * information from any of the eureka servers. 26 | * 27 | *

28 | * This is normally not required, but for applications that cannot exist without 29 | * the registry information it can provide some additional reslience. 30 | *

31 | * 32 | * @author Karthik Ranganathan 33 | * 34 | */ 35 | @ImplementedBy(NotImplementedRegistryImpl.class) 36 | public interface BackupRegistry { 37 | 38 | Applications fetchRegistry(); 39 | 40 | Applications fetchRegistry(String[] includeRemoteRegions); 41 | } 42 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/CacheRefreshedEvent.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | /** 4 | * This event is sent by {@link EurekaClient) whenever it has refreshed its local 5 | * local cache with information received from the Eureka server. 6 | * 7 | * @author brenuart 8 | */ 9 | public class CacheRefreshedEvent extends DiscoveryEvent { 10 | @Override 11 | public String toString() { 12 | return "CacheRefreshedEvent[timestamp=" + getTimestamp() + "]"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/CommonConstants.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | /** 4 | * @author David Liu 5 | */ 6 | public final class CommonConstants { 7 | public static final String CONFIG_FILE_NAME = "eureka-client"; 8 | public static final String DEFAULT_CONFIG_NAMESPACE = "eureka"; 9 | public static final String INSTANCE_CONFIG_NAMESPACE_KEY = "eureka.instance.config.namespace"; 10 | public static final String CLIENT_CONFIG_NAMESPACE_KEY = "eureka.client.config.namespace"; 11 | } 12 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/DNSBasedAzToRegionMapper.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import com.netflix.discovery.endpoint.EndpointUtils; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | /** 11 | * DNS-based region mapper that discovers regions via DNS TXT records. 12 | * @author Nitesh Kant 13 | */ 14 | public class DNSBasedAzToRegionMapper extends AbstractAzToRegionMapper { 15 | 16 | public DNSBasedAzToRegionMapper(EurekaClientConfig clientConfig) { 17 | super(clientConfig); 18 | } 19 | 20 | @Override 21 | protected Set getZonesForARegion(String region) { 22 | Map> zoneBasedDiscoveryUrlsFromRegion = EndpointUtils 23 | .getZoneBasedDiscoveryUrlsFromRegion(clientConfig, region); 24 | if (null != zoneBasedDiscoveryUrlsFromRegion) { 25 | return zoneBasedDiscoveryUrlsFromRegion.keySet(); 26 | } 27 | 28 | return Collections.emptySet(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/DiscoveryEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.netflix.discovery; 5 | 6 | /** 7 | * Class to be extended by all discovery events. Abstract as it 8 | * doesn't make sense for generic events to be published directly. 9 | */ 10 | public abstract class DiscoveryEvent implements EurekaEvent { 11 | 12 | // System time when the event happened 13 | private final long timestamp; 14 | 15 | protected DiscoveryEvent() { 16 | this.timestamp = System.currentTimeMillis(); 17 | } 18 | 19 | /** 20 | * @return Return the system time in milliseconds when the event happened. 21 | */ 22 | public final long getTimestamp() { 23 | return this.timestamp; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/EurekaClientNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public final class EurekaClientNames { 23 | 24 | /** 25 | * Eureka metric names consist of three parts [source].[component].[detailed name]: 26 | *
    27 | *
  • source - fixed to eurekaClient (and eurekaServer on the server side)
  • 28 | *
  • component - Eureka component, like registry cache
  • 29 | *
  • detailed name - a detailed metric name explaining its purpose
  • 30 | *
31 | */ 32 | public static final String METRIC_PREFIX = "eurekaClient."; 33 | 34 | public static final String METRIC_REGISTRATION_PREFIX = METRIC_PREFIX + "registration."; 35 | 36 | public static final String METRIC_REGISTRY_PREFIX = METRIC_PREFIX + "registry."; 37 | 38 | public static final String METRIC_RESOLVER_PREFIX = METRIC_PREFIX + "resolver."; 39 | 40 | public static final String METRIC_TRANSPORT_PREFIX = METRIC_PREFIX + "transport."; 41 | 42 | public static final String RESOLVER = "resolver"; 43 | public static final String BOOTSTRAP = "bootstrap"; 44 | public static final String QUERY = "query"; 45 | public static final String REGISTRATION = "registration"; 46 | 47 | private EurekaClientNames() { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/EurekaEvent.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | /** 4 | * Marker interface for Eureka events 5 | * 6 | * @see {@link EurekaEventListener} 7 | */ 8 | public interface EurekaEvent { 9 | } 10 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/EurekaEventListener.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | /** 4 | * Listener for receiving {@link EurekaClient} events such as {@link StatusChangeEvent}. Register 5 | * a listener by calling {@link EurekaClient#registerEventListener(EurekaEventListener)} 6 | */ 7 | public interface EurekaEventListener { 8 | /** 9 | * Notification of an event within the {@link EurekaClient}. 10 | * 11 | * {@link EurekaEventListener#onEvent} is called from the context of an internal eureka thread 12 | * and must therefore return as quickly as possible without blocking. 13 | * 14 | * @param event 15 | */ 16 | public void onEvent(EurekaEvent event); 17 | } 18 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/EurekaIdentityHeaderFilter.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import com.netflix.appinfo.AbstractEurekaIdentity; 4 | import com.sun.jersey.api.client.ClientHandlerException; 5 | import com.sun.jersey.api.client.ClientRequest; 6 | import com.sun.jersey.api.client.ClientResponse; 7 | import com.sun.jersey.api.client.filter.ClientFilter; 8 | 9 | public class EurekaIdentityHeaderFilter extends ClientFilter { 10 | 11 | private final AbstractEurekaIdentity authInfo; 12 | 13 | public EurekaIdentityHeaderFilter(AbstractEurekaIdentity authInfo) { 14 | this.authInfo = authInfo; 15 | } 16 | 17 | @Override 18 | public ClientResponse handle(ClientRequest cr) throws ClientHandlerException { 19 | if (authInfo != null) { 20 | cr.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_NAME_HEADER_KEY, authInfo.getName()); 21 | cr.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_VERSION_HEADER_KEY, authInfo.getVersion()); 22 | 23 | if (authInfo.getId() != null) { 24 | cr.getHeaders().putSingle(AbstractEurekaIdentity.AUTH_ID_HEADER_KEY, authInfo.getId()); 25 | } 26 | } 27 | return getNext().handle(cr); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/EurekaNamespace.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import com.google.inject.BindingAnnotation; 9 | 10 | @BindingAnnotation 11 | @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface EurekaNamespace { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/NotImplementedRegistryImpl.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import javax.inject.Singleton; 4 | 5 | import com.netflix.discovery.shared.Applications; 6 | 7 | /** 8 | * @author Nitesh Kant 9 | */ 10 | @Singleton 11 | public class NotImplementedRegistryImpl implements BackupRegistry { 12 | 13 | @Override 14 | public Applications fetchRegistry() { 15 | return null; 16 | } 17 | 18 | @Override 19 | public Applications fetchRegistry(String[] includeRemoteRegions) { 20 | return null; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/PreRegistrationHandler.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import com.netflix.appinfo.ApplicationInfoManager; 4 | 5 | /** 6 | * A handler that can be registered with an {@link EurekaClient} at creation time to execute 7 | * pre registration logic. The pre registration logic need to be synchronous to be guaranteed 8 | * to execute before registration. 9 | */ 10 | public interface PreRegistrationHandler { 11 | void beforeRegistration(); 12 | } 13 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/PropertyBasedAzToRegionMapper.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import java.util.Arrays; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | /** 8 | * @author Nitesh Kant 9 | */ 10 | public class PropertyBasedAzToRegionMapper extends AbstractAzToRegionMapper { 11 | 12 | public PropertyBasedAzToRegionMapper(EurekaClientConfig clientConfig) { 13 | super(clientConfig); 14 | } 15 | 16 | @Override 17 | protected Set getZonesForARegion(String region) { 18 | return new HashSet(Arrays.asList(clientConfig.getAvailabilityZones(region))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/StatusChangeEvent.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | 5 | /** 6 | * Event containing the latest instance status information. This event 7 | * is sent to the {@link com.netflix.eventbus.spi.EventBus} by {@link EurekaClient) whenever 8 | * a status change is identified from the remote Eureka server response. 9 | */ 10 | public class StatusChangeEvent extends DiscoveryEvent { 11 | private final InstanceInfo.InstanceStatus current; 12 | private final InstanceInfo.InstanceStatus previous; 13 | 14 | public StatusChangeEvent(InstanceInfo.InstanceStatus previous, InstanceInfo.InstanceStatus current) { 15 | super(); 16 | this.current = current; 17 | this.previous = previous; 18 | } 19 | 20 | /** 21 | * Return the up current when the event was generated. 22 | * @return true if current is up or false for ALL other current values 23 | */ 24 | public boolean isUp() { 25 | return this.current.equals(InstanceInfo.InstanceStatus.UP); 26 | } 27 | 28 | /** 29 | * @return The current at the time the event is generated. 30 | */ 31 | public InstanceInfo.InstanceStatus getStatus() { 32 | return current; 33 | } 34 | 35 | /** 36 | * @return Return the client status immediately before the change 37 | */ 38 | public InstanceInfo.InstanceStatus getPreviousStatus() { 39 | return previous; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return "StatusChangeEvent [timestamp=" + getTimestamp() + ", current=" + current + ", previous=" 45 | + previous + "]"; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/Auto.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.converters; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * A field annotation which helps in avoiding changes to 26 | * {@link com.netflix.discovery.converters.Converters.InstanceInfoConverter} every time additional fields are added to 27 | * {@link com.netflix.appinfo.InstanceInfo}. 28 | * 29 | *

30 | * This annotation informs the {@link com.netflix.discovery.converters.Converters.InstanceInfoConverter} to 31 | * automatically marshall most primitive fields declared in the {@link com.netflix.appinfo.InstanceInfo} class. 32 | *

33 | * 34 | * @author Karthik Ranganathan 35 | * 36 | */ 37 | @Retention(RetentionPolicy.RUNTIME) 38 | @Target({ElementType.FIELD}) 39 | public @interface Auto { 40 | } 41 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/KeyFormatter.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters; 2 | 3 | import javax.inject.Inject; 4 | import javax.inject.Singleton; 5 | 6 | import com.netflix.discovery.EurekaClientConfig; 7 | 8 | /** 9 | * Due to backwards compatibility some names in JSON/XML documents have to be formatted 10 | * according to a given configuration rules. The formatting functionality is provided by this class. 11 | * 12 | * @author Tomasz Bak 13 | */ 14 | @Singleton 15 | public class KeyFormatter { 16 | 17 | public static final String DEFAULT_REPLACEMENT = "__"; 18 | 19 | private static final KeyFormatter DEFAULT_KEY_FORMATTER = new KeyFormatter(DEFAULT_REPLACEMENT); 20 | 21 | private final String replacement; 22 | 23 | public KeyFormatter(String replacement) { 24 | this.replacement = replacement; 25 | } 26 | 27 | @Inject 28 | public KeyFormatter(EurekaClientConfig eurekaClientConfig) { 29 | if (eurekaClientConfig == null) { 30 | this.replacement = DEFAULT_REPLACEMENT; 31 | } else { 32 | this.replacement = eurekaClientConfig.getEscapeCharReplacement(); 33 | } 34 | } 35 | 36 | public String formatKey(String keyTemplate) { 37 | StringBuilder sb = new StringBuilder(keyTemplate.length() + 1); 38 | for (char c : keyTemplate.toCharArray()) { 39 | if (c == '_') { 40 | sb.append(replacement); 41 | } else { 42 | sb.append(c); 43 | } 44 | } 45 | return sb.toString(); 46 | } 47 | 48 | public static KeyFormatter defaultKeyFormatter() { 49 | return DEFAULT_KEY_FORMATTER; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/DataCenterTypeInfoResolver.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.jackson; 2 | 3 | import com.fasterxml.jackson.databind.DatabindContext; 4 | import com.fasterxml.jackson.databind.JavaType; 5 | import com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver; 6 | import com.fasterxml.jackson.databind.type.TypeFactory; 7 | import com.netflix.appinfo.AmazonInfo; 8 | import com.netflix.appinfo.DataCenterInfo; 9 | import com.netflix.appinfo.MyDataCenterInfo; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * @author Tomasz Bak 15 | */ 16 | public class DataCenterTypeInfoResolver extends ClassNameIdResolver { 17 | 18 | /** 19 | * This phantom class name is kept for backwards compatibility. Internally it is mapped to 20 | * {@link MyDataCenterInfo} during the deserialization process. 21 | */ 22 | public static final String MY_DATA_CENTER_INFO_TYPE_MARKER = "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"; 23 | 24 | public DataCenterTypeInfoResolver() { 25 | super(TypeFactory.defaultInstance().constructType(DataCenterInfo.class), TypeFactory.defaultInstance()); 26 | } 27 | 28 | @Override 29 | public JavaType typeFromId(DatabindContext context, String id) throws IOException { 30 | if (MY_DATA_CENTER_INFO_TYPE_MARKER.equals(id)) { 31 | return context.getTypeFactory().constructType(MyDataCenterInfo.class); 32 | } 33 | return super.typeFromId(context, id); 34 | } 35 | 36 | @Override 37 | public String idFromValue(Object value) { 38 | if (value.getClass().equals(AmazonInfo.class)) { 39 | return AmazonInfo.class.getName(); 40 | } 41 | return MY_DATA_CENTER_INFO_TYPE_MARKER; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/EurekaJacksonJsonModifiers.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.jackson; 2 | 3 | import com.fasterxml.jackson.databind.BeanDescription; 4 | import com.fasterxml.jackson.databind.JsonSerializer; 5 | import com.fasterxml.jackson.databind.SerializationConfig; 6 | import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; 7 | import com.fasterxml.jackson.databind.ser.std.BeanSerializerBase; 8 | import com.netflix.appinfo.InstanceInfo; 9 | import com.netflix.discovery.converters.KeyFormatter; 10 | import com.netflix.discovery.converters.jackson.serializer.ApplicationsJsonBeanSerializer; 11 | import com.netflix.discovery.converters.jackson.serializer.InstanceInfoJsonBeanSerializer; 12 | import com.netflix.discovery.shared.Applications; 13 | 14 | /** 15 | * @author Tomasz Bak 16 | */ 17 | final class EurekaJacksonJsonModifiers { 18 | 19 | private EurekaJacksonJsonModifiers() { 20 | } 21 | 22 | public static BeanSerializerModifier createJsonSerializerModifier(final KeyFormatter keyFormatter, final boolean compactMode) { 23 | return new BeanSerializerModifier() { 24 | @Override 25 | public JsonSerializer modifySerializer(SerializationConfig config, 26 | BeanDescription beanDesc, JsonSerializer serializer) { 27 | if (beanDesc.getBeanClass().isAssignableFrom(Applications.class)) { 28 | return new ApplicationsJsonBeanSerializer((BeanSerializerBase) serializer, keyFormatter); 29 | } 30 | if (beanDesc.getBeanClass().isAssignableFrom(InstanceInfo.class)) { 31 | return new InstanceInfoJsonBeanSerializer((BeanSerializerBase) serializer, compactMode); 32 | } 33 | return serializer; 34 | } 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/builder/ApplicationsXmlJacksonBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.converters.jackson.builder; 18 | 19 | import java.util.List; 20 | 21 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; 22 | import com.netflix.discovery.shared.Application; 23 | 24 | /** 25 | * Add XML specific annotation to {@link ApplicationsJacksonBuilder}. 26 | */ 27 | public class ApplicationsXmlJacksonBuilder extends ApplicationsJacksonBuilder { 28 | 29 | @Override 30 | @JacksonXmlElementWrapper(useWrapping = false) 31 | public void withApplication(List applications) { 32 | super.withApplication(applications); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/mixin/ApplicationXmlMixIn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.converters.jackson.mixin; 18 | 19 | import java.util.List; 20 | 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 23 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; 24 | import com.netflix.appinfo.InstanceInfo; 25 | import com.netflix.discovery.converters.jackson.serializer.ApplicationXmlDeserializer; 26 | 27 | /** 28 | * {@link InstanceInfo} objects are unwrapped in XML document. The necessary Jackson instrumentation is provided here. 29 | */ 30 | @JsonDeserialize(using = ApplicationXmlDeserializer.class) 31 | public interface ApplicationXmlMixIn { 32 | 33 | @JacksonXmlElementWrapper(useWrapping = false) 34 | @JsonProperty("instance") 35 | List getInstances(); 36 | } 37 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/mixin/ApplicationsJsonMixIn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.converters.jackson.mixin; 18 | 19 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 20 | import com.netflix.discovery.converters.jackson.builder.ApplicationsJacksonBuilder; 21 | 22 | /** 23 | * Attach custom builder that deals with configurable property name formatting. 24 | */ 25 | @JsonDeserialize(builder = ApplicationsJacksonBuilder.class) 26 | public class ApplicationsJsonMixIn { 27 | } 28 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/mixin/ApplicationsXmlMixIn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.converters.jackson.mixin; 18 | 19 | import java.util.List; 20 | 21 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 22 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; 23 | import com.netflix.discovery.converters.jackson.builder.ApplicationsXmlJacksonBuilder; 24 | import com.netflix.discovery.shared.Application; 25 | 26 | /** 27 | * Attach custom builder that deals with configurable property name formatting. 28 | * {@link Application} objects are unwrapped in XML document. The necessary Jackson instrumentation is provided here. 29 | */ 30 | @JsonDeserialize(builder = ApplicationsXmlJacksonBuilder.class) 31 | public interface ApplicationsXmlMixIn { 32 | 33 | @JacksonXmlElementWrapper(useWrapping = false) 34 | List getRegisteredApplications(); 35 | } 36 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/mixin/DataCenterInfoXmlMixIn.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.jackson.mixin; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo.As; 5 | 6 | /** 7 | * @author Tomasz Bak 8 | */ 9 | @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "class") 10 | public interface DataCenterInfoXmlMixIn { 11 | } 12 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/mixin/InstanceInfoJsonMixIn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.converters.jackson.mixin; 18 | 19 | import java.util.Map; 20 | 21 | import com.fasterxml.jackson.annotation.JsonIgnore; 22 | import com.netflix.discovery.converters.jackson.serializer.InstanceInfoJsonBeanSerializer; 23 | 24 | /** 25 | * Meta data are handled directly by {@link InstanceInfoJsonBeanSerializer}, for backwards compatibility reasons. 26 | */ 27 | public interface InstanceInfoJsonMixIn { 28 | 29 | @JsonIgnore 30 | Map getMetadata(); 31 | } 32 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/mixin/MiniInstanceInfoMixIn.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.jackson.mixin; 2 | 3 | import java.util.Map; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnore; 6 | import com.netflix.appinfo.InstanceInfo.InstanceStatus; 7 | import com.netflix.appinfo.LeaseInfo; 8 | 9 | /** 10 | * @author Tomasz Bak 11 | */ 12 | public interface MiniInstanceInfoMixIn { 13 | 14 | // define fields are are ignored for mini-InstanceInfo 15 | @JsonIgnore 16 | String getAppGroupName(); 17 | 18 | @JsonIgnore 19 | InstanceStatus getOverriddenStatus(); 20 | 21 | @JsonIgnore 22 | String getSID(); 23 | 24 | @JsonIgnore 25 | int getCountryId(); 26 | 27 | @JsonIgnore 28 | String getHomePageUrl(); 29 | 30 | @JsonIgnore 31 | String getStatusPageUrl(); 32 | 33 | @JsonIgnore 34 | String getHealthCheckUrl(); 35 | 36 | @JsonIgnore 37 | String getSecureHealthCheckUrl(); 38 | 39 | @JsonIgnore 40 | boolean isCoordinatingDiscoveryServer(); 41 | 42 | @JsonIgnore 43 | Long getLastDirtyTimestamp(); 44 | 45 | @JsonIgnore 46 | LeaseInfo getLeaseInfo(); 47 | 48 | @JsonIgnore 49 | Map getMetadata(); 50 | } 51 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/jackson/mixin/PortWrapperXmlMixIn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.converters.jackson.mixin; 18 | 19 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 20 | import com.netflix.discovery.converters.jackson.serializer.PortWrapperXmlDeserializer; 21 | 22 | /** 23 | * Add custom XML deserializer, due to issue with annotations based mapping in some Jackson versions. 24 | */ 25 | @JsonDeserialize(using = PortWrapperXmlDeserializer.class) 26 | public interface PortWrapperXmlMixIn { 27 | } 28 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/wrappers/CodecWrapper.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.wrappers; 2 | 3 | /** 4 | * Interface for more useable reference 5 | * 6 | * @author David Liu 7 | */ 8 | public interface CodecWrapper extends EncoderWrapper, DecoderWrapper { 9 | } 10 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/wrappers/CodecWrapperBase.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.wrappers; 2 | 3 | import javax.ws.rs.core.MediaType; 4 | 5 | /** 6 | * @author David Liu 7 | */ 8 | public interface CodecWrapperBase { 9 | 10 | String codecName(); 11 | 12 | boolean support(MediaType mediaType); 13 | } 14 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/wrappers/DecoderWrapper.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.wrappers; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * @author David Liu 8 | */ 9 | public interface DecoderWrapper extends CodecWrapperBase { 10 | 11 | T decode(String textValue, Class type) throws IOException; 12 | 13 | T decode(InputStream inputStream, Class type) throws IOException; 14 | } 15 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/converters/wrappers/EncoderWrapper.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.wrappers; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | /** 7 | * @author David Liu 8 | */ 9 | public interface EncoderWrapper extends CodecWrapperBase { 10 | String encode(T object) throws IOException; 11 | 12 | void encode(T object, OutputStream outputStream) throws IOException; 13 | } 14 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/internal/util/AmazonInfoUtils.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.internal.util; 2 | 3 | import com.netflix.appinfo.AmazonInfo.MetaDataKey; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.IOException; 7 | import java.io.InputStreamReader; 8 | import java.net.HttpURLConnection; 9 | import java.net.URL; 10 | 11 | /** 12 | * This is an INTERNAL class not for public use. 13 | * 14 | * @author David Liu 15 | */ 16 | public final class AmazonInfoUtils { 17 | 18 | public static String readEc2MetadataUrl(MetaDataKey metaDataKey, URL url, int connectionTimeoutMs, int readTimeoutMs) throws IOException { 19 | HttpURLConnection uc = (HttpURLConnection) url.openConnection(); 20 | uc.setConnectTimeout(connectionTimeoutMs); 21 | uc.setReadTimeout(readTimeoutMs); 22 | uc.setRequestProperty("User-Agent", "eureka-java-client"); 23 | 24 | if (uc.getResponseCode() != HttpURLConnection.HTTP_OK) { // need to read the error for clean connection close 25 | BufferedReader br = new BufferedReader(new InputStreamReader(uc.getErrorStream())); 26 | try { 27 | while (br.readLine() != null) { 28 | // do nothing but keep reading the line 29 | } 30 | } finally { 31 | br.close(); 32 | } 33 | } else { 34 | return metaDataKey.read(uc.getInputStream()); 35 | } 36 | 37 | return null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/internal/util/Archaius1Utils.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.internal.util; 2 | 3 | import com.netflix.config.ConfigurationManager; 4 | import com.netflix.config.DynamicPropertyFactory; 5 | import com.netflix.config.DynamicStringProperty; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.io.IOException; 10 | 11 | /** 12 | * This is an INTERNAL class not for public use. 13 | * 14 | * @author David Liu 15 | */ 16 | public final class Archaius1Utils { 17 | 18 | private static final Logger logger = LoggerFactory.getLogger(Archaius1Utils.class); 19 | 20 | private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; 21 | private static final String EUREKA_ENVIRONMENT = "eureka.environment"; 22 | 23 | public static DynamicPropertyFactory initConfig(String configName) { 24 | 25 | DynamicPropertyFactory configInstance = DynamicPropertyFactory.getInstance(); 26 | DynamicStringProperty EUREKA_PROPS_FILE = configInstance.getStringProperty("eureka.client.props", configName); 27 | 28 | String env = ConfigurationManager.getConfigInstance().getString(EUREKA_ENVIRONMENT, "test"); 29 | ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, env); 30 | 31 | String eurekaPropsFile = EUREKA_PROPS_FILE.get(); 32 | try { 33 | ConfigurationManager.loadCascadedPropertiesFromResources(eurekaPropsFile); 34 | } catch (IOException e) { 35 | logger.warn( 36 | "Cannot find the properties specified : {}. This may be okay if there are other environment " 37 | + "specific properties or the configuration is installed with a different mechanism.", 38 | eurekaPropsFile); 39 | 40 | } 41 | 42 | return configInstance; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/provider/ISerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.provider; 18 | 19 | import javax.ws.rs.core.MediaType; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.io.OutputStream; 23 | 24 | /** 25 | * A contract for dispatching to a custom serialization/de-serialization mechanism from jersey. 26 | * 27 | * @author Karthik Ranganathan 28 | * 29 | */ 30 | public interface ISerializer { 31 | 32 | Object read(InputStream is, Class type, MediaType mediaType) throws IOException; 33 | 34 | void write(Object object, OutputStream os, MediaType mediaType) throws IOException; 35 | } 36 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/provider/Serializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.discovery.provider; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * 26 | * An annotation that helps in specifying the custom serializer/de-serialization 27 | * implementation for jersey. 28 | * 29 | *

30 | * Once the annotation is specified, a custom jersey provider invokes an 31 | * instance of the class specified as the value and dispatches all objects that 32 | * needs to be serialized/de-serialized to handle them as and only when it is 33 | * responsible for handling those. 34 | *

35 | * 36 | * @author Karthik Ranganathan 37 | * 38 | */ 39 | @Documented 40 | @Target({ElementType.TYPE, ElementType.METHOD}) 41 | @Retention(RetentionPolicy.RUNTIME) 42 | public @interface Serializer { 43 | String value() default ""; 44 | } 45 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/providers/DefaultEurekaClientConfigProvider.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.providers; 2 | 3 | import javax.inject.Provider; 4 | 5 | import com.google.inject.Inject; 6 | import com.netflix.discovery.DefaultEurekaClientConfig; 7 | import com.netflix.discovery.DiscoveryManager; 8 | import com.netflix.discovery.EurekaClientConfig; 9 | import com.netflix.discovery.EurekaNamespace; 10 | 11 | /** 12 | * This provider is necessary because the namespace is optional. 13 | * @author elandau 14 | */ 15 | public class DefaultEurekaClientConfigProvider implements Provider { 16 | 17 | @Inject(optional = true) 18 | @EurekaNamespace 19 | private String namespace; 20 | 21 | private DefaultEurekaClientConfig config; 22 | 23 | @Override 24 | public synchronized EurekaClientConfig get() { 25 | if (config == null) { 26 | config = (namespace == null) 27 | ? new DefaultEurekaClientConfig() 28 | : new DefaultEurekaClientConfig(namespace); 29 | 30 | // TODO: Remove this when DiscoveryManager is finally no longer used 31 | DiscoveryManager.getInstance().setEurekaClientConfig(config); 32 | } 33 | 34 | return config; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/Pair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared; 18 | 19 | /** 20 | * An utility class for stores any information that needs to exist as a pair. 21 | * 22 | * @author Karthik Ranganathan 23 | * 24 | * @param Generics indicating the type information for the first one in the pair. 25 | * @param Generics indicating the type information for the second one in the pair. 26 | */ 27 | public class Pair { 28 | public E1 first() { 29 | return first; 30 | } 31 | 32 | public void setFirst(E1 first) { 33 | this.first = first; 34 | } 35 | 36 | public E2 second() { 37 | return second; 38 | } 39 | 40 | public void setSecond(E2 second) { 41 | this.second = second; 42 | } 43 | 44 | private E1 first; 45 | private E2 second; 46 | 47 | public Pair(E1 first, E2 second) { 48 | this.first = first; 49 | this.second = second; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/dns/DnsService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.dns; 18 | 19 | import javax.annotation.Nullable; 20 | import java.util.List; 21 | 22 | /** 23 | * @author Tomasz Bak 24 | */ 25 | public interface DnsService { 26 | 27 | /** 28 | * Resolve host name to the bottom A-Record or the latest available CNAME 29 | * 30 | * @return IP address 31 | */ 32 | String resolveIp(String hostName); 33 | 34 | /** 35 | * Resolve A-record entry for a given domain name. 36 | */ 37 | @Nullable 38 | List resolveARecord(String rootDomainName); 39 | } -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/dns/DnsServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.dns; 18 | 19 | import javax.annotation.Nullable; 20 | import java.util.List; 21 | 22 | import com.netflix.discovery.endpoint.DnsResolver; 23 | 24 | /** 25 | * @author Tomasz Bak 26 | */ 27 | public class DnsServiceImpl implements DnsService { 28 | @Override 29 | public String resolveIp(String hostName) { 30 | return DnsResolver.resolve(hostName); 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public List resolveARecord(String rootDomainName) { 36 | return DnsResolver.resolveARecord(rootDomainName); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/resolver/ClosableResolver.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.resolver; 2 | 3 | /** 4 | * @author David Liu 5 | */ 6 | public interface ClosableResolver extends ClusterResolver { 7 | void shutdown(); 8 | } 9 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/resolver/ClusterResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.resolver; 18 | 19 | import java.util.List; 20 | 21 | /** 22 | * @author Tomasz Bak 23 | */ 24 | public interface ClusterResolver { 25 | 26 | String getRegion(); 27 | 28 | List getClusterEndpoints(); 29 | } 30 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/resolver/ClusterResolverException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.resolver; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public class ClusterResolverException extends RuntimeException { 23 | 24 | private static final long serialVersionUID = -3027237921418208925L; 25 | 26 | public ClusterResolverException(String message) { 27 | super(message); 28 | } 29 | 30 | public ClusterResolverException(String message, Throwable cause) { 31 | super(message, cause); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/resolver/ClusterResolverFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.resolver; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public interface ClusterResolverFactory { 23 | 24 | ClusterResolver createClusterResolver(); 25 | } 26 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/resolver/EndpointRandomizer.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.resolver; 2 | 3 | import java.util.List; 4 | 5 | public interface EndpointRandomizer { 6 | List randomize(List list); 7 | } 8 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/resolver/EurekaEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.resolver; 18 | 19 | public interface EurekaEndpoint extends Comparable { 20 | 21 | String getServiceUrl(); 22 | 23 | /** 24 | * @deprecated use {@link #getNetworkAddress()} 25 | */ 26 | @Deprecated 27 | String getHostName(); 28 | 29 | String getNetworkAddress(); 30 | 31 | int getPort(); 32 | 33 | boolean isSecure(); 34 | 35 | String getRelativeUri(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/resolver/README.md: -------------------------------------------------------------------------------- 1 | Much of the code in this package are still experimental and subject to major refactoring down the line. 2 | They should not be exposed through the normal eureka-client APIs, so use directly at your own risk. -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/EurekaHttpClient.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.appinfo.InstanceInfo.InstanceStatus; 5 | import com.netflix.discovery.shared.Application; 6 | import com.netflix.discovery.shared.Applications; 7 | 8 | /** 9 | * Low level Eureka HTTP client API. 10 | * 11 | * @author Tomasz Bak 12 | */ 13 | public interface EurekaHttpClient { 14 | 15 | EurekaHttpResponse register(InstanceInfo info); 16 | 17 | EurekaHttpResponse cancel(String appName, String id); 18 | 19 | EurekaHttpResponse sendHeartBeat(String appName, String id, InstanceInfo info, InstanceStatus overriddenStatus); 20 | 21 | EurekaHttpResponse statusUpdate(String appName, String id, InstanceStatus newStatus, InstanceInfo info); 22 | 23 | EurekaHttpResponse deleteStatusOverride(String appName, String id, InstanceInfo info); 24 | 25 | EurekaHttpResponse getApplications(String... regions); 26 | 27 | EurekaHttpResponse getDelta(String... regions); 28 | 29 | EurekaHttpResponse getVip(String vipAddress, String... regions); 30 | 31 | EurekaHttpResponse getSecureVip(String secureVipAddress, String... regions); 32 | 33 | EurekaHttpResponse getApplication(String appName); 34 | 35 | EurekaHttpResponse getInstance(String appName, String id); 36 | 37 | EurekaHttpResponse getInstance(String id); 38 | 39 | void shutdown(); 40 | } 41 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/EurekaHttpClientFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.transport; 18 | 19 | /** 20 | * A top level factory to create http clients for application/eurekaClient use 21 | * 22 | * @author Tomasz Bak 23 | */ 24 | public interface EurekaHttpClientFactory { 25 | 26 | EurekaHttpClient newClient(); 27 | 28 | void shutdown(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/PropertyBasedTransportConfigConstants.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport; 2 | 3 | /** 4 | * constants pertaining to property based transport configs 5 | * 6 | * @author David Liu 7 | */ 8 | final class PropertyBasedTransportConfigConstants { 9 | 10 | // NOTE: all keys are before any prefixes are applied 11 | static final String SESSION_RECONNECT_INTERVAL_KEY = "sessionedClientReconnectIntervalSeconds"; 12 | static final String QUARANTINE_REFRESH_PERCENTAGE_KEY = "retryableClientQuarantineRefreshPercentage"; 13 | static final String DATA_STALENESS_THRESHOLD_KEY = "applicationsResolverDataStalenessThresholdSeconds"; 14 | static final String APPLICATION_RESOLVER_USE_IP_KEY = "applicationsResolverUseIp"; 15 | static final String ASYNC_RESOLVER_REFRESH_INTERVAL_KEY = "asyncResolverRefreshIntervalMs"; 16 | static final String ASYNC_RESOLVER_WARMUP_TIMEOUT_KEY = "asyncResolverWarmupTimeoutMs"; 17 | static final String ASYNC_EXECUTOR_THREADPOOL_SIZE_KEY = "asyncExecutorThreadPoolSize"; 18 | static final String WRITE_CLUSTER_VIP_KEY = "writeClusterVip"; 19 | static final String READ_CLUSTER_VIP_KEY = "readClusterVip"; 20 | static final String BOOTSTRAP_RESOLVER_STRATEGY_KEY = "bootstrapResolverStrategy"; 21 | static final String USE_BOOTSTRAP_RESOLVER_FOR_QUERY = "useBootstrapResolverForQuery"; 22 | 23 | static final String TRANSPORT_CONFIG_SUB_NAMESPACE = "transport"; 24 | 25 | 26 | static class Values { 27 | static final int SESSION_RECONNECT_INTERVAL = 20*60; 28 | static final double QUARANTINE_REFRESH_PERCENTAGE = 0.66; 29 | static final int DATA_STALENESS_TRHESHOLD = 5*60; 30 | static final int ASYNC_RESOLVER_REFRESH_INTERVAL = 5*60*1000; 31 | static final int ASYNC_RESOLVER_WARMUP_TIMEOUT = 5000; 32 | static final int ASYNC_EXECUTOR_THREADPOOL_SIZE = 5; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/README.md: -------------------------------------------------------------------------------- 1 | Much of the code in this package are still experimental and subject to major refactoring down the line. 2 | They should not be exposed through the normal eureka-client APIs, so use directly at your own risk. -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/TransportClientFactory.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport; 2 | 3 | import com.netflix.discovery.shared.resolver.EurekaEndpoint; 4 | 5 | /** 6 | * A low level client factory interface. Not advised to be used by top level consumers. 7 | * 8 | * @author David Liu 9 | */ 10 | public interface TransportClientFactory { 11 | 12 | EurekaHttpClient newClient(EurekaEndpoint serviceUrl); 13 | 14 | void shutdown(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/TransportException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.transport; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public class TransportException extends RuntimeException { 23 | public TransportException(String message) { 24 | super(message); 25 | } 26 | 27 | public TransportException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/TransportUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.transport; 18 | 19 | import java.util.concurrent.atomic.AtomicReference; 20 | 21 | /** 22 | * @author Tomasz Bak 23 | */ 24 | public final class TransportUtils { 25 | 26 | private TransportUtils() { 27 | } 28 | 29 | public static EurekaHttpClient getOrSetAnotherClient(AtomicReference eurekaHttpClientRef, EurekaHttpClient another) { 30 | EurekaHttpClient existing = eurekaHttpClientRef.get(); 31 | if (eurekaHttpClientRef.compareAndSet(null, another)) { 32 | return another; 33 | } 34 | another.shutdown(); 35 | return existing; 36 | } 37 | 38 | public static void shutdown(EurekaHttpClient eurekaHttpClient) { 39 | if (eurekaHttpClient != null) { 40 | eurekaHttpClient.shutdown(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/ServerStatusEvaluator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.transport.decorator; 18 | 19 | import com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.RequestType; 20 | 21 | /** 22 | * HTTP status code evaluator, that can be used to make a decision whether it makes sense to 23 | * immediately retry a request on another server or stick to the current one. 24 | * Registration requests are critical to complete as soon as possible, so any server error should be followed 25 | * by retry on another one. Registry fetch/delta fetch should stick to the same server, to avoid delta hash code 26 | * mismatches. See https://github.com/Netflix/eureka/issues/628. 27 | * 28 | * @author Tomasz Bak 29 | */ 30 | public interface ServerStatusEvaluator { 31 | boolean accept(int statusCode, RequestType requestType); 32 | } 33 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/jersey/EurekaJerseyClient.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport.jersey; 2 | 3 | import com.sun.jersey.client.apache4.ApacheHttpClient4; 4 | 5 | /** 6 | * @author David Liu 7 | */ 8 | public interface EurekaJerseyClient { 9 | 10 | ApacheHttpClient4 getClient(); 11 | 12 | /** 13 | * Clean up resources. 14 | */ 15 | void destroyResources(); 16 | } 17 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/jersey/Jersey1DiscoveryClientOptionalArgs.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport.jersey; 2 | 3 | import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs; 4 | import com.sun.jersey.api.client.filter.ClientFilter; 5 | 6 | /** 7 | * Jersey1 implementation of DiscoveryClientOptionalArg. 8 | * 9 | * @author Matt Nelson 10 | */ 11 | public class Jersey1DiscoveryClientOptionalArgs extends AbstractDiscoveryClientOptionalArgs { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/jersey/JerseyApplicationClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.transport.jersey; 18 | 19 | import com.netflix.discovery.shared.transport.EurekaHttpClient; 20 | import com.sun.jersey.api.client.Client; 21 | import com.sun.jersey.api.client.WebResource.Builder; 22 | 23 | import java.util.Map; 24 | 25 | /** 26 | * A version of Jersey1 {@link EurekaHttpClient} to be used by applications. 27 | * 28 | * @author Tomasz Bak 29 | */ 30 | public class JerseyApplicationClient extends AbstractJerseyEurekaHttpClient { 31 | 32 | private final Map additionalHeaders; 33 | 34 | public JerseyApplicationClient(Client jerseyClient, String serviceUrl, Map additionalHeaders) { 35 | super(jerseyClient, serviceUrl); 36 | this.additionalHeaders = additionalHeaders; 37 | } 38 | 39 | @Override 40 | protected void addExtraHeaders(Builder webResource) { 41 | if (additionalHeaders != null) { 42 | for (Map.Entry entry : additionalHeaders.entrySet()) { 43 | webResource.header(entry.getKey(), entry.getValue()); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/shared/transport/jersey/TransportClientFactories.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.transport.jersey; 2 | 3 | import java.util.Collection; 4 | import java.util.Optional; 5 | 6 | import javax.net.ssl.HostnameVerifier; 7 | import javax.net.ssl.SSLContext; 8 | 9 | import com.netflix.appinfo.InstanceInfo; 10 | import com.netflix.discovery.EurekaClientConfig; 11 | import com.netflix.discovery.shared.transport.TransportClientFactory; 12 | 13 | public interface TransportClientFactories { 14 | 15 | @Deprecated 16 | public TransportClientFactory newTransportClientFactory(final Collection additionalFilters, 17 | final EurekaJerseyClient providedJerseyClient); 18 | 19 | public TransportClientFactory newTransportClientFactory(final EurekaClientConfig clientConfig, 20 | final Collection additionalFilters, 21 | final InstanceInfo myInstanceInfo); 22 | 23 | public TransportClientFactory newTransportClientFactory(final EurekaClientConfig clientConfig, 24 | final Collection additionalFilters, 25 | final InstanceInfo myInstanceInfo, 26 | final Optional sslContext, 27 | final Optional hostnameVerifier); 28 | } -------------------------------------------------------------------------------- /eureka-client/src/main/java/com/netflix/discovery/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.util; 18 | 19 | public final class StringUtil { 20 | 21 | private StringUtil() { 22 | } 23 | 24 | /** 25 | * Join all values separating them with a comma. 26 | */ 27 | public static String join(String... values) { 28 | if (values == null || values.length == 0) { 29 | return null; 30 | } 31 | StringBuilder sb = new StringBuilder(); 32 | for (String value : values) { 33 | sb.append(',').append(value); 34 | } 35 | return sb.substring(1); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/AbstractDiscoveryClientTester.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import com.netflix.discovery.junit.resource.DiscoveryClientResource; 4 | import org.junit.After; 5 | import org.junit.Before; 6 | 7 | /** 8 | * @author Nitesh Kant 9 | */ 10 | public abstract class AbstractDiscoveryClientTester extends BaseDiscoveryClientTester { 11 | 12 | @Before 13 | public void setUp() throws Exception { 14 | 15 | setupProperties(); 16 | 17 | populateLocalRegistryAtStartup(); 18 | populateRemoteRegistryAtStartup(); 19 | 20 | setupDiscoveryClient(); 21 | } 22 | 23 | @After 24 | public void tearDown() throws Exception { 25 | shutdownDiscoveryClient(); 26 | DiscoveryClientResource.clearDiscoveryClientConfig(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/DiscoveryClientCloseJerseyThreadTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import java.util.Set; 4 | import org.junit.Test; 5 | 6 | import static org.hamcrest.CoreMatchers.equalTo; 7 | import static org.junit.Assert.assertThat; 8 | 9 | public class DiscoveryClientCloseJerseyThreadTest extends AbstractDiscoveryClientTester { 10 | 11 | private static final String JERSEY_THREAD_NAME = "Eureka-JerseyClient-Conn-Cleaner"; 12 | private static final String APACHE_THREAD_NAME = "Apache-HttpClient-Conn-Cleaner"; 13 | 14 | @Test 15 | public void testThreadCount() throws InterruptedException { 16 | assertThat(containsClientThread(), equalTo(true)); 17 | client.shutdown(); 18 | // Give up control for cleaner thread to die 19 | Thread.sleep(5); 20 | assertThat(containsClientThread(), equalTo(false)); 21 | } 22 | 23 | private boolean containsClientThread() { 24 | Set threads = Thread.getAllStackTraces().keySet(); 25 | for (Thread t : threads) { 26 | if (t.getName().contains(JERSEY_THREAD_NAME) || t.getName().contains(APACHE_THREAD_NAME)) { 27 | return true; 28 | } 29 | } 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/DiscoveryClientDisableRegistryTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import java.util.UUID; 4 | 5 | import com.netflix.appinfo.ApplicationInfoManager; 6 | import com.netflix.appinfo.DataCenterInfo; 7 | import com.netflix.appinfo.InstanceInfo; 8 | import com.netflix.appinfo.MyDataCenterInstanceConfig; 9 | import com.netflix.config.ConfigurationManager; 10 | import org.junit.Assert; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | 14 | /** 15 | * @author Nitesh Kant 16 | */ 17 | public class DiscoveryClientDisableRegistryTest { 18 | 19 | private EurekaClient client; 20 | private MockRemoteEurekaServer mockLocalEurekaServer; 21 | 22 | @Before 23 | public void setUp() throws Exception { 24 | mockLocalEurekaServer = new MockRemoteEurekaServer(); 25 | mockLocalEurekaServer.start(); 26 | 27 | ConfigurationManager.getConfigInstance().setProperty("eureka.registration.enabled", "false"); 28 | ConfigurationManager.getConfigInstance().setProperty("eureka.shouldFetchRegistry", "false"); 29 | ConfigurationManager.getConfigInstance().setProperty("eureka.serviceUrl.default", 30 | "http://localhost:" + mockLocalEurekaServer.getPort() + 31 | MockRemoteEurekaServer.EUREKA_API_BASE_PATH); 32 | 33 | InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); 34 | builder.setIPAddr("10.10.101.00"); 35 | builder.setHostName("Hosttt"); 36 | builder.setAppName("EurekaTestApp-" + UUID.randomUUID()); 37 | builder.setDataCenterInfo(new DataCenterInfo() { 38 | @Override 39 | public Name getName() { 40 | return Name.MyOwn; 41 | } 42 | }); 43 | 44 | ApplicationInfoManager applicationInfoManager = new ApplicationInfoManager(new MyDataCenterInstanceConfig(), builder.build()); 45 | client = new DiscoveryClient(applicationInfoManager, new DefaultEurekaClientConfig()); 46 | } 47 | 48 | @Test 49 | public void testDisableFetchRegistry() throws Exception { 50 | Assert.assertFalse("Registry fetch disabled but eureka server recieved a registry fetch.", 51 | mockLocalEurekaServer.isSentRegistry()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/DiscoveryClientStatsInitFailedTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import com.netflix.discovery.junit.resource.DiscoveryClientResource; 4 | import org.junit.After; 5 | import org.junit.Assert; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | /** 10 | * Tests for DiscoveryClient stats reported when initial registry fetch fails. 11 | */ 12 | public class DiscoveryClientStatsInitFailedTest extends BaseDiscoveryClientTester { 13 | 14 | @Before 15 | public void setUp() throws Exception { 16 | setupProperties(); 17 | populateRemoteRegistryAtStartup(); 18 | setupDiscoveryClient(); 19 | } 20 | 21 | @After 22 | public void tearDown() throws Exception { 23 | shutdownDiscoveryClient(); 24 | DiscoveryClientResource.clearDiscoveryClientConfig(); 25 | } 26 | 27 | @Test 28 | public void testEmptyInitLocalRegistrySize() throws Exception { 29 | Assert.assertTrue(client instanceof DiscoveryClient); 30 | DiscoveryClient clientImpl = (DiscoveryClient) client; 31 | Assert.assertEquals(0, clientImpl.getStats().initLocalRegistrySize()); 32 | } 33 | 34 | @Test 35 | public void testInitFailed() throws Exception { 36 | Assert.assertTrue(client instanceof DiscoveryClient); 37 | DiscoveryClient clientImpl = (DiscoveryClient) client; 38 | Assert.assertFalse(clientImpl.getStats().initSucceeded()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/DiscoveryClientStatsTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | /** 7 | * Tests for DiscoveryClient stats reported when initial registry fetch succeeds. 8 | */ 9 | public class DiscoveryClientStatsTest extends AbstractDiscoveryClientTester { 10 | 11 | @Test 12 | public void testNonEmptyInitLocalRegistrySize() throws Exception { 13 | Assert.assertTrue(client instanceof DiscoveryClient); 14 | DiscoveryClient clientImpl = (DiscoveryClient) client; 15 | Assert.assertEquals(createLocalApps().size(), clientImpl.getStats().initLocalRegistrySize()); 16 | } 17 | 18 | @Test 19 | public void testInitSucceeded() throws Exception { 20 | Assert.assertTrue(client instanceof DiscoveryClient); 21 | DiscoveryClient clientImpl = (DiscoveryClient) client; 22 | Assert.assertTrue(clientImpl.getStats().initSucceeded()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/Jersey1DiscoveryClientOptionalArgsTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import javax.inject.Provider; 4 | 5 | import com.netflix.discovery.shared.transport.jersey.Jersey1DiscoveryClientOptionalArgs; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import com.netflix.appinfo.HealthCheckCallback; 10 | import com.netflix.appinfo.HealthCheckHandler; 11 | 12 | /** 13 | * @author Matt Nelson 14 | */ 15 | public class Jersey1DiscoveryClientOptionalArgsTest { 16 | 17 | private Jersey1DiscoveryClientOptionalArgs args; 18 | 19 | @Before 20 | public void before() { 21 | args = new Jersey1DiscoveryClientOptionalArgs(); 22 | } 23 | 24 | @Test 25 | public void testHealthCheckCallbackGuiceProvider() { 26 | args.setHealthCheckCallbackProvider(new GuiceProvider()); 27 | } 28 | 29 | @Test 30 | public void testHealthCheckCallbackJavaxProvider() { 31 | args.setHealthCheckCallbackProvider(new JavaxProvider()); 32 | } 33 | 34 | @Test 35 | public void testHealthCheckHandlerGuiceProvider() { 36 | args.setHealthCheckHandlerProvider(new GuiceProvider()); 37 | } 38 | 39 | @Test 40 | public void testHealthCheckHandlerJavaxProvider() { 41 | args.setHealthCheckHandlerProvider(new JavaxProvider()); 42 | } 43 | 44 | private class JavaxProvider implements Provider { 45 | @Override 46 | public T get() { 47 | return null; 48 | } 49 | } 50 | 51 | private class GuiceProvider implements com.google.inject.Provider { 52 | 53 | @Override 54 | public T get() { 55 | return null; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/MockBackupRegistry.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.google.inject.Singleton; 7 | import com.netflix.discovery.shared.Application; 8 | import com.netflix.discovery.shared.Applications; 9 | 10 | /** 11 | * @author Nitesh Kant 12 | */ 13 | @Singleton 14 | public class MockBackupRegistry implements BackupRegistry { 15 | 16 | private Map remoteRegionVsApps = new HashMap(); 17 | private Applications localRegionApps; 18 | 19 | @Override 20 | public Applications fetchRegistry() { 21 | if (null == localRegionApps) { 22 | return new Applications(); 23 | } 24 | return localRegionApps; 25 | } 26 | 27 | @Override 28 | public Applications fetchRegistry(String[] includeRemoteRegions) { 29 | Applications toReturn = new Applications(); 30 | for (Application application : localRegionApps.getRegisteredApplications()) { 31 | toReturn.addApplication(application); 32 | } 33 | for (String region : includeRemoteRegions) { 34 | Applications applications = remoteRegionVsApps.get(region); 35 | if (null != applications) { 36 | for (Application application : applications.getRegisteredApplications()) { 37 | toReturn.addApplication(application); 38 | } 39 | } 40 | } 41 | return toReturn; 42 | } 43 | 44 | public Applications getLocalRegionApps() { 45 | return localRegionApps; 46 | } 47 | 48 | public Map getRemoteRegionVsApps() { 49 | return remoteRegionVsApps; 50 | } 51 | 52 | public void setRemoteRegionVsApps(Map remoteRegionVsApps) { 53 | this.remoteRegionVsApps = remoteRegionVsApps; 54 | } 55 | 56 | public void setLocalRegionApps(Applications localRegionApps) { 57 | this.localRegionApps = localRegionApps; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/converters/EnumLookupTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class EnumLookupTest { 7 | 8 | enum TestEnum { 9 | VAL_ONE("one"), VAL_TWO("two"), VAL_THREE("three"); 10 | private final String name; 11 | 12 | private TestEnum(String name) { 13 | this.name = name; 14 | } 15 | } 16 | 17 | @Test 18 | public void testLookup() { 19 | EnumLookup lookup = new EnumLookup<>(TestEnum.class, v->v.name.toCharArray()); 20 | char[] buffer = "zeroonetwothreefour".toCharArray(); 21 | Assert.assertSame(TestEnum.VAL_ONE, lookup.find(buffer, 4, 3)); 22 | Assert.assertSame(TestEnum.VAL_TWO, lookup.find(buffer, 7, 3)); 23 | Assert.assertSame(TestEnum.VAL_THREE, lookup.find(buffer, 10, 5)); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/converters/JsonXStreamTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters; 2 | 3 | import static org.hamcrest.CoreMatchers.is; 4 | import static org.junit.Assert.assertThat; 5 | 6 | import com.thoughtworks.xstream.security.ForbiddenClassException; 7 | import org.junit.Test; 8 | 9 | import com.netflix.discovery.shared.Applications; 10 | import com.netflix.discovery.util.EurekaEntityComparators; 11 | import com.netflix.discovery.util.InstanceInfoGenerator; 12 | import com.thoughtworks.xstream.XStream; 13 | 14 | /** 15 | * @author Borja Lafuente 16 | */ 17 | public class JsonXStreamTest { 18 | 19 | @Test 20 | public void testEncodingDecodingWithoutMetaData() throws Exception { 21 | Applications applications = InstanceInfoGenerator.newBuilder(10, 2).withMetaData(false).build().toApplications(); 22 | 23 | XStream xstream = JsonXStream.getInstance(); 24 | String jsonDocument = xstream.toXML(applications); 25 | 26 | Applications decodedApplications = (Applications) xstream.fromXML(jsonDocument); 27 | 28 | assertThat(EurekaEntityComparators.equal(decodedApplications, applications), is(true)); 29 | } 30 | 31 | @Test 32 | public void testEncodingDecodingWithMetaData() throws Exception { 33 | Applications applications = InstanceInfoGenerator.newBuilder(10, 2).withMetaData(true).build().toApplications(); 34 | 35 | XStream xstream = JsonXStream.getInstance(); 36 | String jsonDocument = xstream.toXML(applications); 37 | 38 | Applications decodedApplications = (Applications) xstream.fromXML(jsonDocument); 39 | 40 | assertThat(EurekaEntityComparators.equal(decodedApplications, applications), is(true)); 41 | } 42 | 43 | /** 44 | * Tests: http://x-stream.github.io/CVE-2017-7957.html 45 | */ 46 | @Test(expected=ForbiddenClassException.class, timeout=5000) 47 | public void testVoidElementUnmarshalling() throws Exception { 48 | XStream xstream = JsonXStream.getInstance(); 49 | xstream.fromXML("{'void':null}"); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/converters/StringCacheTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters; 2 | 3 | import com.netflix.discovery.util.StringCache; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertTrue; 7 | 8 | /** 9 | * @author Tomasz Bak 10 | */ 11 | public class StringCacheTest { 12 | 13 | public static final int CACHE_SIZE = 100000; 14 | 15 | @Test 16 | public void testVerifyStringsAreGarbageCollectedIfNotReferenced() throws Exception { 17 | StringCache cache = new StringCache(); 18 | for (int i = 0; i < CACHE_SIZE; i++) { 19 | cache.cachedValueOf("id#" + i); 20 | } 21 | gc(); 22 | // Testing GC behavior is unpredictable, so we set here low target level 23 | // The tests run on desktop show that all strings are removed actually. 24 | assertTrue(cache.size() < CACHE_SIZE * 0.1); 25 | } 26 | 27 | public static void gc() { 28 | System.gc(); 29 | System.runFinalization(); 30 | try { 31 | Thread.sleep(1000); 32 | } catch (InterruptedException e) { 33 | // IGNORE 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/converters/wrappers/CodecWrappersTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.converters.wrappers; 2 | 3 | import junit.framework.Assert; 4 | import org.junit.Test; 5 | 6 | import javax.ws.rs.core.MediaType; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | 11 | /** 12 | * @author David Liu 13 | */ 14 | public class CodecWrappersTest { 15 | 16 | private static String testWrapperName = "FOO_WRAPPER"; 17 | 18 | @Test 19 | public void testRegisterNewWrapper() { 20 | Assert.assertNull(CodecWrappers.getEncoder(testWrapperName)); 21 | Assert.assertNull(CodecWrappers.getDecoder(testWrapperName)); 22 | 23 | CodecWrappers.registerWrapper(new TestWrapper()); 24 | 25 | Assert.assertNotNull(CodecWrappers.getEncoder(testWrapperName)); 26 | Assert.assertNotNull(CodecWrappers.getDecoder(testWrapperName)); 27 | } 28 | 29 | private final class TestWrapper implements CodecWrapper { 30 | 31 | @Override 32 | public T decode(String textValue, Class type) throws IOException { 33 | return null; 34 | } 35 | 36 | @Override 37 | public T decode(InputStream inputStream, Class type) throws IOException { 38 | return null; 39 | } 40 | 41 | @Override 42 | public String encode(T object) throws IOException { 43 | return null; 44 | } 45 | 46 | @Override 47 | public void encode(T object, OutputStream outputStream) throws IOException { 48 | 49 | } 50 | 51 | @Override 52 | public String codecName() { 53 | return testWrapperName; 54 | } 55 | 56 | @Override 57 | public boolean support(MediaType mediaType) { 58 | return false; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/shared/resolver/aws/TestEurekaHttpResolver.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.shared.resolver.aws; 2 | 3 | import com.netflix.discovery.EurekaClientConfig; 4 | import com.netflix.discovery.shared.transport.EurekaHttpClientFactory; 5 | import com.netflix.discovery.shared.transport.EurekaTransportConfig; 6 | 7 | /** 8 | * Used to expose test constructor to other packages 9 | * 10 | * @author David Liu 11 | */ 12 | public class TestEurekaHttpResolver extends EurekaHttpResolver { 13 | public TestEurekaHttpResolver(EurekaClientConfig clientConfig, EurekaTransportConfig transportConfig, EurekaHttpClientFactory clientFactory, String vipAddress) { 14 | super(clientConfig, transportConfig, clientFactory, vipAddress); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/shared/transport/jersey/JerseyApplicationClientTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.transport.jersey; 18 | 19 | import java.net.URI; 20 | 21 | import com.google.common.base.Preconditions; 22 | import com.netflix.discovery.shared.resolver.DefaultEndpoint; 23 | import com.netflix.discovery.shared.transport.EurekaHttpClient; 24 | import com.netflix.discovery.shared.transport.EurekaHttpClientCompatibilityTestSuite; 25 | import com.netflix.discovery.shared.transport.TransportClientFactory; 26 | import org.junit.After; 27 | 28 | public class JerseyApplicationClientTest extends EurekaHttpClientCompatibilityTestSuite { 29 | 30 | private JerseyApplicationClient jerseyHttpClient; 31 | 32 | @Override 33 | @After 34 | public void tearDown() throws Exception { 35 | if (jerseyHttpClient != null) { 36 | jerseyHttpClient.shutdown(); 37 | } 38 | super.tearDown(); 39 | } 40 | 41 | @Override 42 | protected EurekaHttpClient getEurekaHttpClient(URI serviceURI) { 43 | Preconditions.checkState(jerseyHttpClient == null, "EurekaHttpClient has been already created"); 44 | 45 | TransportClientFactory clientFactory = JerseyEurekaHttpClientFactory.newBuilder() 46 | .withClientName("compatibilityTestClient") 47 | .build(); 48 | jerseyHttpClient = (JerseyApplicationClient) clientFactory.newClient(new DefaultEndpoint(serviceURI.toString())); 49 | 50 | return jerseyHttpClient; 51 | } 52 | } -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/util/DiscoveryBuildInfoTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.util; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.junit.Test; 5 | 6 | import static org.hamcrest.CoreMatchers.is; 7 | import static org.junit.Assert.assertThat; 8 | 9 | /** 10 | * @author Tomasz Bak 11 | */ 12 | public class DiscoveryBuildInfoTest { 13 | 14 | @Test 15 | public void testRequestedManifestIsLocatedAndLoaded() throws Exception { 16 | DiscoveryBuildInfo buildInfo = new DiscoveryBuildInfo(ObjectMapper.class); 17 | assertThat(buildInfo.getBuildVersion().contains("version_unknown"), is(false)); 18 | } 19 | } -------------------------------------------------------------------------------- /eureka-client/src/test/java/com/netflix/discovery/util/EurekaUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.discovery.util; 2 | 3 | import com.netflix.appinfo.AmazonInfo; 4 | import com.netflix.appinfo.DataCenterInfo; 5 | import com.netflix.appinfo.InstanceInfo; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | 9 | /** 10 | * @author David Liu 11 | */ 12 | public class EurekaUtilsTest { 13 | @Test 14 | public void testIsInEc2() { 15 | InstanceInfo instanceInfo1 = new InstanceInfo.Builder(InstanceInfoGenerator.takeOne()) 16 | .setDataCenterInfo(new DataCenterInfo() { 17 | @Override 18 | public Name getName() { 19 | return Name.MyOwn; 20 | } 21 | }) 22 | .build(); 23 | 24 | Assert.assertFalse(EurekaUtils.isInEc2(instanceInfo1)); 25 | 26 | InstanceInfo instanceInfo2 = InstanceInfoGenerator.takeOne(); 27 | Assert.assertTrue(EurekaUtils.isInEc2(instanceInfo2)); 28 | } 29 | 30 | @Test 31 | public void testIsInVpc() { 32 | InstanceInfo instanceInfo1 = new InstanceInfo.Builder(InstanceInfoGenerator.takeOne()) 33 | .setDataCenterInfo(new DataCenterInfo() { 34 | @Override 35 | public Name getName() { 36 | return Name.MyOwn; 37 | } 38 | }) 39 | .build(); 40 | 41 | Assert.assertFalse(EurekaUtils.isInVpc(instanceInfo1)); 42 | 43 | InstanceInfo instanceInfo2 = InstanceInfoGenerator.takeOne(); 44 | Assert.assertFalse(EurekaUtils.isInVpc(instanceInfo2)); 45 | 46 | InstanceInfo instanceInfo3 = InstanceInfoGenerator.takeOne(); 47 | ((AmazonInfo) instanceInfo3.getDataCenterInfo()).getMetadata() 48 | .put(AmazonInfo.MetaDataKey.vpcId.getName(), "vpc-123456"); 49 | 50 | Assert.assertTrue(EurekaUtils.isInVpc(instanceInfo3)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /eureka-core-jersey2/README.md: -------------------------------------------------------------------------------- 1 | Please note that this jersey2 compatible Eureka core (eureka-core-jersey2) is created and maintained by the community. Netflix does not currently use this library internally. -------------------------------------------------------------------------------- /eureka-core-jersey2/build.gradle: -------------------------------------------------------------------------------- 1 | configurations.all { 2 | exclude module: 'jsr311-api' 3 | exclude group: 'com.sun.jersey' 4 | exclude group: 'com.sun.jersey.contribs' 5 | } 6 | 7 | dependencies { 8 | compile project(':eureka-core') 9 | compile project(':eureka-client-jersey2') 10 | compile 'org.glassfish.jersey.core:jersey-client:2.23.1' 11 | compile 'org.glassfish.jersey.connectors:jersey-apache-connector:2.23.1' 12 | 13 | testCompile (project(':eureka-test-utils')) { 14 | // exclude all transitives to avoid bringing in jersey1 eureka-core 15 | transitive = false 16 | } 17 | // bring in jersey2 compatible eureka-core-jersey2 directly 18 | testCompile project(':eureka-core-jersey2') 19 | 20 | testCompile "junit:junit:${junit_version}" 21 | testCompile "org.mock-server:mockserver-netty:${mockserverVersion}" 22 | testCompile "org.mockito:mockito-core:${mockitoVersion}" 23 | testRuntime 'org.slf4j:slf4j-simple:1.7.10' 24 | } 25 | -------------------------------------------------------------------------------- /eureka-core-jersey2/src/main/java/com/netflix/eureka/Jersey2EurekaBootStrap.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka; 2 | 3 | import com.netflix.appinfo.ApplicationInfoManager; 4 | import com.netflix.discovery.DiscoveryClient; 5 | import com.netflix.discovery.EurekaClientConfig; 6 | import com.netflix.eureka.cluster.Jersey2PeerEurekaNodes; 7 | import com.netflix.eureka.cluster.PeerEurekaNodes; 8 | import com.netflix.eureka.registry.PeerAwareInstanceRegistry; 9 | import com.netflix.eureka.resources.ServerCodecs; 10 | 11 | /** 12 | * Jersey2 eureka server bootstrapper 13 | * @author Matt Nelson 14 | */ 15 | public class Jersey2EurekaBootStrap extends EurekaBootStrap { 16 | 17 | public Jersey2EurekaBootStrap(DiscoveryClient discoveryClient) { 18 | super(discoveryClient); 19 | } 20 | 21 | @Override 22 | protected PeerEurekaNodes getPeerEurekaNodes(PeerAwareInstanceRegistry registry, EurekaServerConfig eurekaServerConfig, EurekaClientConfig eurekaClientConfig, ServerCodecs serverCodecs, ApplicationInfoManager applicationInfoManager) { 23 | PeerEurekaNodes peerEurekaNodes = new Jersey2PeerEurekaNodes( 24 | registry, 25 | eurekaServerConfig, 26 | eurekaClientConfig, 27 | serverCodecs, 28 | applicationInfoManager 29 | ); 30 | 31 | return peerEurekaNodes; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /eureka-core-jersey2/src/main/java/com/netflix/eureka/cluster/Jersey2PeerEurekaNodes.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.cluster; 2 | 3 | import com.netflix.appinfo.ApplicationInfoManager; 4 | import com.netflix.discovery.EurekaClientConfig; 5 | import com.netflix.eureka.EurekaServerConfig; 6 | import com.netflix.eureka.registry.PeerAwareInstanceRegistry; 7 | import com.netflix.eureka.resources.ServerCodecs; 8 | import com.netflix.eureka.transport.Jersey2ReplicationClient; 9 | 10 | /** 11 | * Jersey2 implementation of PeerEurekaNodes that uses the Jersey2 replication client 12 | * @author Matt Nelson 13 | */ 14 | public class Jersey2PeerEurekaNodes extends PeerEurekaNodes { 15 | 16 | public Jersey2PeerEurekaNodes(PeerAwareInstanceRegistry registry, EurekaServerConfig serverConfig, 17 | EurekaClientConfig clientConfig, ServerCodecs serverCodecs, ApplicationInfoManager applicationInfoManager) { 18 | super(registry, serverConfig, clientConfig, serverCodecs, applicationInfoManager); 19 | } 20 | 21 | @Override 22 | protected PeerEurekaNode createPeerEurekaNode(String peerEurekaNodeUrl) { 23 | HttpReplicationClient replicationClient = Jersey2ReplicationClient.createReplicationClient(serverConfig, serverCodecs, peerEurekaNodeUrl); 24 | String targetHost = hostFromUrl(peerEurekaNodeUrl); 25 | if (targetHost == null) { 26 | targetHost = "host"; 27 | } 28 | return new PeerEurekaNode(registry, targetHost, peerEurekaNodeUrl, replicationClient, serverConfig); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /eureka-core-jersey2/src/main/java/com/netflix/eureka/resources/EurekaServerContextBinder.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.resources; 2 | 3 | import org.glassfish.hk2.api.Factory; 4 | import org.glassfish.hk2.utilities.binding.AbstractBinder; 5 | 6 | import com.netflix.eureka.EurekaServerContext; 7 | import com.netflix.eureka.EurekaServerContextHolder; 8 | 9 | /** 10 | * Jersey2 binder for the EurekaServerContext. Replaces the GuiceFilter in the server WAR web.xml 11 | * @author Matt Nelson 12 | */ 13 | public class EurekaServerContextBinder extends AbstractBinder { 14 | 15 | public class EurekaServerContextFactory implements Factory { 16 | @Override 17 | public EurekaServerContext provide() { 18 | return EurekaServerContextHolder.getInstance().getServerContext(); 19 | } 20 | 21 | @Override 22 | public void dispose(EurekaServerContext t) { 23 | } 24 | } 25 | 26 | /** 27 | * {@inheritDoc} 28 | */ 29 | @Override 30 | protected void configure() { 31 | bindFactory(new EurekaServerContextFactory()).to(EurekaServerContext.class); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /eureka-core-jersey2/src/main/java/com/netflix/eureka/transport/Jersey2DynamicGZIPContentEncodingFilter.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.transport; 2 | 3 | import com.netflix.eureka.EurekaServerConfig; 4 | 5 | import javax.ws.rs.client.ClientRequestContext; 6 | import javax.ws.rs.client.ClientRequestFilter; 7 | import javax.ws.rs.client.ClientResponseContext; 8 | import javax.ws.rs.client.ClientResponseFilter; 9 | import javax.ws.rs.core.HttpHeaders; 10 | import java.io.IOException; 11 | 12 | public class Jersey2DynamicGZIPContentEncodingFilter implements ClientRequestFilter, ClientResponseFilter { 13 | 14 | private final EurekaServerConfig config; 15 | 16 | public Jersey2DynamicGZIPContentEncodingFilter(EurekaServerConfig config) { 17 | this.config = config; 18 | } 19 | 20 | @Override 21 | public void filter(ClientRequestContext requestContext) throws IOException { 22 | if (!requestContext.getHeaders().containsKey(HttpHeaders.ACCEPT_ENCODING)) { 23 | requestContext.getHeaders().add(HttpHeaders.ACCEPT_ENCODING, "gzip"); 24 | } 25 | 26 | if (hasEntity(requestContext) && isCompressionEnabled()) { 27 | Object contentEncoding = requestContext.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING); 28 | if (!"gzip".equals(contentEncoding)) { 29 | requestContext.getHeaders().add(HttpHeaders.CONTENT_ENCODING, "gzip"); 30 | } 31 | } 32 | } 33 | 34 | @Override 35 | public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { 36 | Object contentEncoding = responseContext.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING); 37 | if ("gzip".equals(contentEncoding)) { 38 | responseContext.getHeaders().remove(HttpHeaders.CONTENT_ENCODING); 39 | } 40 | } 41 | 42 | private boolean hasEntity(ClientRequestContext requestContext) { 43 | return false; 44 | } 45 | 46 | private boolean isCompressionEnabled() { 47 | return config.shouldEnableReplicatedRequestCompression(); 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /eureka-core/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compile project(':eureka-client') 3 | 4 | compile "com.amazonaws:aws-java-sdk-core:${awsVersion}" 5 | compile "com.amazonaws:aws-java-sdk-ec2:${awsVersion}" 6 | compile "com.amazonaws:aws-java-sdk-autoscaling:${awsVersion}" 7 | compile "com.amazonaws:aws-java-sdk-sts:${awsVersion}" 8 | compile "com.amazonaws:aws-java-sdk-route53:${awsVersion}" 9 | compile "javax.servlet:servlet-api:${servletVersion}" 10 | compile 'com.thoughtworks.xstream:xstream:1.4.19' 11 | compile 'javax.ws.rs:jsr311-api:1.1.1' 12 | 13 | // These dependencies are marked 'compileOnly' in the client, but we need them always on the server 14 | compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jacksonVersion}" 15 | compile "com.fasterxml.woodstox:woodstox-core:${woodstoxVersion}" 16 | 17 | testCompile project(':eureka-test-utils') 18 | testCompile "junit:junit:${junit_version}" 19 | testCompile 'org.mortbay.jetty:jetty:6.1H.22' 20 | testCompile "org.mock-server:mockserver-netty:${mockserverVersion}" 21 | testCompile "com.jcraft:jzlib:1.1.3" // netty dependency 22 | testCompile "org.mockito:mockito-core:${mockitoVersion}" 23 | testRuntime 'org.slf4j:slf4j-simple:1.7.10' 24 | } 25 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/EurekaServerContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.eureka; 18 | 19 | import com.netflix.appinfo.ApplicationInfoManager; 20 | import com.netflix.eureka.cluster.PeerEurekaNodes; 21 | import com.netflix.eureka.registry.PeerAwareInstanceRegistry; 22 | import com.netflix.eureka.resources.ServerCodecs; 23 | 24 | /** 25 | * @author David Liu 26 | */ 27 | public interface EurekaServerContext { 28 | 29 | void initialize() throws Exception; 30 | 31 | void shutdown() throws Exception; 32 | 33 | EurekaServerConfig getServerConfig(); 34 | 35 | PeerEurekaNodes getPeerEurekaNodes(); 36 | 37 | ServerCodecs getServerCodecs(); 38 | 39 | PeerAwareInstanceRegistry getRegistry(); 40 | 41 | ApplicationInfoManager getApplicationInfoManager(); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/EurekaServerContextHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.eureka; 18 | 19 | /** 20 | * A static holder for the server context for use in non-DI cases. 21 | * 22 | * @author David Liu 23 | */ 24 | public class EurekaServerContextHolder { 25 | 26 | private final EurekaServerContext serverContext; 27 | 28 | private EurekaServerContextHolder(EurekaServerContext serverContext) { 29 | this.serverContext = serverContext; 30 | } 31 | 32 | public EurekaServerContext getServerContext() { 33 | return this.serverContext; 34 | } 35 | 36 | private static EurekaServerContextHolder holder; 37 | 38 | public static synchronized void initialize(EurekaServerContext serverContext) { 39 | holder = new EurekaServerContextHolder(serverContext); 40 | } 41 | 42 | public static EurekaServerContextHolder getInstance() { 43 | return holder; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/EurekaServerIdentity.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka; 2 | 3 | import com.netflix.appinfo.AbstractEurekaIdentity; 4 | 5 | /** 6 | * This class holds metadata information related to eureka server auth with peer eureka servers 7 | */ 8 | public class EurekaServerIdentity extends AbstractEurekaIdentity { 9 | public static final String DEFAULT_SERVER_NAME = "DefaultServer"; 10 | 11 | private final String serverVersion = "1.0"; 12 | private final String id; 13 | 14 | public EurekaServerIdentity(String id) { 15 | this.id = id; 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return DEFAULT_SERVER_NAME; 21 | } 22 | 23 | @Override 24 | public String getVersion() { 25 | return serverVersion; 26 | } 27 | 28 | @Override 29 | public String getId() { 30 | return id; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/Names.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.eureka; 18 | 19 | /** 20 | * @author Tomasz Bak 21 | */ 22 | public class Names { 23 | 24 | /** 25 | * Eureka metric names consist of three parts [source].[component].[detailed name]: 26 | *
    27 | *
  • source - fixed to eurekaServer (and eurekaClient on the client side)
  • 28 | *
  • component - Eureka component, like REST layer, replication, etc
  • 29 | *
  • detailed name - a detailed metric name explaining its purpose
  • 30 | *
31 | */ 32 | public static final String METRIC_PREFIX = "eurekaServer."; 33 | 34 | public static final String METRIC_REPLICATION_PREFIX = METRIC_PREFIX + "replication."; 35 | 36 | public static final String METRIC_REGISTRY_PREFIX = METRIC_PREFIX + "registry."; 37 | 38 | public static final String REMOTE = "remote"; 39 | } 40 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/V1AwareInstanceInfoConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.eureka; 18 | 19 | import com.netflix.appinfo.InstanceInfo; 20 | import com.netflix.appinfo.InstanceInfo.InstanceStatus; 21 | import com.netflix.discovery.converters.Converters.InstanceInfoConverter; 22 | import com.netflix.eureka.resources.CurrentRequestVersion; 23 | 24 | /** 25 | * Support for {@link Version#V1}. {@link Version#V2} introduces a new status 26 | * {@link InstanceStatus#OUT_OF_SERVICE}. 27 | * 28 | * @author Karthik Ranganathan, Greg Kim 29 | * 30 | */ 31 | public class V1AwareInstanceInfoConverter extends InstanceInfoConverter { 32 | 33 | @Override 34 | public String getStatus(InstanceInfo info) { 35 | Version version = CurrentRequestVersion.get(); 36 | if (version == null || version == Version.V1) { 37 | InstanceStatus status = info.getStatus(); 38 | switch (status) { 39 | case DOWN: 40 | case STARTING: 41 | case UP: 42 | break; 43 | default: 44 | // otherwise return DOWN 45 | status = InstanceStatus.DOWN; 46 | break; 47 | } 48 | return status.name(); 49 | } else { 50 | return super.getStatus(info); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/Version.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.eureka; 18 | 19 | 20 | /** 21 | * Supported versions for Eureka. 22 | * 23 | *

The latest versions are always recommended.

24 | * 25 | * @author Karthik Ranganathan, Greg Kim 26 | * 27 | */ 28 | public enum Version { 29 | V1, V2; 30 | 31 | public static Version toEnum(String v) { 32 | for (Version version : Version.values()) { 33 | if (version.name().equalsIgnoreCase(v)) { 34 | return version; 35 | } 36 | } 37 | //Defaults to v2 38 | return V2; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/aws/AsgClient.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.aws; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | 5 | public interface AsgClient { 6 | boolean isASGEnabled(InstanceInfo instanceInfo); 7 | 8 | void setStatus(String asgName, boolean enabled); 9 | } 10 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/aws/AwsBinder.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.aws; 2 | 3 | /** 4 | * Binds the Eureka server to a EIP, Route53 or else... 5 | */ 6 | public interface AwsBinder { 7 | void start() throws Exception; 8 | void shutdown() throws Exception; 9 | } -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/aws/AwsBinderDelegate.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.aws; 2 | 3 | import com.netflix.appinfo.ApplicationInfoManager; 4 | import com.netflix.discovery.EurekaClientConfig; 5 | import com.netflix.eureka.EurekaServerConfig; 6 | import com.netflix.eureka.registry.PeerAwareInstanceRegistry; 7 | 8 | import javax.annotation.PostConstruct; 9 | import javax.annotation.PreDestroy; 10 | import javax.inject.Inject; 11 | import javax.inject.Singleton; 12 | 13 | @Singleton 14 | public class AwsBinderDelegate implements AwsBinder { 15 | 16 | private final AwsBinder delegate; 17 | 18 | @Inject 19 | public AwsBinderDelegate(EurekaServerConfig serverConfig, 20 | EurekaClientConfig clientConfig, 21 | PeerAwareInstanceRegistry registry, 22 | ApplicationInfoManager applicationInfoManager) { 23 | AwsBindingStrategy bindingStrategy = serverConfig.getBindingStrategy(); 24 | switch (bindingStrategy) { 25 | case ROUTE53: 26 | delegate = new Route53Binder(serverConfig, clientConfig, applicationInfoManager); 27 | break; 28 | case EIP: 29 | delegate = new EIPManager(serverConfig, clientConfig, registry, applicationInfoManager); 30 | break; 31 | case ENI: 32 | delegate = new ElasticNetworkInterfaceBinder(serverConfig, clientConfig, registry, applicationInfoManager); 33 | break; 34 | default: 35 | throw new IllegalArgumentException("Unexpected BindingStrategy " + bindingStrategy); 36 | } 37 | } 38 | 39 | @Override 40 | @PostConstruct 41 | public void start() { 42 | try { 43 | delegate.start(); 44 | } catch (Exception e) { 45 | throw new RuntimeException(e); 46 | } 47 | } 48 | 49 | @Override 50 | @PreDestroy 51 | public void shutdown() { 52 | try { 53 | delegate.shutdown(); 54 | } catch (Exception e) { 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/aws/AwsBindingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.aws; 2 | 3 | public enum AwsBindingStrategy { 4 | EIP, ROUTE53, ENI 5 | } 6 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/cluster/AsgReplicationTask.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.cluster; 2 | 3 | import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl.Action; 4 | import com.netflix.eureka.resources.ASGResource.ASGStatus; 5 | 6 | /** 7 | * Base {@link ReplicationTask} class for ASG related replication requests. 8 | * 9 | * @author Tomasz Bak 10 | */ 11 | public abstract class AsgReplicationTask extends ReplicationTask { 12 | 13 | private final String asgName; 14 | private final ASGStatus newStatus; 15 | 16 | protected AsgReplicationTask(String peerNodeName, Action action, String asgName, ASGStatus newStatus) { 17 | super(peerNodeName, action); 18 | this.asgName = asgName; 19 | this.newStatus = newStatus; 20 | } 21 | 22 | @Override 23 | public String getTaskName() { 24 | return asgName + ':' + action + '@' + peerNodeName; 25 | } 26 | 27 | public String getAsgName() { 28 | return asgName; 29 | } 30 | 31 | public ASGStatus getNewStatus() { 32 | return newStatus; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/cluster/HttpReplicationClient.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.cluster; 2 | 3 | import com.netflix.discovery.shared.transport.EurekaHttpClient; 4 | import com.netflix.discovery.shared.transport.EurekaHttpResponse; 5 | import com.netflix.eureka.cluster.protocol.ReplicationList; 6 | import com.netflix.eureka.cluster.protocol.ReplicationListResponse; 7 | import com.netflix.eureka.resources.ASGResource.ASGStatus; 8 | 9 | /** 10 | * @author Tomasz Bak 11 | */ 12 | public interface HttpReplicationClient extends EurekaHttpClient { 13 | 14 | EurekaHttpResponse statusUpdate(String asgName, ASGStatus newStatus); 15 | 16 | EurekaHttpResponse submitBatchUpdates(ReplicationList replicationList); 17 | } 18 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/cluster/ReplicationTask.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.cluster; 2 | 3 | import com.netflix.discovery.shared.transport.EurekaHttpResponse; 4 | import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl.Action; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * Base class for all replication tasks. 10 | */ 11 | abstract class ReplicationTask { 12 | 13 | private static final Logger logger = LoggerFactory.getLogger(ReplicationTask.class); 14 | 15 | protected final String peerNodeName; 16 | protected final Action action; 17 | 18 | ReplicationTask(String peerNodeName, Action action) { 19 | this.peerNodeName = peerNodeName; 20 | this.action = action; 21 | } 22 | 23 | public abstract String getTaskName(); 24 | 25 | public Action getAction() { 26 | return action; 27 | } 28 | 29 | public abstract EurekaHttpResponse execute() throws Throwable; 30 | 31 | public void handleSuccess() { 32 | } 33 | 34 | public void handleFailure(int statusCode, Object responseEntity) throws Throwable { 35 | logger.warn("The replication of task {} failed with response code {}", getTaskName(), statusCode); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/cluster/protocol/ReplicationList.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.cluster.protocol; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import com.fasterxml.jackson.annotation.JsonCreator; 8 | import com.fasterxml.jackson.annotation.JsonProperty; 9 | import com.netflix.discovery.provider.Serializer; 10 | 11 | /** 12 | * @author Tomasz Bak 13 | */ 14 | @Serializer("jackson") // For backwards compatibility with DiscoveryJerseyProvider 15 | public class ReplicationList { 16 | private final List replicationList; 17 | 18 | public ReplicationList() { 19 | this.replicationList = new ArrayList<>(); 20 | } 21 | 22 | @JsonCreator 23 | public ReplicationList(@JsonProperty("replicationList") List replicationList) { 24 | this.replicationList = replicationList; 25 | } 26 | 27 | public ReplicationList(ReplicationInstance replicationInstance) { 28 | this(Collections.singletonList(replicationInstance)); 29 | } 30 | 31 | public void addReplicationInstance(ReplicationInstance instance) { 32 | replicationList.add(instance); 33 | } 34 | 35 | public List getReplicationList() { 36 | return this.replicationList; 37 | } 38 | 39 | @Override 40 | public boolean equals(Object o) { 41 | if (this == o) 42 | return true; 43 | if (o == null || getClass() != o.getClass()) 44 | return false; 45 | 46 | ReplicationList that = (ReplicationList) o; 47 | 48 | return !(replicationList != null ? !replicationList.equals(that.replicationList) : that.replicationList != null); 49 | 50 | } 51 | 52 | @Override 53 | public int hashCode() { 54 | return replicationList != null ? replicationList.hashCode() : 0; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/cluster/protocol/ReplicationListResponse.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.cluster.protocol; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.fasterxml.jackson.annotation.JsonCreator; 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import com.netflix.discovery.provider.Serializer; 9 | 10 | /** 11 | * The jersey resource class that generates the replication batch response. 12 | */ 13 | @Serializer("jackson") // For backwards compatibility with DiscoveryJerseyProvider 14 | public class ReplicationListResponse { 15 | private List responseList; 16 | 17 | public ReplicationListResponse() { 18 | this.responseList = new ArrayList(); 19 | } 20 | 21 | @JsonCreator 22 | public ReplicationListResponse(@JsonProperty("responseList") List responseList) { 23 | this.responseList = responseList; 24 | } 25 | 26 | public List getResponseList() { 27 | return responseList; 28 | } 29 | 30 | public void addResponse(ReplicationInstanceResponse singleResponse) { 31 | responseList.add(singleResponse); 32 | } 33 | 34 | @Override 35 | public boolean equals(Object o) { 36 | if (this == o) 37 | return true; 38 | if (o == null || getClass() != o.getClass()) 39 | return false; 40 | 41 | ReplicationListResponse that = (ReplicationListResponse) o; 42 | 43 | return !(responseList != null ? !responseList.equals(that.responseList) : that.responseList != null); 44 | 45 | } 46 | 47 | @Override 48 | public int hashCode() { 49 | return responseList != null ? responseList.hashCode() : 0; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/ResponseCache.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry; 2 | 3 | import javax.annotation.Nullable; 4 | import java.util.concurrent.atomic.AtomicLong; 5 | 6 | /** 7 | * @author David Liu 8 | */ 9 | public interface ResponseCache { 10 | 11 | void invalidate(String appName, @Nullable String vipAddress, @Nullable String secureVipAddress); 12 | 13 | AtomicLong getVersionDelta(); 14 | 15 | AtomicLong getVersionDeltaWithRegions(); 16 | 17 | /** 18 | * Get the cached information about applications. 19 | * 20 | *

21 | * If the cached information is not available it is generated on the first 22 | * request. After the first request, the information is then updated 23 | * periodically by a background thread. 24 | *

25 | * 26 | * @param key the key for which the cached information needs to be obtained. 27 | * @return payload which contains information about the applications. 28 | */ 29 | String get(Key key); 30 | 31 | /** 32 | * Get the compressed information about the applications. 33 | * 34 | * @param key the key for which the compressed cached information needs to be obtained. 35 | * @return compressed payload which contains information about the applications. 36 | */ 37 | byte[] getGZIP(Key key); 38 | 39 | /** 40 | * Performs a shutdown of this cache by stopping internal threads and unregistering 41 | * Servo monitors. 42 | */ 43 | void stop(); 44 | } 45 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/rule/AlwaysMatchInstanceStatusRule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry.rule; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.eureka.lease.Lease; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * This rule matches always and returns the current status of the instance. 10 | * 11 | * Created by Nikos Michalakis on 7/13/16. 12 | */ 13 | public class AlwaysMatchInstanceStatusRule implements InstanceStatusOverrideRule { 14 | private static final Logger logger = LoggerFactory.getLogger(AlwaysMatchInstanceStatusRule.class); 15 | 16 | @Override 17 | public StatusOverrideResult apply(InstanceInfo instanceInfo, 18 | Lease existingLease, 19 | boolean isReplication) { 20 | logger.debug("Returning the default instance status {} for instance {}", instanceInfo.getStatus(), 21 | instanceInfo.getId()); 22 | return StatusOverrideResult.matchingStatus(instanceInfo.getStatus()); 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return AlwaysMatchInstanceStatusRule.class.getName(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/rule/AsgEnabledRule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry.rule; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.appinfo.InstanceInfo.InstanceStatus; 5 | import com.netflix.eureka.aws.AsgClient; 6 | import com.netflix.eureka.lease.Lease; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | /** 12 | * This is a rule that checks if the ASG for an instance is enabled or not and if not then it brings the instance 13 | * OUT_OF_SERVICE. 14 | * 15 | * Created by Nikos Michalakis on 7/14/16. 16 | */ 17 | public class AsgEnabledRule implements InstanceStatusOverrideRule { 18 | private static final Logger logger = LoggerFactory.getLogger(AsgEnabledRule.class); 19 | 20 | private final AsgClient asgClient; 21 | 22 | public AsgEnabledRule(AsgClient asgClient) { 23 | this.asgClient = asgClient; 24 | } 25 | 26 | @Override 27 | public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease existingLease, boolean isReplication) { 28 | // If the ASGName is present- check for its status 29 | if (instanceInfo.getASGName() != null) { 30 | boolean isASGDisabled = !asgClient.isASGEnabled(instanceInfo); 31 | logger.debug("The ASG name is specified {} and the value is {}", instanceInfo.getASGName(), isASGDisabled); 32 | if (isASGDisabled) { 33 | return StatusOverrideResult.matchingStatus(InstanceStatus.OUT_OF_SERVICE); 34 | } else { 35 | return StatusOverrideResult.matchingStatus(InstanceStatus.UP); 36 | } 37 | } 38 | return StatusOverrideResult.NO_MATCH; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return AsgEnabledRule.class.getName(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/rule/DownOrStartingRule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry.rule; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.eureka.lease.Lease; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * This rule matches if the instance is DOWN or STARTING. 10 | * 11 | * Created by Nikos Michalakis on 7/13/16. 12 | */ 13 | public class DownOrStartingRule implements InstanceStatusOverrideRule { 14 | private static final Logger logger = LoggerFactory.getLogger(DownOrStartingRule.class); 15 | 16 | @Override 17 | public StatusOverrideResult apply(InstanceInfo instanceInfo, 18 | Lease existingLease, 19 | boolean isReplication) { 20 | // ReplicationInstance is DOWN or STARTING - believe that, but when the instance says UP, question that 21 | // The client instance sends STARTING or DOWN (because of heartbeat failures), then we accept what 22 | // the client says. The same is the case with replica as well. 23 | // The OUT_OF_SERVICE from the client or replica needs to be confirmed as well since the service may be 24 | // currently in SERVICE 25 | if ((!InstanceInfo.InstanceStatus.UP.equals(instanceInfo.getStatus())) 26 | && (!InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(instanceInfo.getStatus()))) { 27 | logger.debug("Trusting the instance status {} from replica or instance for instance {}", 28 | instanceInfo.getStatus(), instanceInfo.getId()); 29 | return StatusOverrideResult.matchingStatus(instanceInfo.getStatus()); 30 | } 31 | return StatusOverrideResult.NO_MATCH; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return DownOrStartingRule.class.getName(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/rule/FirstMatchWinsCompositeRule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry.rule; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.eureka.lease.Lease; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * This rule takes an ordered list of rules and returns the result of the first match or the 11 | * result of the {@link AlwaysMatchInstanceStatusRule}. 12 | * 13 | * Created by Nikos Michalakis on 7/13/16. 14 | */ 15 | public class FirstMatchWinsCompositeRule implements InstanceStatusOverrideRule { 16 | 17 | private final InstanceStatusOverrideRule[] rules; 18 | private final InstanceStatusOverrideRule defaultRule; 19 | private final String compositeRuleName; 20 | 21 | public FirstMatchWinsCompositeRule(InstanceStatusOverrideRule... rules) { 22 | this.rules = rules; 23 | this.defaultRule = new AlwaysMatchInstanceStatusRule(); 24 | // Let's build up and "cache" the rule name to be used by toString(); 25 | List ruleNames = new ArrayList<>(rules.length+1); 26 | for (int i = 0; i < rules.length; ++i) { 27 | ruleNames.add(rules[i].toString()); 28 | } 29 | ruleNames.add(defaultRule.toString()); 30 | compositeRuleName = ruleNames.toString(); 31 | } 32 | 33 | @Override 34 | public StatusOverrideResult apply(InstanceInfo instanceInfo, 35 | Lease existingLease, 36 | boolean isReplication) { 37 | for (int i = 0; i < this.rules.length; ++i) { 38 | StatusOverrideResult result = this.rules[i].apply(instanceInfo, existingLease, isReplication); 39 | if (result.matches()) { 40 | return result; 41 | } 42 | } 43 | return defaultRule.apply(instanceInfo, existingLease, isReplication); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return this.compositeRuleName; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/rule/InstanceStatusOverrideRule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry.rule; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.eureka.lease.Lease; 5 | import com.netflix.eureka.registry.AbstractInstanceRegistry; 6 | 7 | /** 8 | * A single rule that if matched it returns an instance status. 9 | * The idea is to use an ordered list of such rules and pick the first result that matches. 10 | * 11 | * It is designed to be used by 12 | * {@link AbstractInstanceRegistry#getOverriddenInstanceStatus(InstanceInfo, Lease, boolean)} 13 | * 14 | * Created by Nikos Michalakis on 7/13/16. 15 | */ 16 | public interface InstanceStatusOverrideRule { 17 | 18 | /** 19 | * Match this rule. 20 | * 21 | * @param instanceInfo The instance info whose status we care about. 22 | * @param existingLease Does the instance have an existing lease already? If so let's consider that. 23 | * @param isReplication When overriding consider if we are under a replication mode from other servers. 24 | * @return A result with whether we matched and what we propose the status to be overriden to. 25 | */ 26 | StatusOverrideResult apply(final InstanceInfo instanceInfo, 27 | final Lease existingLease, 28 | boolean isReplication); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/rule/LeaseExistsRule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry.rule; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.eureka.lease.Lease; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * This rule matches if we have an existing lease for the instance that is UP or OUT_OF_SERVICE. 10 | * 11 | * Created by Nikos Michalakis on 7/13/16. 12 | */ 13 | public class LeaseExistsRule implements InstanceStatusOverrideRule { 14 | 15 | private static final Logger logger = LoggerFactory.getLogger(LeaseExistsRule.class); 16 | 17 | @Override 18 | public StatusOverrideResult apply(InstanceInfo instanceInfo, 19 | Lease existingLease, 20 | boolean isReplication) { 21 | // This is for backward compatibility until all applications have ASG 22 | // names, otherwise while starting up 23 | // the client status may override status replicated from other servers 24 | if (!isReplication) { 25 | InstanceInfo.InstanceStatus existingStatus = null; 26 | if (existingLease != null) { 27 | existingStatus = existingLease.getHolder().getStatus(); 28 | } 29 | // Allow server to have its way when the status is UP or OUT_OF_SERVICE 30 | if ((existingStatus != null) 31 | && (InstanceInfo.InstanceStatus.OUT_OF_SERVICE.equals(existingStatus) 32 | || InstanceInfo.InstanceStatus.UP.equals(existingStatus))) { 33 | logger.debug("There is already an existing lease with status {} for instance {}", 34 | existingLease.getHolder().getStatus().name(), 35 | existingLease.getHolder().getId()); 36 | return StatusOverrideResult.matchingStatus(existingLease.getHolder().getStatus()); 37 | } 38 | } 39 | return StatusOverrideResult.NO_MATCH; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return LeaseExistsRule.class.getName(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/rule/OverrideExistsRule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry.rule; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.eureka.lease.Lease; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * This rule checks to see if we have overrides for an instance and if we do then we return those. 12 | * 13 | * Created by Nikos Michalakis on 7/13/16. 14 | */ 15 | public class OverrideExistsRule implements InstanceStatusOverrideRule { 16 | 17 | private static final Logger logger = LoggerFactory.getLogger(OverrideExistsRule.class); 18 | 19 | private Map statusOverrides; 20 | 21 | public OverrideExistsRule(Map statusOverrides) { 22 | this.statusOverrides = statusOverrides; 23 | } 24 | 25 | @Override 26 | public StatusOverrideResult apply(InstanceInfo instanceInfo, Lease existingLease, boolean isReplication) { 27 | InstanceInfo.InstanceStatus overridden = statusOverrides.get(instanceInfo.getId()); 28 | // If there are instance specific overrides, then they win - otherwise the ASG status 29 | if (overridden != null) { 30 | logger.debug("The instance specific override for instance {} and the value is {}", 31 | instanceInfo.getId(), overridden.name()); 32 | return StatusOverrideResult.matchingStatus(overridden); 33 | } 34 | return StatusOverrideResult.NO_MATCH; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return OverrideExistsRule.class.getName(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/registry/rule/StatusOverrideResult.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.registry.rule; 2 | 3 | import com.netflix.appinfo.InstanceInfo; 4 | import com.netflix.eureka.registry.rule.InstanceStatusOverrideRule; 5 | 6 | /** 7 | * Container for a result computed by an {@link InstanceStatusOverrideRule}. 8 | * 9 | * Created by Nikos Michalakis on 7/13/16. 10 | */ 11 | public class StatusOverrideResult { 12 | 13 | public static StatusOverrideResult NO_MATCH = new StatusOverrideResult(false, null); 14 | 15 | public static StatusOverrideResult matchingStatus(InstanceInfo.InstanceStatus status) { 16 | return new StatusOverrideResult(true, status); 17 | } 18 | 19 | // Does the rule match? 20 | private final boolean matches; 21 | 22 | // The status computed by the rule. 23 | private final InstanceInfo.InstanceStatus status; 24 | 25 | private StatusOverrideResult(boolean matches, InstanceInfo.InstanceStatus status) { 26 | this.matches = matches; 27 | this.status = status; 28 | } 29 | 30 | public boolean matches() { 31 | return matches; 32 | } 33 | 34 | public InstanceInfo.InstanceStatus status() { 35 | return status; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/resources/CurrentRequestVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.eureka.resources; 18 | 19 | 20 | import com.netflix.eureka.Version; 21 | 22 | /** 23 | * A thread-scoped value that holds the "current {@link com.netflix.eureka.Version}" for the 24 | * request. 25 | * 26 | *

This is not intended as a general mechanism for passing data. 27 | * Rather it is here to support those cases where someplace deep in 28 | * a library we need to know about the context of the request that 29 | * initially triggered the current request.

30 | * 31 | * @author Karthik Ranganathan, Greg Kim 32 | */ 33 | public final class CurrentRequestVersion { 34 | 35 | private static final ThreadLocal CURRENT_REQ_VERSION = 36 | new ThreadLocal<>(); 37 | 38 | private CurrentRequestVersion() { 39 | } 40 | 41 | /** 42 | * Gets the current {@link Version} 43 | * Will return null if no current version has been set. 44 | */ 45 | public static Version get() { 46 | return CURRENT_REQ_VERSION.get(); 47 | } 48 | 49 | /** 50 | * Sets the current {@link Version}. 51 | * 52 | * Use {@link #remove()} as soon as the version is no longer required 53 | * in order to purge the ThreadLocal used for storing it. 54 | */ 55 | public static void set(Version version) { 56 | CURRENT_REQ_VERSION.set(version); 57 | } 58 | 59 | /** 60 | * Clears the {@link ThreadLocal} used to store the version. 61 | */ 62 | public static void remove() { 63 | CURRENT_REQ_VERSION.remove(); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/resources/ServerCodecs.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.resources; 2 | 3 | import com.netflix.appinfo.EurekaAccept; 4 | import com.netflix.discovery.converters.wrappers.CodecWrapper; 5 | import com.netflix.discovery.converters.wrappers.EncoderWrapper; 6 | import com.netflix.eureka.registry.Key; 7 | 8 | /** 9 | * @author David Liu 10 | */ 11 | public interface ServerCodecs { 12 | 13 | CodecWrapper getFullJsonCodec(); 14 | 15 | CodecWrapper getCompactJsonCodec(); 16 | 17 | CodecWrapper getFullXmlCodec(); 18 | 19 | CodecWrapper getCompactXmlCodecr(); 20 | 21 | EncoderWrapper getEncoder(Key.KeyType keyType, boolean compact); 22 | 23 | EncoderWrapper getEncoder(Key.KeyType keyType, EurekaAccept eurekaAccept); 24 | } 25 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/resources/ServerInfoResource.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.resources; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.netflix.appinfo.InstanceInfo; 5 | import com.netflix.eureka.EurekaServerContext; 6 | import com.netflix.eureka.EurekaServerContextHolder; 7 | import com.netflix.eureka.registry.PeerAwareInstanceRegistry; 8 | 9 | import javax.inject.Inject; 10 | import javax.ws.rs.GET; 11 | import javax.ws.rs.Path; 12 | import javax.ws.rs.Produces; 13 | import javax.ws.rs.core.Response; 14 | import java.util.Map; 15 | 16 | /** 17 | * @author David Liu 18 | */ 19 | @Produces("application/json") 20 | @Path("/serverinfo") 21 | public class ServerInfoResource { 22 | private final PeerAwareInstanceRegistry registry; 23 | 24 | @Inject 25 | ServerInfoResource(EurekaServerContext server) { 26 | this.registry = server.getRegistry(); 27 | } 28 | 29 | public ServerInfoResource() { 30 | this(EurekaServerContextHolder.getInstance().getServerContext()); 31 | } 32 | 33 | @GET 34 | @Path("statusoverrides") 35 | public Response getOverrides() throws Exception { 36 | Map result = registry.overriddenInstanceStatusesSnapshot(); 37 | 38 | ObjectMapper objectMapper = new ObjectMapper(); 39 | String responseStr = objectMapper.writeValueAsString(result); 40 | return Response.ok(responseStr).build(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/util/ServoControl.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.util; 2 | 3 | import com.netflix.servo.monitor.MonitorConfig; 4 | import com.netflix.servo.monitor.StatsTimer; 5 | import com.netflix.servo.stats.StatsConfig; 6 | 7 | /** 8 | * The sole purpose of this class is shutting down the {@code protected} executor of {@link StatsTimer} 9 | */ 10 | public class ServoControl extends StatsTimer { 11 | 12 | public ServoControl(MonitorConfig baseConfig, StatsConfig statsConfig) { 13 | super(baseConfig, statsConfig); 14 | throw new UnsupportedOperationException(getClass().getName() + " is not meant to be instantiated."); 15 | } 16 | 17 | public static void shutdown() { 18 | DEFAULT_EXECUTOR.shutdown(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/util/batcher/TaskDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.util.batcher; 2 | 3 | /** 4 | * Task dispatcher takes task from clients, and delegates their execution to a configurable number of workers. 5 | * The task can be processed one at a time or in batches. Only non-expired tasks are executed, and if a newer 6 | * task with the same id is scheduled for execution, the old one is deleted. Lazy dispatch of work (only on demand) 7 | * to workers, guarantees that data are always up to date, and no stale task processing takes place. 8 | *

Task processor

9 | * A client of this component must provide an implementation of {@link TaskProcessor} interface, which will do 10 | * the actual work of task processing. This implementation must be thread safe, as it is called concurrently by 11 | * multiple threads. 12 | *

Execution modes

13 | * To create non batched executor call {@link TaskDispatchers#createNonBatchingTaskDispatcher(String, int, int, long, long, TaskProcessor)} 14 | * method. Batched executor is created by {@link TaskDispatchers#createBatchingTaskDispatcher(String, int, int, int, long, long, TaskProcessor)}. 15 | * 16 | * @author Tomasz Bak 17 | */ 18 | public interface TaskDispatcher { 19 | 20 | void process(ID id, T task, long expiryTime); 21 | 22 | void shutdown(); 23 | } 24 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/util/batcher/TaskHolder.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.util.batcher; 2 | 3 | /** 4 | * @author Tomasz Bak 5 | */ 6 | class TaskHolder { 7 | 8 | private final ID id; 9 | private final T task; 10 | private final long expiryTime; 11 | private final long submitTimestamp; 12 | 13 | TaskHolder(ID id, T task, long expiryTime) { 14 | this.id = id; 15 | this.expiryTime = expiryTime; 16 | this.task = task; 17 | this.submitTimestamp = System.currentTimeMillis(); 18 | } 19 | 20 | public ID getId() { 21 | return id; 22 | } 23 | 24 | public T getTask() { 25 | return task; 26 | } 27 | 28 | public long getExpiryTime() { 29 | return expiryTime; 30 | } 31 | 32 | public long getSubmitTimestamp() { 33 | return submitTimestamp; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /eureka-core/src/main/java/com/netflix/eureka/util/batcher/TaskProcessor.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.util.batcher; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * An interface to be implemented by clients for task execution. 7 | * 8 | * @author Tomasz Bak 9 | */ 10 | public interface TaskProcessor { 11 | 12 | /** 13 | * A processed task/task list ends up in one of the following states: 14 | *
    15 | *
  • {@code Success} processing finished successfully
  • 16 | *
  • {@code TransientError} processing failed, but shall be retried later
  • 17 | *
  • {@code PermanentError} processing failed, and is non recoverable
  • 18 | *
19 | */ 20 | enum ProcessingResult { 21 | Success, Congestion, TransientError, PermanentError 22 | } 23 | 24 | /** 25 | * In non-batched mode a single task is processed at a time. 26 | */ 27 | ProcessingResult process(T task); 28 | 29 | /** 30 | * For batched mode a collection of tasks is run at a time. The result is provided for the aggregated result, 31 | * and all tasks are handled in the same way according to what is returned (for example are rescheduled, if the 32 | * error is transient). 33 | */ 34 | ProcessingResult process(List tasks); 35 | } 36 | -------------------------------------------------------------------------------- /eureka-core/src/test/java/com/netflix/eureka/RemoteRegionSoftDependencyTest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka; 2 | 3 | import com.netflix.eureka.mock.MockRemoteEurekaServer; 4 | import org.junit.Assert; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import static org.mockito.Mockito.doReturn; 9 | 10 | /** 11 | * @author Nitesh Kant 12 | */ 13 | public class RemoteRegionSoftDependencyTest extends AbstractTester { 14 | 15 | @Override 16 | @Before 17 | public void setUp() throws Exception { 18 | super.setUp(); 19 | doReturn(10).when(serverConfig).getWaitTimeInMsWhenSyncEmpty(); 20 | doReturn(1).when(serverConfig).getRegistrySyncRetries(); 21 | doReturn(1l).when(serverConfig).getRegistrySyncRetryWaitMs(); 22 | registry.syncUp(); 23 | } 24 | 25 | @Test 26 | public void testSoftDepRemoteDown() throws Exception { 27 | Assert.assertTrue("Registry access disallowed when remote region is down.", registry.shouldAllowAccess(false)); 28 | Assert.assertFalse("Registry access allowed when remote region is down.", registry.shouldAllowAccess(true)); 29 | } 30 | 31 | @Override 32 | protected MockRemoteEurekaServer newMockRemoteServer() { 33 | MockRemoteEurekaServer server = super.newMockRemoteServer(); 34 | server.simulateNotReady(true); 35 | return server; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /eureka-core/src/test/java/com/netflix/eureka/test/async/executor/AsyncExecutorException.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.test.async.executor; 2 | 3 | /** 4 | * Async executor exception for {@link ConcreteAsyncResult}. 5 | */ 6 | public class AsyncExecutorException extends RuntimeException { 7 | 8 | public AsyncExecutorException() { 9 | } 10 | 11 | public AsyncExecutorException(String message) { 12 | super(message); 13 | } 14 | 15 | public AsyncExecutorException(String message, Throwable cause) { 16 | super(message, cause); 17 | } 18 | 19 | public AsyncExecutorException(Throwable cause) { 20 | super(cause); 21 | } 22 | 23 | public AsyncExecutorException(String message, 24 | Throwable cause, 25 | boolean enableSuppression, 26 | boolean writableStackTrace) { 27 | super(message, cause, enableSuppression, writableStackTrace); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /eureka-core/src/test/java/com/netflix/eureka/test/async/executor/AsyncResult.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.test.async.executor; 2 | 3 | import java.util.concurrent.Future; 4 | 5 | /** 6 | * Async result which extends {@link Future}. 7 | * 8 | * @param The result type. 9 | */ 10 | public interface AsyncResult extends Future { 11 | 12 | /** 13 | * Handle result normally. 14 | * 15 | * @param result result. 16 | */ 17 | void handleResult(T result); 18 | 19 | /** 20 | * Handle error. 21 | * 22 | * @param error error during execution. 23 | */ 24 | void handleError(Throwable error); 25 | 26 | /** 27 | * Get result which will be blocked until the result is available or an error occurs. 28 | */ 29 | T getResult() throws AsyncExecutorException; 30 | 31 | /** 32 | * Get error if possible. 33 | * 34 | * @return error. 35 | */ 36 | Throwable getError(); 37 | } 38 | -------------------------------------------------------------------------------- /eureka-core/src/test/java/com/netflix/eureka/test/async/executor/Backoff.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.test.async.executor; 2 | 3 | /** 4 | * Backoff for pausing for a duration 5 | */ 6 | public class Backoff { 7 | 8 | /** 9 | * Pause time in milliseconds 10 | */ 11 | private final int pauseTimeInMs; 12 | 13 | /** 14 | * Prepare to pause for one duration. 15 | * 16 | * @param pauseTimeInMs pause time in milliseconds 17 | */ 18 | public Backoff(int pauseTimeInMs) { 19 | this.pauseTimeInMs = pauseTimeInMs; 20 | } 21 | 22 | /** 23 | * Backoff for one duration. 24 | */ 25 | public void backoff() throws InterruptedException { 26 | Thread.sleep(pauseTimeInMs); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /eureka-examples/conf/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 5 | -------------------------------------------------------------------------------- /eureka-examples/conf/sample-eureka-client.properties: -------------------------------------------------------------------------------- 1 | ###Eureka Client configuration for Sample Eureka Client 2 | 3 | # see the README in eureka-examples to see an overview of the example set up 4 | 5 | # note that for a purely client usage (e.g. only used to get information about other services, 6 | # there is no need for registration. This property applies to the singleton DiscoveryClient so 7 | # if you run a server that is both a service provider and also a service consumer, 8 | # then don't set this property to false. 9 | eureka.registration.enabled=false 10 | 11 | ## configuration related to reaching the eureka servers 12 | eureka.preferSameZone=true 13 | eureka.shouldUseDns=false 14 | eureka.serviceUrl.default=http://localhost:8080/eureka/v2/ 15 | 16 | eureka.decoderName=JacksonJson 17 | -------------------------------------------------------------------------------- /eureka-examples/conf/sample-eureka-service.properties: -------------------------------------------------------------------------------- 1 | ###Eureka Client configuration for Sample Service that register with Eureka 2 | 3 | # see the README in eureka-examples to see an overview of the example set up 4 | 5 | ## configurations related to self identification for registration. 6 | ## There are other properties that can be defined, see eureka-client/../CloudInstanceConfig for full details. 7 | # where am I deployed? 8 | eureka.region=default 9 | 10 | # what is my application name? (clients can query on this appName) 11 | eureka.name=sampleRegisteringService 12 | 13 | # what is my application virtual ip address? (clients can query on this vipAddress) 14 | eureka.vipAddress=sampleservice.mydomain.net 15 | 16 | # what is the port that I serve on? (Change this if port 8001 is already in use in your environment) 17 | eureka.port=8001 18 | 19 | ## configuration related to reaching the eureka servers 20 | eureka.preferSameZone=true 21 | eureka.shouldUseDns=false 22 | eureka.serviceUrl.default=http://localhost:8080/eureka/v2/ 23 | -------------------------------------------------------------------------------- /eureka-resources/src/main/resources/jsp/navbar.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" 2 | import="java.util.*,java.net.*,com.netflix.config.*, com.netflix.eureka.*,com.netflix.eureka.resources.*,com.netflix.eureka.cluster.*,com.netflix.appinfo.*" pageEncoding="UTF-8" %> 3 | 9 | 10 |
 
11 |
DS Replicas: 12 | <% 13 | EurekaServerContext serverContext = (EurekaServerContext) pageContext.getServletContext() 14 | .getAttribute(EurekaServerContext.class.getName()); 15 | List list = serverContext.getPeerEurekaNodes().getPeerNodesView(); 16 | int i=0; 17 | for(PeerEurekaNode node : list){ 18 | try{ 19 | URI uri = new URI(node.getServiceUrl()); 20 | String href = "http://" + uri.getHost() + ":" + uri.getPort() + request.getContextPath(); 21 | out.print("" + uri.getHost() + ""); 22 | }catch(Exception e){ 23 | } 24 | } 25 | %> 26 |
27 | -------------------------------------------------------------------------------- /eureka-server-governator/README.md: -------------------------------------------------------------------------------- 1 | This server build is still experimental. -------------------------------------------------------------------------------- /eureka-server-governator/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'war' 2 | apply plugin: 'org.gretty' 3 | 4 | dependencies { 5 | compile project(':eureka-core') 6 | compile project(':eureka-client') 7 | compile "com.netflix.governator:governator:${governatorVersion}" 8 | compile "com.netflix.governator:governator-servlet:${governatorVersion}" 9 | compile "com.sun.jersey:jersey-server:${jerseyVersion}" 10 | compile "com.sun.jersey:jersey-servlet:${jerseyVersion}" 11 | compile "com.sun.jersey.contribs:jersey-guice:${jerseyVersion}" 12 | compile 'org.slf4j:slf4j-log4j12:1.6.1' 13 | runtimeOnly "org.codehaus.jettison:jettison:${jettisonVersion}" 14 | providedCompile "javax.servlet:servlet-api:${servletVersion}" 15 | 16 | testCompile project(':eureka-test-utils') 17 | testCompile 'org.mockito:mockito-core:1.10.19' 18 | testCompile "org.eclipse.jetty:jetty-server:${jetty_version}" 19 | testCompile "org.eclipse.jetty:jetty-webapp:${jetty_version}" 20 | } 21 | 22 | task copyLibs(type: Copy) { 23 | into 'testlibs/WEB-INF/libs' 24 | from configurations.runtime 25 | } 26 | 27 | war { 28 | from (project(':eureka-resources').file('build/resources/main')) 29 | } 30 | 31 | gretty { 32 | contextPath 'eureka' 33 | } 34 | -------------------------------------------------------------------------------- /eureka-server-governator/src/main/java/com/netflix/eureka/guice/Ec2EurekaServerModule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.guice; 2 | 3 | import com.google.inject.AbstractModule; 4 | import com.google.inject.Scopes; 5 | import com.netflix.eureka.DefaultEurekaServerConfig; 6 | import com.netflix.eureka.DefaultEurekaServerContext; 7 | import com.netflix.eureka.EurekaServerConfig; 8 | import com.netflix.eureka.EurekaServerContext; 9 | import com.netflix.eureka.aws.AwsBinderDelegate; 10 | import com.netflix.eureka.cluster.PeerEurekaNodes; 11 | import com.netflix.eureka.registry.AbstractInstanceRegistry; 12 | import com.netflix.eureka.registry.AwsInstanceRegistry; 13 | import com.netflix.eureka.registry.InstanceRegistry; 14 | import com.netflix.eureka.registry.PeerAwareInstanceRegistry; 15 | import com.netflix.eureka.resources.DefaultServerCodecs; 16 | import com.netflix.eureka.resources.ServerCodecs; 17 | 18 | /** 19 | * @author David Liu 20 | */ 21 | public class Ec2EurekaServerModule extends AbstractModule { 22 | @Override 23 | protected void configure() { 24 | bind(EurekaServerConfig.class).to(DefaultEurekaServerConfig.class).in(Scopes.SINGLETON); 25 | bind(PeerEurekaNodes.class).in(Scopes.SINGLETON); 26 | 27 | bind(AwsBinderDelegate.class).asEagerSingleton(); 28 | 29 | // registry and interfaces 30 | bind(AwsInstanceRegistry.class).asEagerSingleton(); 31 | bind(InstanceRegistry.class).to(AwsInstanceRegistry.class); 32 | bind(AbstractInstanceRegistry.class).to(AwsInstanceRegistry.class); 33 | bind(PeerAwareInstanceRegistry.class).to(AwsInstanceRegistry.class); 34 | 35 | bind(ServerCodecs.class).to(DefaultServerCodecs.class).in(Scopes.SINGLETON); 36 | 37 | bind(EurekaServerContext.class).to(DefaultEurekaServerContext.class).in(Scopes.SINGLETON); 38 | } 39 | 40 | @Override 41 | public boolean equals(Object obj) { 42 | return Ec2EurekaServerModule.class.equals(obj.getClass()); 43 | } 44 | 45 | @Override 46 | public int hashCode() { 47 | return Ec2EurekaServerModule.class.hashCode(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /eureka-server-governator/src/main/java/com/netflix/eureka/guice/LocalDevEurekaServerModule.java: -------------------------------------------------------------------------------- 1 | package com.netflix.eureka.guice; 2 | 3 | import com.google.inject.AbstractModule; 4 | import com.google.inject.Scopes; 5 | import com.netflix.eureka.DefaultEurekaServerConfig; 6 | import com.netflix.eureka.DefaultEurekaServerContext; 7 | import com.netflix.eureka.EurekaServerConfig; 8 | import com.netflix.eureka.EurekaServerContext; 9 | import com.netflix.eureka.cluster.PeerEurekaNodes; 10 | import com.netflix.eureka.registry.AbstractInstanceRegistry; 11 | import com.netflix.eureka.registry.InstanceRegistry; 12 | import com.netflix.eureka.registry.PeerAwareInstanceRegistry; 13 | import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl; 14 | import com.netflix.eureka.resources.DefaultServerCodecs; 15 | import com.netflix.eureka.resources.ServerCodecs; 16 | 17 | /** 18 | * @author David Liu 19 | */ 20 | public class LocalDevEurekaServerModule extends AbstractModule { 21 | @Override 22 | protected void configure() { 23 | // server bindings 24 | bind(EurekaServerConfig.class).to(DefaultEurekaServerConfig.class).in(Scopes.SINGLETON); 25 | bind(PeerEurekaNodes.class).in(Scopes.SINGLETON); 26 | 27 | // registry and interfaces 28 | bind(PeerAwareInstanceRegistryImpl.class).asEagerSingleton(); 29 | bind(InstanceRegistry.class).to(PeerAwareInstanceRegistryImpl.class); 30 | bind(AbstractInstanceRegistry.class).to(PeerAwareInstanceRegistryImpl.class); 31 | bind(PeerAwareInstanceRegistry.class).to(PeerAwareInstanceRegistryImpl.class); 32 | 33 | bind(ServerCodecs.class).to(DefaultServerCodecs.class).in(Scopes.SINGLETON); 34 | 35 | bind(EurekaServerContext.class).to(DefaultEurekaServerContext.class).in(Scopes.SINGLETON); 36 | } 37 | 38 | @Override 39 | public boolean equals(Object obj) { 40 | return LocalDevEurekaServerModule.class.equals(obj.getClass()); 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | return LocalDevEurekaServerModule.class.hashCode(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /eureka-server-governator/src/main/resources/eureka-server.properties: -------------------------------------------------------------------------------- 1 | # Set this only for this sample service without which starting the instance will by default wait for the default of 5 mins 2 | eureka.waitTimeInMsWhenSyncEmpty=0 3 | 4 | # for the example, set this to zero as we will not have peers to sync up with. 5 | # Do not set in a real environment with multi-node eureka clusters. 6 | eureka.numberRegistrySyncRetries=0 7 | 8 | # for cascade loading of property files for different deployment environments and/or regions etc, 9 | # see archaius cascade loading: https://github.com/Netflix/archaius/wiki/Deployment-context 10 | -------------------------------------------------------------------------------- /eureka-server-governator/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 5 | log4j.logger.asyncAppenders=INFO,stdout -------------------------------------------------------------------------------- /eureka-server-governator/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | guiceFilter 10 | com.google.inject.servlet.GuiceFilter 11 | 12 | 13 | 14 | guiceFilter 15 | /* 16 | 17 | 18 | 19 | com.netflix.eureka.EurekaContextListener 20 | 21 | 22 | 23 | jsp/status.jsp 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /eureka-server/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'war' 2 | 3 | dependencies { 4 | compile project(':eureka-client') 5 | compile project(':eureka-core') 6 | compile "com.sun.jersey:jersey-server:$jerseyVersion" 7 | compile "com.sun.jersey:jersey-servlet:$jerseyVersion" 8 | compile 'org.slf4j:slf4j-log4j12:1.6.1' 9 | compile 'org.glassfish.jaxb:jaxb-runtime:2.3.3' 10 | 11 | runtimeOnly 'xerces:xercesImpl:2.12.0' 12 | runtimeOnly "org.codehaus.jettison:jettison:${jettisonVersion}" 13 | 14 | providedCompile "javax.servlet:servlet-api:$servletVersion" 15 | 16 | testCompile project(':eureka-test-utils') 17 | testCompile "org.mockito:mockito-core:${mockitoVersion}" 18 | testCompile "org.eclipse.jetty:jetty-server:$jetty_version" 19 | testCompile "org.eclipse.jetty:jetty-webapp:$jetty_version" 20 | } 21 | 22 | task copyLibs(type: Copy) { 23 | into 'testlibs/WEB-INF/libs' 24 | from configurations.runtime 25 | } 26 | 27 | war { 28 | from (project(':eureka-resources').file('build/resources/main')) 29 | } 30 | 31 | // Integration test loads eureka war, so it must be ready prior to running tests 32 | test.dependsOn war 33 | -------------------------------------------------------------------------------- /eureka-server/runclient.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Copy all libraries 3 | TEST_CLASSPATH= 4 | for i in testlibs/WEB-INF/lib/* 5 | do 6 | if [ "$TEST_CLASSPATH" = "" ] ; then 7 | TEST_CLASSPATH=$i 8 | fi 9 | TEST_CLASSPATH=$TEST_CLASSPATH:$i 10 | done 11 | TEST_CLASSPATH=$TEST_CLASSPATH:build/classes/main:conf/sampleclient 12 | 13 | echo CLASSPATH:$TEST_CLASSPATH 14 | java -Deureka.region=default -Deureka.environment=test -Deureka.client.props=sample-eureka-client -cp $TEST_CLASSPATH com.netflix.eureka.SampleEurekaClient 15 | 16 | -------------------------------------------------------------------------------- /eureka-server/runservice.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Copy all libraries 3 | TEST_CLASSPATH= 4 | for i in testlibs/WEB-INF/lib/* 5 | do 6 | if [ "$TEST_CLASSPATH" = "" ] ; then 7 | TEST_CLASSPATH=$i 8 | fi 9 | TEST_CLASSPATH=$TEST_CLASSPATH:$i 10 | done 11 | TEST_CLASSPATH=$TEST_CLASSPATH:build/classes/main:conf/sampleservice 12 | 13 | echo CLASSPATH:$TEST_CLASSPATH 14 | java -Deureka.region=default -Deureka.environment=test -Deureka.client.props=sample-eureka-service -cp $TEST_CLASSPATH com.netflix.eureka.SampleEurekaService 15 | 16 | -------------------------------------------------------------------------------- /eureka-server/src/main/resources/eureka-server.properties: -------------------------------------------------------------------------------- 1 | ## Set this only for this sample service without which starting the instance will by default wait for the default of 5 mins 2 | #eureka.waitTimeInMsWhenSyncEmpty=0 3 | 4 | ## for the example, set this to zero as we will not have peers to sync up with. 5 | ## Do not set in a real environment with multi-node eureka clusters. 6 | #eureka.numberRegistrySyncRetries=0 7 | 8 | ## for cascade loading of property files for different deployment environments and/or regions etc, 9 | ## see archaius cascade loading: https://github.com/Netflix/archaius/wiki/Deployment-context 10 | -------------------------------------------------------------------------------- /eureka-server/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO,stdout 2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | #log4j.appender.stdout.layout=com.netflix.logging.log4jAdapter.NFPatternLayout 5 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n 6 | log4j.logger.asyncAppenders=INFO,stdout 7 | -------------------------------------------------------------------------------- /eureka-test-utils/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compile project(':eureka-core') 3 | compile "junit:junit:${junit_version}" 4 | compile "org.mockito:mockito-core:${mockitoVersion}" 5 | } 6 | -------------------------------------------------------------------------------- /eureka-test-utils/src/main/java/com/netflix/discovery/junit/resource/SimpleEurekaHttpServerResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.junit.resource; 18 | 19 | import com.netflix.discovery.shared.transport.EurekaHttpClient; 20 | import com.netflix.discovery.shared.transport.SimpleEurekaHttpServer; 21 | import org.junit.rules.ExternalResource; 22 | 23 | import static org.mockito.Mockito.mock; 24 | 25 | /** 26 | * @author Tomasz Bak 27 | */ 28 | public class SimpleEurekaHttpServerResource extends ExternalResource { 29 | 30 | private final EurekaHttpClient requestHandler = mock(EurekaHttpClient.class); 31 | 32 | private SimpleEurekaHttpServer eurekaHttpServer; 33 | 34 | @Override 35 | protected void before() throws Throwable { 36 | eurekaHttpServer = new SimpleEurekaHttpServer(requestHandler); 37 | } 38 | 39 | @Override 40 | protected void after() { 41 | if (eurekaHttpServer != null) { 42 | eurekaHttpServer.shutdown(); 43 | } 44 | } 45 | 46 | public EurekaHttpClient getRequestHandler() { 47 | return requestHandler; 48 | } 49 | 50 | public SimpleEurekaHttpServer getEurekaHttpServer() { 51 | return eurekaHttpServer; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /eureka-test-utils/src/main/java/com/netflix/discovery/shared/transport/EurekaHttpRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.transport; 18 | 19 | import java.net.URI; 20 | import java.util.Collections; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | /** 25 | */ 26 | public class EurekaHttpRequest { 27 | 28 | private final String requestMethod; 29 | private final URI requestURI; 30 | private final Map headers; 31 | 32 | public EurekaHttpRequest(String requestMethod, URI requestURI, Map headers) { 33 | this.requestMethod = requestMethod; 34 | this.requestURI = requestURI; 35 | this.headers = Collections.unmodifiableMap(new HashMap(headers)); 36 | } 37 | 38 | public String getRequestMethod() { 39 | return requestMethod; 40 | } 41 | 42 | public URI getRequestURI() { 43 | return requestURI; 44 | } 45 | 46 | public Map getHeaders() { 47 | return headers; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /eureka-test-utils/src/main/java/com/netflix/discovery/shared/transport/EurekaTransportEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.shared.transport; 18 | 19 | /** 20 | */ 21 | public interface EurekaTransportEventListener { 22 | 23 | void onHttpRequest(EurekaHttpRequest request); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /eureka-test-utils/src/test/java/com/netflix/discovery/util/InstanceInfoGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.discovery.util; 18 | 19 | import java.util.Iterator; 20 | 21 | import com.netflix.appinfo.InstanceInfo; 22 | import org.junit.Test; 23 | 24 | import static org.hamcrest.CoreMatchers.equalTo; 25 | import static org.hamcrest.CoreMatchers.is; 26 | import static org.junit.Assert.assertThat; 27 | 28 | /** 29 | * @author Tomasz Bak 30 | */ 31 | public class InstanceInfoGeneratorTest { 32 | 33 | @Test 34 | public void testInstanceInfoStream() throws Exception { 35 | Iterator it = InstanceInfoGenerator.newBuilder(4, "app1", "app2").build().serviceIterator(); 36 | 37 | assertThat(it.next().getAppName(), is(equalTo("APP1"))); 38 | assertThat(it.next().getAppName(), is(equalTo("APP2"))); 39 | assertThat(it.next().getAppName(), is(equalTo("APP1"))); 40 | assertThat(it.next().getAppName(), is(equalTo("APP2"))); 41 | } 42 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | release.scope=patch 2 | org.gradle.caching = true 3 | org.gradle.parallel = true 4 | org.gradle.vfs.watch = true 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/eureka/015400c60d3dc730c3fc4871e9b586d3805cce0d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 30 10:13:13 PDT 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 7 | -------------------------------------------------------------------------------- /images/eureka_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/eureka/015400c60d3dc730c3fc4871e9b586d3805cce0d/images/eureka_architecture.png -------------------------------------------------------------------------------- /images/logo/eureka-logo-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/eureka/015400c60d3dc730c3fc4871e9b586d3805cce0d/images/logo/eureka-logo-150.png -------------------------------------------------------------------------------- /images/logo/eureka-logo-2624.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/eureka/015400c60d3dc730c3fc4871e9b586d3805cce0d/images/logo/eureka-logo-2624.png -------------------------------------------------------------------------------- /images/logo/eureka-logo-300.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/eureka/015400c60d3dc730c3fc4871e9b586d3805cce0d/images/logo/eureka-logo-300.png -------------------------------------------------------------------------------- /images/logo/eureka-logo-600.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/eureka/015400c60d3dc730c3fc4871e9b586d3805cce0d/images/logo/eureka-logo-600.png -------------------------------------------------------------------------------- /images/logo/eureka-logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/eureka/015400c60d3dc730c3fc4871e9b586d3805cce0d/images/logo/eureka-logo.ai -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name='eureka' 2 | include 'eureka-client', 3 | 'eureka-client-jersey2', 4 | 'eureka-client-archaius2', 5 | 'eureka-server', 6 | 'eureka-server-governator', 7 | 'eureka-core', 8 | 'eureka-core-jersey2', 9 | 'eureka-resources', 10 | 'eureka-examples', 11 | 'eureka-test-utils' 12 | --------------------------------------------------------------------------------