package netflix.ocelli.eureka2;
import com.netflix.eureka2.client.EurekaInterestClient;
import com.netflix.eureka2.client.Eurekas;
import com.netflix.eureka2.client.resolver.ServerResolver;
import com.netflix.eureka2.interests.ChangeNotification;
import com.netflix.eureka2.interests.Interest;
import com.netflix.eureka2.interests.Interests;
import com.netflix.eureka2.registry.instance.InstanceInfo;
import com.netflix.eureka2.registry.instance.ServicePort;
import netflix.ocelli.Instance;
import netflix.ocelli.InstanceManager;
import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.Subscriber;
import rx.functions.Action1;
import rx.functions.Func1;
import javax.inject.Inject;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.HashSet;
/**
* @author Nitesh Kant
*/
public class Eureka2InterestManager {
private final EurekaInterestClient client;
private static final DefaultMapper defaultMapper = new DefaultMapper();
public Eureka2InterestManager(ServerResolver eurekaResolver) {
client = Eurekas.newInterestClientBuilder().withServerResolver(eurekaResolver).build();
}
@Inject
public Eureka2InterestManager(EurekaInterestClient client) {
this.client = client;
}
public Observable<Instance<SocketAddress>> forVip(String... vips) {
return forInterest(Interests.forVips(vips));
}
public Observable<Instance<SocketAddress>> forInterest(Interest<InstanceInfo> interest) {
return forInterest(interest, defaultMapper);
}
public Observable<Instance<SocketAddress>> forInterest(final Interest<InstanceInfo> interest,
final Func1<InstanceInfo, SocketAddress> instanceInfoToHost) {
return Observable.create(new OnSubscribe<Instance<SocketAddress>>() {
@Override
public void call(Subscriber<? super Instance<SocketAddress>> s) {
final InstanceManager<SocketAddress> subject = InstanceManager.create();
s.add(client
.forInterest(interest)
.subscribe(new Action1<ChangeNotification<InstanceInfo>>() {
@Override
public void call(ChangeNotification<InstanceInfo> notification) {
SocketAddress host = instanceInfoToHost.call(notification.getData());
switch (notification.getKind()) {
case Add:
subject.add(host);
break;
case Delete:
subject.remove(host);
break;
case Modify:
subject.remove(host);
subject.add(host);
break;
default:
break;
}
}
}));
subject.subscribe(s);
}
});
}
protected static class DefaultMapper implements Func1<InstanceInfo, SocketAddress> {
@Override
public SocketAddress call(InstanceInfo instanceInfo) {
String ipAddress = instanceInfo.getDataCenterInfo().getDefaultAddress().getIpAddress();
HashSet<ServicePort> servicePorts = instanceInfo.getPorts();
ServicePort portToUse = servicePorts.iterator().next();
return new InetSocketAddress(ipAddress, portToUse.getPort());
}
}
}