package com.netflix.loadbalancer;
import static org.junit.Assert.assertEquals;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.Subscriber;
import com.google.common.collect.Lists;
import com.netflix.client.RetryHandler;
import com.netflix.loadbalancer.reactive.LoadBalancerCommand;
import com.netflix.loadbalancer.reactive.ServerOperation;
public class LoadBalancerCommandTest {
static Server server1 = new Server("1", 80);
static Server server2 = new Server("2", 80);
static Server server3 = new Server("3", 80);
static List<Server> list = Lists.newArrayList(server1, server2, server3);
@Test
public void testRetrySameServer() {
BaseLoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(list);
RetryHandler handler = new RetryHandler() {
@Override
public boolean isRetriableException(Throwable e, boolean sameServer) {
return (e instanceof IllegalArgumentException);
}
@Override
public boolean isCircuitTrippingException(Throwable e) {
return false;
}
@Override
public int getMaxRetriesOnSameServer() {
return 3;
}
@Override
public int getMaxRetriesOnNextServer() {
return 0;
}
};
LoadBalancerCommand<String> command = LoadBalancerCommand.<String>builder()
.withLoadBalancer(loadBalancer)
.withRetryHandler(handler)
.withServer(server1)
.build();
ServerOperation<String> operation = new ServerOperation<String>() {
AtomicInteger count = new AtomicInteger();
@Override
public Observable<String> call(final Server server) {
return Observable.create(new OnSubscribe<String>(){
@Override
public void call(Subscriber<? super String> t1) {
if (count.incrementAndGet() < 3) {
t1.onError(new IllegalArgumentException());
} else {
t1.onNext(server.getHost());
t1.onCompleted();
}
}
});
}
};
String result = command.submit(operation).toBlocking().single();
assertEquals(3, loadBalancer.getLoadBalancerStats().getSingleServerStat(server1).getTotalRequestsCount());
assertEquals("1", result);
}
@Test
public void testRetryNextServer() {
BaseLoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(list);
RetryHandler handler = new RetryHandler() {
@Override
public boolean isRetriableException(Throwable e, boolean sameServer) {
return (e instanceof IllegalArgumentException);
}
@Override
public boolean isCircuitTrippingException(Throwable e) {
return false;
}
@Override
public int getMaxRetriesOnSameServer() {
return 1;
}
@Override
public int getMaxRetriesOnNextServer() {
return 5;
}
};
ServerOperation<String> operation = new ServerOperation<String>() {
AtomicInteger count = new AtomicInteger();
@Override
public Observable<String> call(final Server server) {
return Observable.create(new OnSubscribe<String>(){
@Override
public void call(Subscriber<? super String> t1) {
if (count.incrementAndGet() < 3) {
t1.onError(new IllegalArgumentException());
} else {
t1.onNext(server.getHost());
t1.onCompleted();
}
}
});
}
};
LoadBalancerCommand<String> command = LoadBalancerCommand.<String>builder()
.withLoadBalancer(loadBalancer)
.withRetryHandler(handler)
.build();
String result = command.submit(operation).toBlocking().single();
assertEquals("3", result); // server2 is picked first
assertEquals(1, loadBalancer.getLoadBalancerStats().getSingleServerStat(server3).getTotalRequestsCount());
}
}