/*
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.feign.ribbon;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.LoadBalancerStats;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerStats;
import feign.Client;
import feign.Request;
import feign.Request.Options;
import feign.RequestTemplate;
import org.hamcrest.CustomMatcher;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* @author Dave Syer
* @author Spencer Gibb
*/
public class FeignRibbonClientTests {
private AbstractLoadBalancer loadBalancer = mock(AbstractLoadBalancer.class);
private Client delegate = mock(Client.class);
private RibbonLoadBalancedRetryPolicyFactory retryPolicyFactory = mock(RibbonLoadBalancedRetryPolicyFactory.class);
private SpringClientFactory factory = new SpringClientFactory() {
@Override
public IClientConfig getClientConfig(String name) {
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.set(CommonClientConfigKey.ConnectTimeout, 1000);
config.set(CommonClientConfigKey.ReadTimeout, 500);
return config;
}
@Override
public <C> C getInstance(String name, Class<C> type) {
if (type.isAssignableFrom(ServerIntrospector.class)) {
@SuppressWarnings("unchecked")
C instance = (C) new DefaultServerIntrospector();
return instance;
}
return null;
}
@Override
public ILoadBalancer getLoadBalancer(String name) {
return FeignRibbonClientTests.this.loadBalancer;
}
};
// Even though we don't maintain FeignRibbonClient, keep these tests
// around to make sure the expected behaviour doesn't break
private Client client = new LoadBalancerFeignClient(this.delegate, new CachingSpringLoadBalancerFactory(this.factory,
retryPolicyFactory), this.factory);
@Before
public void init() {
when(this.loadBalancer.chooseServer(any())).thenReturn(
new Server("foo.com", 8000));
//to fix NPE
LoadBalancerStats stats = mock(LoadBalancerStats.class);
when(this.loadBalancer.getLoadBalancerStats()).thenReturn(stats);
when(stats.getSingleServerStat(any(Server.class))).thenReturn(mock(ServerStats.class));
}
@Test
public void remoteRequestIsSent() throws Exception {
Request request = new RequestTemplate().method("GET").append("http://foo/")
.request();
this.client.execute(request, new Options());
RequestMatcher matcher = new RequestMatcher("http://foo.com:8000/");
verify(this.delegate).execute(argThat(matcher),
any(Options.class));
}
@Test
public void remoteRequestIsSecure() throws Exception {
Request request = new RequestTemplate().method("GET").append("https://foo/")
.request();
this.client.execute(request, new Options());
RequestMatcher matcher = new RequestMatcher("https://foo.com:8000/");
verify(this.delegate).execute(argThat(matcher),
any(Options.class));
}
private final static class RequestMatcher extends CustomMatcher<Request> {
private String url;
private RequestMatcher(String url) {
super("request has URI: " + url);
this.url = url;
}
@Override
public boolean matches(Object item) {
Request request = (Request) item;
return request.url().equals(this.url);
}
}
}