Skip to content

Commit

Permalink
First pass at eureka extention providing Guice bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
elandau committed Jan 16, 2014
1 parent 8c5d7c8 commit 9f62daa
Show file tree
Hide file tree
Showing 6 changed files with 487 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Thumbs.db
*/target
/build
*/build
/bin
*/bin
#
# # IntelliJ specific files/directories

Expand Down
20 changes: 16 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
ext.githubProjectName = 'eureka'

ext {
jerseyVersion="1.11"
governatorVersion="1.2.5"
}

buildscript {
repositories {
mavenLocal()
Expand Down Expand Up @@ -36,8 +41,8 @@ project(':eureka-client') {
compile 'com.netflix.archaius:archaius-core:0.3.3'
compile 'javax.ws.rs:jsr311-api:1.1.1'
compile 'com.netflix.servo:servo-core:0.4.36'
compile 'com.sun.jersey:jersey-core:1.11'
compile 'com.sun.jersey:jersey-client:1.11'
compile "com.sun.jersey:jersey-core:$jerseyVersion"
compile "com.sun.jersey:jersey-client:$jerseyVersion"
compile 'com.sun.jersey.contribs:jersey-apache-client4:1.8'
compile 'org.apache.httpcomponents:httpclient:4.1.2'
compile 'com.netflix.ribbon:ribbon-httpclient:0.3.4'
Expand Down Expand Up @@ -68,6 +73,13 @@ project(':eureka-core') {
project(':eureka-resources') {
}

project(':eureka-governator') {
dependencies {
compile project(':eureka-client')
compile project(':eureka-core')
compile "com.netflix.governator:governator:$governatorVersion"
}
}

project(':eureka-server') {
apply plugin: 'war'
Expand All @@ -90,8 +102,8 @@ project(':eureka-server') {
compile project(':eureka-core')
runtime 'xerces:xercesImpl:2.4.0'
runtime 'asm:asm:3.1'
compile 'com.sun.jersey:jersey-server:1.11'
compile 'com.sun.jersey:jersey-servlet:1.11'
compile "com.sun.jersey:jersey-server:$jerseyVersion"
compile "com.sun.jersey:jersey-servlet:$jerseyVersion"
compile 'org.slf4j:slf4j-log4j12:1.6.1'
runtime 'org.codehaus.jettison:jettison:1.2'
providedCompile 'javax.servlet:servlet-api:2.4'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.netflix.discovery;

import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.governator.annotations.Configuration;
import com.netflix.governator.annotations.binding.Background;
import com.netflix.governator.annotations.binding.UpStatus;

/**
* Background task for checking the up status of the instance in discovery.
* It's important to check against the instance's status in discovery instead
* of an internally managed state since an instance can be disabled externally
* in Eureka.
*
* @author elandau
*
*/
@Singleton
public class DiscoveryStatusChecker {
private static Logger LOG = LoggerFactory.getLogger(DiscoveryStatusChecker.class);

private final ScheduledExecutorService executor;
private final Provider<DiscoveryClient> discoveryClientProvider;
private final Provider<InstanceInfo> instanceInfoProvider;
private final AtomicBoolean upStatus;

@Configuration(value="discovery.status.interval")
private long interval = 1;

private ScheduledFuture<?> future = null;

/**
* @param executor
* @param upStatus
* @param discoveryClientProvider Provider that returns a discovery client. We use a provider
* because the DiscoveryClient reference may not exist at bootstrap time
*/
@Inject
public DiscoveryStatusChecker(
@Background ScheduledExecutorService executor,
@UpStatus AtomicBoolean upStatus,
Provider<DiscoveryClient> discoveryClientProvider,
Provider<InstanceInfo> instanceInfoProvider) {
this.executor = executor;
this.discoveryClientProvider = discoveryClientProvider;
this.upStatus = upStatus;
this.instanceInfoProvider = instanceInfoProvider;
}

@PostConstruct
public void init() {
LOG.info("Updating internal instance discovery up status every " + interval + " seconds");

updateInstanceUpStatus();
this.future = executor.scheduleAtFixedRate(new Runnable(){
@Override
public void run() {
updateInstanceUpStatus();
}}, interval, interval, TimeUnit.SECONDS);
}

@PreDestroy
public void shutdown() {
if (future != null)
future.cancel(true);
}

private void updateInstanceUpStatus() {
DiscoveryClient client = discoveryClientProvider.get();
if (client != null) {
final InstanceInfo instanceInfo = instanceInfoProvider.get();
if (instanceInfo != null) {
List<InstanceInfo> discoveryInstanceInfoList = client.getInstancesById(instanceInfo.getId());
final boolean currentStatus;
if ((discoveryInstanceInfoList != null) && (discoveryInstanceInfoList.size() == 1)) {
InstanceInfo discoveryInstanceInfo = discoveryInstanceInfoList.get(0);
currentStatus = InstanceStatus.UP.equals(discoveryInstanceInfo.getStatus());
}
else {
LOG.info("Instance not found");
currentStatus = false;
}

LOG.info("Discovery upStatus=" + currentStatus);

if (upStatus.compareAndSet(!currentStatus, currentStatus)) {
// TODO: Add subscribers
}
}
else {
LOG.info("Discovery InstanceInfo is null");
}
}
else {
LOG.info("Discovery client is null");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.netflix.discovery;

import java.util.concurrent.atomic.AtomicBoolean;

import com.google.common.base.Supplier;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.governator.annotations.binding.DownStatus;
import com.netflix.governator.annotations.binding.UpStatus;

/**
* Guice module that provides specific bindings to Eureka components.
*
* Available bindings are,
*
* @UpStatus AtomicBoolean upStatus
* @UpStatus Supplier<Boolean> upStatus
* @DownStatus Supplier<Boolean> upStatus
* DiscoveryClient
* InstanceInfo
*
* @author elandau
*
*/
public class EurekaModule extends AbstractModule {

private AtomicBoolean upStatus = new AtomicBoolean();

@Override
protected void configure() {
bind(AtomicBoolean.class)
.annotatedWith(UpStatus.class)
.toInstance(upStatus);

bind(new TypeLiteral<Supplier<Boolean>>() {})
.annotatedWith(UpStatus.class)
.toInstance(new Supplier<Boolean>() {
@Override
public Boolean get() {
return upStatus.get();
}
});

bind(new TypeLiteral<Supplier<Boolean>>() {})
.annotatedWith(DownStatus.class)
.toInstance(new Supplier<Boolean>() {
@Override
public Boolean get() {
return !upStatus.get();
}
});

bind(DiscoveryStatusChecker.class);
}

@Provides
@Singleton
public DiscoveryClient getDiscoveryClient() {
return DiscoveryManager.getInstance().getDiscoveryClient();
}

@Provides
@Singleton
public InstanceInfo getInstanceInfo() {
return ApplicationInfoManager.getInstance().getInfo();
}

}
Loading

0 comments on commit 9f62daa

Please sign in to comment.