This commit is contained in:
Coramo
2016-08-12 11:00:43 +08:00
104 changed files with 1787 additions and 862 deletions

View File

@@ -59,6 +59,11 @@ public @interface FeignClient {
*/
@AliasFor("value")
String name() default "";
/**
* Sets the <code>@Qualifier</code> value for the feign client.
*/
String qualifier() default "";
/**
* An absolute URL or resolvable hostname (the protocol is optional).

View File

@@ -184,6 +184,12 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
String alias = name + "FeignClient";
AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
beanDefinition.setPrimary(true);
String qualifier = getQualifier(attributes);
if (StringUtils.hasText(qualifier)) {
alias = qualifier;
}
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className,
new String[] { alias });
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
@@ -317,6 +323,17 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
}
return basePackages;
}
private String getQualifier(Map<String, Object> client) {
if (client == null) {
return null;
}
String qualifier = (String) client.get("qualifier");
if (StringUtils.hasText(qualifier)) {
return qualifier;
}
return null;
}
private String getClientName(Map<String, Object> client) {
if (client == null) {

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2013-2016 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.hystrix.security;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration.HystrixSecurityCondition;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContext;
import com.netflix.hystrix.Hystrix;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
/**
* @author Daniel Lavoie
*/
@Configuration
@Conditional(HystrixSecurityCondition.class)
@ConditionalOnClass({ Hystrix.class, SecurityContext.class })
public class HystrixSecurityAutoConfiguration {
@Autowired(required = false)
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
@PostConstruct
public void init() {
// Keeps references of existing Hystrix plugins.
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
.getEventNotifier();
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
.getMetricsPublisher();
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
.getPropertiesStrategy();
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance()
.getCommandExecutionHook();
HystrixPlugins.reset();
// Registers existing plugins excepts the Concurrent Strategy plugin.
HystrixPlugins.getInstance().registerConcurrencyStrategy(
new SecurityContextConcurrencyStrategy(existingConcurrencyStrategy));
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
}
static class HystrixSecurityCondition extends AllNestedConditions {
public HystrixSecurityCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = true)
static class HystrixEnabled {
}
@ConditionalOnProperty(name = "hystrix.shareSecurityContext")
static class ShareSecurityContext {
}
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2013-2016 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.hystrix.security;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.springframework.security.concurrent.DelegatingSecurityContextCallable;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
import com.netflix.hystrix.strategy.properties.HystrixProperty;
/**
* @author daniellavoie
*/
public class SecurityContextConcurrencyStrategy extends HystrixConcurrencyStrategy {
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
public SecurityContextConcurrencyStrategy(
HystrixConcurrencyStrategy existingConcurrencyStrategy) {
this.existingConcurrencyStrategy = existingConcurrencyStrategy;
}
@Override
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getBlockingQueue(maxQueueSize)
: super.getBlockingQueue(maxQueueSize);
}
@Override
public <T> HystrixRequestVariable<T> getRequestVariable(
HystrixRequestVariableLifecycle<T> rv) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getRequestVariable(rv)
: super.getRequestVariable(rv);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
HystrixProperty<Integer> corePoolSize,
HystrixProperty<Integer> maximumPoolSize,
HystrixProperty<Integer> keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize,
maximumPoolSize, keepAliveTime, unit, workQueue)
: super.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize,
keepAliveTime, unit, workQueue);
}
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy
.wrapCallable(new DelegatingSecurityContextCallable<T>(callable))
: super.wrapCallable(new DelegatingSecurityContextCallable<T>(callable));
}
}

View File

@@ -13,6 +13,8 @@
package org.springframework.cloud.netflix.metrics;
import java.util.ArrayList;
import org.aspectj.lang.JoinPoint;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -25,6 +27,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@@ -80,8 +83,8 @@ public class MetricsInterceptorConfiguration {
return new MetricsInterceptorPostProcessor();
}
private static class MetricsInterceptorPostProcessor implements
BeanPostProcessor, ApplicationContextAware {
private static class MetricsInterceptorPostProcessor
implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext context;
private MetricsClientHttpRequestInterceptor interceptor;
@@ -97,7 +100,12 @@ public class MetricsInterceptorConfiguration {
this.interceptor = this.context
.getBean(MetricsClientHttpRequestInterceptor.class);
}
((RestTemplate) bean).getInterceptors().add(interceptor);
RestTemplate restTemplate = (RestTemplate) bean;
// create a new list as the old one may be unmodifiable (ie Arrays.asList())
ArrayList<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(interceptor);
interceptors.addAll(restTemplate.getInterceptors());
restTemplate.setInterceptors(interceptors);
}
return bean;
}

View File

@@ -200,7 +200,7 @@ public class RibbonClientConfiguration {
public URI reconstructURIWithServer(Server server, URI original) {
String scheme = original.getScheme();
if (!"https".equals(scheme) && this.serverIntrospector.isSecure(server)) {
original = UriComponentsBuilder.fromUri(original).scheme("https").build()
original = UriComponentsBuilder.fromUri(original).scheme("https").build(true)
.toUri();
}
return super.reconstructURIWithServer(server, original);

View File

@@ -48,7 +48,7 @@ public class ZuulProperties {
* duplicated if the proxy and the backend are secured with Spring. By default they
* are added to the ignored headers if Spring Security is present.
*/
private static final List<String> SECURITY_HEADERS = Arrays.asList("Pragma",
public static final List<String> SECURITY_HEADERS = Arrays.asList("Pragma",
"Cache-Control", "X-Frame-Options", "X-Content-Type-Options",
"X-XSS-Protection", "Expires");

View File

@@ -26,6 +26,8 @@ import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
@@ -57,13 +59,19 @@ import com.netflix.zuul.http.ServletInputStreamWrapper;
public class FormBodyWrapperFilter extends ZuulFilter {
private Field requestField;
private Field servletRequestField;
public FormBodyWrapperFilter() {
this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class,
"req", HttpServletRequest.class);
this.servletRequestField = ReflectionUtils.findField(ServletRequestWrapper.class,
"request", ServletRequest.class);
Assert.notNull(this.requestField,
"HttpServletRequestWrapper.req field not found");
Assert.notNull(this.servletRequestField,
"ServletRequestWrapper.request field not found");
this.requestField.setAccessible(true);
this.servletRequestField.setAccessible(true);
}
@Override
@@ -113,6 +121,9 @@ public class FormBodyWrapperFilter extends ZuulFilter {
.getField(this.requestField, request);
wrapper = new FormBodyRequestWrapper(wrapped);
ReflectionUtils.setField(this.requestField, request, wrapper);
if(request instanceof ServletRequestWrapper) {
ReflectionUtils.setField(this.servletRequestField, request, wrapper);
}
}
else {
wrapper = new FormBodyRequestWrapper(request);
@@ -159,6 +170,11 @@ public class FormBodyWrapperFilter extends ZuulFilter {
}
return this.contentLength;
}
@Override
public long getContentLengthLong() {
return getContentLength();
}
@Override
public ServletInputStream getInputStream() throws IOException {
@@ -184,10 +200,10 @@ public class FormBodyWrapperFilter extends ZuulFilter {
MultipartRequest multi = (MultipartRequest) this.request;
for (Entry<String, List<MultipartFile>> parts : multi
.getMultiFileMap().entrySet()) {
for (Part file : this.request.getParts()) {
for (MultipartFile file : parts.getValue()) {
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData(file.getName(),
file.getSubmittedFileName());
file.getOriginalFilename());
if (file.getContentType() != null) {
headers.setContentType(
MediaType.valueOf(file.getContentType()));

View File

@@ -74,9 +74,9 @@ public abstract class AbstractRibbonCommand<LBC extends AbstractLoadBalancerAwar
@Override
protected ClientHttpResponse run() throws Exception {
final RequestContext context = RequestContext.getCurrentContext();
String contentLengthHeader = context.getRequest().getHeader("Content-Length");
if (StringUtils.hasText(contentLengthHeader)) {
this.context.setContentLength(new Long(contentLengthHeader));
long contentLength = context.getRequest().getContentLengthLong();
if (contentLength != -1) {
this.context.setContentLength(contentLength);
}
RQ request = createRequest();

View File

@@ -5,6 +5,7 @@ org.springframework.cloud.netflix.feign.FeignAutoConfiguration,\
org.springframework.cloud.netflix.feign.encoding.FeignAcceptGzipEncodingAutoConfiguration,\
org.springframework.cloud.netflix.feign.encoding.FeignContentGzipEncodingAutoConfiguration,\
org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\
org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration,\
org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration,\
org.springframework.cloud.netflix.rx.RxJavaAutoConfiguration,\
org.springframework.cloud.netflix.metrics.servo.ServoMetricsAutoConfiguration

View File

@@ -27,7 +27,7 @@ import com.netflix.config.ConfigurationManager;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

View File

@@ -20,7 +20,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
@@ -42,7 +42,7 @@ import feign.slf4j.Slf4jLogger;
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = EnableFeignClientsTests.PlainConfiguration.class)
@SpringBootTest(classes = EnableFeignClientsTests.PlainConfiguration.class)
@DirtiesContext
public class EnableFeignClientsTests {

View File

@@ -16,11 +16,15 @@
package org.springframework.cloud.netflix.feign;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
@@ -33,10 +37,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import feign.Contract;
import feign.Feign;
import feign.Logger;
@@ -56,7 +56,7 @@ import feign.slf4j.Slf4jLogger;
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FeignClientOverrideDefaultsTests.TestConfiguration.class)
@SpringBootTest(classes = FeignClientOverrideDefaultsTests.TestConfiguration.class)
@DirtiesContext
public class FeignClientOverrideDefaultsTests {

View File

@@ -31,8 +31,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
@@ -55,8 +55,7 @@ import lombok.NoArgsConstructor;
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FeignHttpClientUrlTests.TestConfig.class)
@WebIntegrationTest(value = {
@SpringBootTest(classes = FeignHttpClientUrlTests.TestConfig.class, webEnvironment = WebEnvironment.DEFINED_PORT, value = {
"spring.application.name=feignclienturltest", "feign.hystrix.enabled=false",
"feign.okhttp.enabled=false" })
@DirtiesContext
@@ -98,12 +97,15 @@ public class FeignHttpClientUrlTests {
public Targeter feignTargeter() {
return new Targeter() {
@Override
public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, Target.HardCodedTarget<T> target) {
Field field = ReflectionUtils.findField(Feign.Builder.class, "client");
public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign,
FeignContext context, Target.HardCodedTarget<T> target) {
Field field = ReflectionUtils.findField(Feign.Builder.class,
"client");
ReflectionUtils.makeAccessible(field);
Client client = (Client) ReflectionUtils.getField(field, feign);
if (target.name().equals("localappurl")) {
assertThat("client was wrong type", client, is(instanceOf(ApacheHttpClient.class)));
assertThat("client was wrong type", client,
is(instanceOf(ApacheHttpClient.class)));
}
return feign.target(target);
}

View File

@@ -16,43 +16,40 @@
package org.springframework.cloud.netflix.feign;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringDecoderTests.Application.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "spring.application.name=springdecodertest",
"spring.jmx.enabled=true" })
@SpringBootTest(classes = SpringDecoderTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=springdecodertest", "spring.jmx.enabled=true" })
@DirtiesContext
public class SpringDecoderTests extends FeignClientFactoryBean {
@@ -83,7 +80,8 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
assertEquals("wrong status code", HttpStatus.OK, response.getStatusCode());
Hello hello = response.getBody();
assertNotNull("hello was null", hello);
assertEquals("first hello didn't match", new Hello("hello world via response"), hello);
assertEquals("first hello didn't match", new Hello("hello world via response"),
hello);
}
@Test
@@ -198,13 +196,14 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
@Override
public ResponseEntity<String> getNotFound() {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body((String)null);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body((String) null);
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=springdecodertest",
"management.contextPath=/admin").run(args);
new SpringApplicationBuilder(Application.class)
.properties("spring.application.name=springdecodertest",
"management.contextPath=/admin")
.run(args);
}
}

View File

@@ -16,6 +16,9 @@
package org.springframework.cloud.netflix.feign.beans;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;
@@ -23,11 +26,12 @@ import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.context.ApplicationContext;
@@ -38,9 +42,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -49,8 +50,7 @@ import lombok.NoArgsConstructor;
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FeignClientTests.Application.class)
@WebIntegrationTest(randomPort = true, value = {
@SpringBootTest(classes = FeignClientTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=feignclienttest",
"logging.level.org.springframework.cloud.netflix.feign.valid=DEBUG",
"feign.httpclient.enabled=false", "feign.okhttp.enabled=false" })
@@ -66,6 +66,7 @@ public class FeignClientTests {
@Autowired
private ApplicationContext context;
@Qualifier("uniquequalifier")
@Autowired
private org.springframework.cloud.netflix.feign.beans.extra.TestClient extraClient;

View File

@@ -21,7 +21,7 @@ import org.springframework.cloud.netflix.feign.beans.FeignClientTests.Hello;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient(value = "otherapp")
@FeignClient(value = "otherapp", qualifier = "uniquequalifier")
public interface TestClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
Hello getHello();

View File

@@ -16,6 +16,9 @@
package org.springframework.cloud.netflix.feign.encoding;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.Collections;
import java.util.List;
@@ -24,8 +27,8 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.encoding.app.client.InvoiceClient;
import org.springframework.cloud.netflix.feign.encoding.app.domain.Invoice;
@@ -35,23 +38,18 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Tests the response compression.
*
* @author Jakub Narloch
*/
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "feign.compression.response.enabled=true" })
@SpringApplicationConfiguration(classes = { FeignAcceptEncodingTests.Application.class })
@SpringBootTest(classes = FeignAcceptEncodingTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"feign.compression.response.enabled=true" })
@RunWith(SpringJUnit4ClassRunner.class)
public class FeignAcceptEncodingTests {

View File

@@ -16,6 +16,9 @@
package org.springframework.cloud.netflix.feign.encoding;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.Collections;
import java.util.List;
@@ -24,8 +27,8 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.encoding.app.client.InvoiceClient;
import org.springframework.cloud.netflix.feign.encoding.app.domain.Invoice;
@@ -35,25 +38,20 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Tests the response compression.
*
* @author Jakub Narloch
*/
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "feign.compression.request.enabled=true",
@SpringBootTest(classes = FeignContentEncodingTest.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"feign.compression.request.enabled=true",
"hystrix.command.default.execution.isolation.strategy=SEMAPHORE",
"ribbon.OkToRetryOnAllOperations=false" })
@SpringApplicationConfiguration(classes = { FeignContentEncodingTest.Application.class })
@RunWith(SpringJUnit4ClassRunner.class)
public class FeignContentEncodingTest {

View File

@@ -16,14 +16,17 @@
package org.springframework.cloud.netflix.feign.ribbon;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
@@ -43,17 +46,11 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* @author Venil Noronha
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FeignRibbonClientPathTests.Application.class)
@WebIntegrationTest(
randomPort = true,
value = {
@SpringBootTest(classes = FeignRibbonClientPathTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT,value = {
"spring.application.name=feignribbonclientpathtest",
"feign.okhttp.enabled=false",
"feign.httpclient.enabled=false",

View File

@@ -16,6 +16,10 @@
package org.springframework.cloud.netflix.feign.ribbon;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.concurrent.atomic.AtomicInteger;
@@ -26,8 +30,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
@@ -47,19 +51,14 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* Tests the Feign Retryer, not ribbon retry.
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FeignRibbonClientRetryTests.Application.class)
@WebIntegrationTest(randomPort = true, value = { "spring.application.name=feignclientretrytest",
"feign.okhttp.enabled=false", "feign.httpclient.enabled=false",
"feign.hystrix.enabled=false", })
@SpringBootTest(classes = FeignRibbonClientRetryTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=feignclientretrytest", "feign.okhttp.enabled=false",
"feign.httpclient.enabled=false", "feign.hystrix.enabled=false", })
@DirtiesContext
public class FeignRibbonClientRetryTests {
@@ -98,10 +97,10 @@ public class FeignRibbonClientRetryTests {
}
public static void main(String[] args) throws InterruptedException {
new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=feignclientretrytest",
"management.contextPath=/admin"
).run(args);
new SpringApplicationBuilder(Application.class)
.properties("spring.application.name=feignclientretrytest",
"management.contextPath=/admin")
.run(args);
}
}

View File

@@ -16,12 +16,14 @@
package org.springframework.cloud.netflix.feign.ribbon;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.feign.FeignContext;
@@ -34,16 +36,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
import static org.junit.Assert.assertEquals;
import feign.Request;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = LoadBalancerFeignClientOverrideTests.TestConfiguration.class)
@WebIntegrationTest(randomPort = true, value = {
@SpringBootTest(classes = LoadBalancerFeignClientOverrideTests.TestConfiguration.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=loadBalancerFeignClientTests",
"feign.httpclient.enabled=false", "feign.okhttp.enabled=false" })
@DirtiesContext

View File

@@ -1,5 +1,9 @@
package org.springframework.cloud.netflix.feign.support;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Collection;
@@ -10,8 +14,8 @@ import org.mockito.ArgumentMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.FeignContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -24,13 +28,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RestController;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import feign.RequestTemplate;
import lombok.Data;
@@ -38,10 +37,8 @@ import lombok.Data;
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringEncoderTests.Application.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "spring.application.name=springencodertest",
"spring.jmx.enabled=true" })
@SpringBootTest(classes = SpringEncoderTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=springencodertest", "spring.jmx.enabled=true" })
@DirtiesContext
public class SpringEncoderTests {

View File

@@ -16,6 +16,14 @@
package org.springframework.cloud.netflix.feign.valid;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.text.ParseException;
@@ -33,8 +41,8 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.feign.FeignFormatterRegistrar;
@@ -72,24 +80,15 @@ import lombok.NoArgsConstructor;
import rx.Observable;
import rx.Single;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* @author Spencer Gibb
* @author Jakub Narloch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FeignClientTests.Application.class)
@WebIntegrationTest(randomPort = true, value = {
@SpringBootTest(classes = FeignClientTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=feignclienttest",
"logging.level.org.springframework.cloud.netflix.feign.valid=DEBUG",
"feign.httpclient.enabled=false", "feign.okhttp.enabled=false"})
"feign.httpclient.enabled=false", "feign.okhttp.enabled=false" })
@DirtiesContext
public class FeignClientTests {
@@ -167,18 +166,15 @@ public class FeignClientTests {
HystrixCommand<List<Hello>> getHellosHystrix();
@RequestMapping(method = RequestMethod.GET, path = "/noContent")
ResponseEntity noContent();
ResponseEntity<Void> noContent();
@RequestMapping(method = RequestMethod.HEAD, path = "/head")
ResponseEntity head();
ResponseEntity<Void> head();
@RequestMapping(method = RequestMethod.GET, path = "/hello")
HttpEntity<Hello> getHelloEntity();
@RequestMapping(method = RequestMethod.POST,
consumes = "application/vnd.io.spring.cloud.test.v1+json",
produces = "application/vnd.io.spring.cloud.test.v1+json",
path = "/complex")
@RequestMapping(method = RequestMethod.POST, consumes = "application/vnd.io.spring.cloud.test.v1+json", produces = "application/vnd.io.spring.cloud.test.v1+json", path = "/complex")
String moreComplexContentType(String body);
@RequestMapping(method = RequestMethod.GET, path = "/tostring")
@@ -271,14 +267,14 @@ public class FeignClientTests {
@Configuration
@EnableAutoConfiguration
@RestController
@EnableFeignClients(clients = {TestClientServiceId.class, TestClient.class, DecodingTestClient.class, HystrixClient.class},
defaultConfiguration = TestDefaultFeignConfig.class)
@EnableFeignClients(clients = { TestClientServiceId.class, TestClient.class,
DecodingTestClient.class,
HystrixClient.class }, defaultConfiguration = TestDefaultFeignConfig.class)
@RibbonClients({
@RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class),
@RibbonClient(name = "localapp1", configuration = LocalRibbonClientConfiguration.class),
@RibbonClient(name = "localapp2", configuration = LocalRibbonClientConfiguration.class),
@RibbonClient(name = "localapp3", configuration = LocalRibbonClientConfiguration.class),
})
@RibbonClient(name = "localapp3", configuration = LocalRibbonClientConfiguration.class), })
protected static class Application {
// needs to be in parent context to test multiple HystrixClient beans
@@ -344,7 +340,8 @@ public class FeignClientTests {
}
@RequestMapping(method = RequestMethod.GET, path = "/helloheadersplaceholders")
public String getHelloHeadersPlaceholders(@RequestHeader("myPlaceholderHeader") String myPlaceholderHeader) {
public String getHelloHeadersPlaceholders(
@RequestHeader("myPlaceholderHeader") String myPlaceholderHeader) {
return myPlaceholderHeader;
}
@@ -354,12 +351,12 @@ public class FeignClientTests {
}
@RequestMapping(method = RequestMethod.GET, path = "/noContent")
ResponseEntity noContent() {
ResponseEntity<Void> noContent() {
return ResponseEntity.noContent().build();
}
@RequestMapping(method = RequestMethod.HEAD, path = "/head")
ResponseEntity head() {
ResponseEntity<Void> head() {
return ResponseEntity.ok().build();
}
@@ -369,14 +366,11 @@ public class FeignClientTests {
}
@RequestMapping(method = RequestMethod.GET, path = "/notFound")
ResponseEntity notFound() {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body((String)null);
ResponseEntity<String> notFound() {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body((String) null);
}
@RequestMapping(method = RequestMethod.POST,
consumes = "application/vnd.io.spring.cloud.test.v1+json",
produces = "application/vnd.io.spring.cloud.test.v1+json",
path = "/complex")
@RequestMapping(method = RequestMethod.POST, consumes = "application/vnd.io.spring.cloud.test.v1+json", produces = "application/vnd.io.spring.cloud.test.v1+json", path = "/complex")
String complex(String body) {
return "{\"value\":\"OK\"}";
}
@@ -392,9 +386,10 @@ public class FeignClientTests {
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=feignclienttest",
"management.contextPath=/admin").run(args);
new SpringApplicationBuilder(Application.class)
.properties("spring.application.name=feignclienttest",
"management.contextPath=/admin")
.run(args);
}
}
@@ -480,7 +475,9 @@ public class FeignClientTests {
public void testHystrixCommand() {
HystrixCommand<List<Hello>> command = this.testClient.getHellosHystrix();
assertNotNull("command was null", command);
assertEquals("Hystrix command group name should match the name of the feign client", "localapp", command.getCommandGroup().name());
assertEquals(
"Hystrix command group name should match the name of the feign client",
"localapp", command.getCommandGroup().name());
List<Hello> hellos = command.execute();
assertNotNull("hellos was null", hellos);
assertEquals("hellos didn't match", hellos, getHelloList());
@@ -497,14 +494,15 @@ public class FeignClientTests {
@Test
public void testNoContentResponse() {
ResponseEntity response = testClient.noContent();
ResponseEntity<Void> response = testClient.noContent();
assertNotNull("response was null", response);
assertEquals("status code was wrong", HttpStatus.NO_CONTENT, response.getStatusCode());
assertEquals("status code was wrong", HttpStatus.NO_CONTENT,
response.getStatusCode());
}
@Test
public void testHeadResponse() {
ResponseEntity response = testClient.head();
ResponseEntity<Void> response = testClient.head();
assertNotNull("response was null", response);
assertEquals("status code was wrong", HttpStatus.OK, response.getStatusCode());
}
@@ -522,14 +520,16 @@ public class FeignClientTests {
public void testMoreComplexHeader() {
String response = testClient.moreComplexContentType("{\"value\":\"OK\"}");
assertNotNull("response was null", response);
assertEquals("didn't respond with {\"value\":\"OK\"}", "{\"value\":\"OK\"}", response);
assertEquals("didn't respond with {\"value\":\"OK\"}", "{\"value\":\"OK\"}",
response);
}
@Test
public void testDecodeNotFound() {
ResponseEntity response = decodingTestClient.notFound();
ResponseEntity<String> response = decodingTestClient.notFound();
assertNotNull("response was null", response);
assertEquals("status code was wrong", HttpStatus.NOT_FOUND, response.getStatusCode());
assertEquals("status code was wrong", HttpStatus.NOT_FOUND,
response.getStatusCode());
assertNull("response body was not null", response.getBody());
}

View File

@@ -29,8 +29,8 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient;
@@ -58,8 +58,7 @@ import lombok.NoArgsConstructor;
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FeignHttpClientTests.Application.class)
@WebIntegrationTest(randomPort = true, value = {
@SpringBootTest(classes = FeignHttpClientTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=feignclienttest", "feign.hystrix.enabled=false",
"feign.okhttp.enabled=false" })
@DirtiesContext

View File

@@ -25,8 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
@@ -48,9 +48,8 @@ import feign.Client;
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FeignClientScanningTests.Application.class)
@WebIntegrationTest(randomPort = true, value = { "spring.application.name=feignclienttest",
"feign.httpclient.enabled=false"})
@SpringBootTest(classes = FeignClientScanningTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=feignclienttest", "feign.httpclient.enabled=false" })
@DirtiesContext
public class FeignClientScanningTests {
@@ -62,8 +61,9 @@ public class FeignClientScanningTests {
@Autowired
private TestClientByKey testClientByKey;
@Autowired
@SuppressWarnings("unused")
private Client feignClient;
@FeignClient("localapp")
@@ -77,7 +77,7 @@ public class FeignClientScanningTests {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
String getHello();
}
@Configuration
@EnableAutoConfiguration
@RestController
@@ -90,9 +90,10 @@ public class FeignClientScanningTests {
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=feignclienttest",
"management.contextPath=/admin").run(args);
new SpringApplicationBuilder(Application.class)
.properties("spring.application.name=feignclienttest",
"management.contextPath=/admin")
.run(args);
}
}
@@ -109,7 +110,7 @@ public class FeignClientScanningTests {
assertNotNull("hello was null", hello);
assertEquals("first hello didn't match", "hello world 1", hello);
}
// Load balancer with fixed server list for "local" pointing to localhost
@Configuration
public static class LocalRibbonClientConfiguration {

View File

@@ -16,6 +16,11 @@
package org.springframework.cloud.netflix.hystrix;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Base64;
import java.util.Map;
import org.junit.Test;
@@ -24,48 +29,50 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = HystrixOnlyApplication.class)
@WebAppConfiguration
@IntegrationTest({ "server.port: 0" })
@SpringBootTest(classes = HystrixOnlyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class HystrixOnlyTests {
@Value("${local.server.port}")
private int port;
@Value("${security.user.username}")
private String username;
@Value("${security.user.password}")
private String password;
@Test
public void testNormalExecution() {
String s = new TestRestTemplate().getForObject("http://localhost:" + this.port
+ "/", String.class);
String s = new TestRestTemplate()
.getForObject("http://localhost:" + this.port + "/", String.class);
assertEquals("incorrect response", "Hello world", s);
}
@Test
public void testFailureFallback() {
String s = new TestRestTemplate().getForObject("http://localhost:" + this.port
+ "/fail", String.class);
String s = new TestRestTemplate()
.getForObject("http://localhost:" + this.port + "/fail", String.class);
assertEquals("incorrect fallback", "Fallback Hello world", s);
}
@@ -85,9 +92,27 @@ public class HystrixOnlyTests {
map.containsKey("discovery"));
}
private Map<?, ?> getHealth() {
return new TestRestTemplate().getForObject("http://localhost:" + this.port
+ "/admin/health", Map.class);
return new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/admin/health", HttpMethod.GET,
new HttpEntity<Void>(createBasicAuthHeader(username, password)),
Map.class).getBody();
}
public static HttpHeaders createBasicAuthHeader(final String username,
final String password) {
return new HttpHeaders() {
private static final long serialVersionUID = 1766341693637204893L;
{
String auth = username + ":" + password;
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
String authHeader = "Basic " + new String(encodedAuth);
this.set("Authorization", authHeader);
}
};
}
}

View File

@@ -16,15 +16,20 @@
package org.springframework.cloud.netflix.hystrix;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import java.net.URL;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -32,23 +37,18 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.InputStream;
import java.net.URL;
import static org.junit.Assert.*;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
/**
* @author Dave Syer
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = HystrixStreamEndpointTests.Application.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "spring.application.name=hystrixstreamtest" })
@SpringBootTest(classes = HystrixStreamEndpointTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=hystrixstreamtest" })
@DirtiesContext
public class HystrixStreamEndpointTests {
@@ -64,8 +64,9 @@ public class HystrixStreamEndpointTests {
@Test
public void hystrixStreamWorks() throws Exception {
String url = "http://localhost:" + port;
//you have to hit a Hystrix circuit breaker before the stream sends anything
ResponseEntity<String> response = new TestRestTemplate().getForEntity(url, String.class);
// you have to hit a Hystrix circuit breaker before the stream sends anything
ResponseEntity<String> response = new TestRestTemplate().getForEntity(url,
String.class);
assertEquals("bad response code", HttpStatus.OK, response.getStatusCode());
URL hystrixUrl = new URL(url + "/admin/hystrix.stream");
@@ -103,4 +104,3 @@ public class HystrixStreamEndpointTests {
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2013-2016 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.hystrix.security;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.security.app.UsernameClient;
import org.springframework.context.annotation.Configuration;
/**
* @author Daniel Lavoie
*/
@Configuration
@SpringBootApplication
@EnableFeignClients(clients = UsernameClient.class)
public class HystrixSecurityApplication {
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2013-2016 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.hystrix.security;
import java.util.Base64;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.hystrix.security.app.CustomConcurrenyStrategy;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.RestTemplate;
/**
* Tests that a secured web service returning values using a feign client properly access
* the security context from a hystrix command.
* @author Daniel Lavoie
*/
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
@SpringBootTest(classes = HystrixSecurityApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = "username.ribbon.listOfServers=localhost:${local.server.port}")
public class HystrixSecurityTests {
@Autowired
private CustomConcurrenyStrategy customConcurrenyStrategy;
@Value("${local.server.port}")
private String serverPort;
@Value("${security.user.username}")
private String username;
@Value("${security.user.password}")
private String password;
@Test
public void testFeignHystrixSecurity() {
HttpHeaders headers = HystrixSecurityTests.createBasicAuthHeader(username,
password);
String usernameResult = new RestTemplate()
.exchange("http://localhost:" + serverPort + "/proxy-username",
HttpMethod.GET, new HttpEntity<Void>(headers), String.class)
.getBody();
Assert.assertTrue("Username should have been intercepted by feign interceptor.",
username.equals(usernameResult));
Assert.assertTrue("Custom hook should have been called.",
customConcurrenyStrategy.isHookCalled());
}
public static HttpHeaders createBasicAuthHeader(final String username,
final String password) {
return new HttpHeaders() {
private static final long serialVersionUID = 1766341693637204893L;
{
String auth = username + ":" + password;
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
String authHeader = "Basic " + new String(encodedAuth);
this.set("Authorization", authHeader);
}
};
}
}

View File

@@ -0,0 +1,23 @@
package org.springframework.cloud.netflix.hystrix.security.app;
import java.util.concurrent.Callable;
import org.springframework.stereotype.Component;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
@Component
public class CustomConcurrenyStrategy extends HystrixConcurrencyStrategy {
private boolean hookCalled;
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
this.hookCalled = true;
return super.wrapCallable(callable);
}
public boolean isHookCalled() {
return hookCalled;
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2013-2016 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.hystrix.security.app;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Daniel Lavoie
*/
@RestController
@RequestMapping("/proxy-username")
public class ProxyUsernameController {
@Autowired
private UsernameClient usernameClient;
@RequestMapping
public String getUsername() {
return usernameClient.getUsername();
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2013-2016 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.hystrix.security.app;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import feign.RequestInterceptor;
import feign.RequestTemplate;
/**
* This interceptor should be called from an Hyxtrix command execution thread. It is
* access the SecurityContext and settings an http header from the authentication details.
*
* @author Daniel Lavoie
*/
@Component
public class TestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
if (SecurityContextHolder.getContext().getAuthentication() != null)
template.header("username",
SecurityContextHolder.getContext().getAuthentication().getName());
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2013-2016 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.hystrix.security.app;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Daniel Lavoie
*/
@FeignClient("username")
public interface UsernameClient {
@RequestMapping("/username")
public String getUsername();
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2013-2016 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.hystrix.security.app;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Daniel Lavoie
*/
@RestController
@RequestMapping("/username")
public class UsernameController {
@RequestMapping
public String getUsername(@RequestHeader String username){
return username;
}
}

View File

@@ -15,12 +15,15 @@ package org.springframework.cloud.netflix.metrics;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.boot.autoconfigure.test.ImportAutoConfiguration;
import org.springframework.cloud.netflix.metrics.servo.ServoMetricsAutoConfiguration;
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
import org.springframework.context.annotation.Bean;
@@ -28,6 +31,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -58,6 +62,9 @@ public class MetricsClientHttpRequestInterceptorTests {
@Autowired
RestTemplate restTemplate;
@Autowired
RestTemplate restTemplateWithFakeInterceptorsList;
@Test
public void metricsGatheredWhenSuccessful() {
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
@@ -79,6 +86,28 @@ public class MetricsClientHttpRequestInterceptorTests {
mockServer.verify();
}
@Test
public void restTemplateWithFakeInterceptorList() {
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplateWithFakeInterceptorsList);
mockServer.expect(MockRestRequestMatchers.requestTo("/test/123"))
.andExpect(MockRestRequestMatchers.method(HttpMethod.GET))
.andRespond(MockRestResponseCreators.withSuccess("OK", MediaType.APPLICATION_JSON));
String s = restTemplate.getForObject("/test/{id}", String.class, 123);
MonitorConfig.Builder builder = new MonitorConfig.Builder("metricName")
.withTag("method", "GET")
.withTag("uri", "_test_-id-")
.withTag("status", "200")
.withTag("clientName", "none");
BasicTimer timer = servoMonitorCache.getTimer(builder.build());
assertEquals(2L, (long) timer.getCount());
assertEquals("OK", s);
mockServer.verify();
}
}
@Configuration
@@ -95,7 +124,15 @@ class MetricsRestTemplateTestConfig {
@Configuration
class MetricsRestTemplateRestTemplateConfig {
@Bean
@Primary
RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean(name="restTemplateWithFakeInterceptorsList")
RestTemplate restTemplateWithFakeInterceptorsList() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Arrays.asList(Mockito.mock(ClientHttpRequestInterceptor.class)));
return restTemplate;
}
}

View File

@@ -13,6 +13,10 @@
package org.springframework.cloud.netflix.metrics;
import static org.junit.Assert.assertFalse;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import javax.servlet.http.HttpServletRequest;
import org.junit.Assert;
@@ -20,8 +24,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.test.ImportAutoConfiguration;
import org.springframework.cloud.netflix.metrics.servo.ServoMetricsAutoConfiguration;
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
import org.springframework.context.annotation.Bean;
@@ -49,10 +53,6 @@ import com.netflix.servo.MonitorRegistry;
import com.netflix.servo.monitor.BasicTimer;
import com.netflix.servo.monitor.MonitorConfig;
import static org.junit.Assert.assertFalse;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Jon Schneider
*/

View File

@@ -16,12 +16,17 @@
package org.springframework.cloud.netflix.metrics;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactory;
import org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactoryTests;
import org.springframework.http.client.ClientHttpRequestFactory;
@@ -31,18 +36,13 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.util.ReflectionTestUtils;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MetricsRestTemplateTests.App.class)
@WebIntegrationTest(value = { "spring.application.name=ribbonclienttest",
"spring.jmx.enabled=true", "ribbon.http.client.enabled=true" }, randomPort = true)
@SpringBootTest(classes = MetricsRestTemplateTests.App.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=ribbonclienttest", "spring.jmx.enabled=true",
"ribbon.http.client.enabled=true" })
@DirtiesContext
public class MetricsRestTemplateTests extends RibbonClientHttpRequestFactoryTests {

View File

@@ -20,7 +20,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@@ -37,7 +37,7 @@ import com.netflix.servo.monitor.DynamicCounter;
/**
* @author Jon Schneider
*/
@SpringApplicationConfiguration(AtlasExporterConfiguration.class)
@SpringBootTest(classes = AtlasExporterConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class AtlasExporterTests {
@Autowired

View File

@@ -16,24 +16,24 @@
package org.springframework.cloud.netflix.metrics.servo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.ExportMetricReader;
import org.springframework.boot.actuate.metrics.reader.MetricReader;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* @author Dave Syer
*/
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration()
public class NoServoMetricsAutoConfigurationTests {
@Autowired(required = false)

View File

@@ -16,23 +16,23 @@
package org.springframework.cloud.netflix.metrics.servo;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.ExportMetricReader;
import org.springframework.boot.actuate.metrics.reader.MetricReader;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertNotNull;
/**
* @author Dave Syer
*/
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration()
public class ServoMetricsAutoConfigurationTests {
@Autowired(required = false)

View File

@@ -1,18 +1,19 @@
package org.springframework.cloud.netflix.metrics.servo;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.OutputCapture;
import org.springframework.boot.test.rule.OutputCapture;
import com.netflix.servo.MonitorRegistry;
import com.netflix.servo.monitor.MonitorConfig;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
/**
* @author Spencer Gibb
*/

View File

@@ -1,5 +1,8 @@
package org.springframework.cloud.netflix.resttemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
@@ -12,8 +15,8 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
@@ -39,12 +42,8 @@ import com.netflix.loadbalancer.ServerList;
import com.netflix.loadbalancer.ServerStats;
import com.netflix.niws.client.http.HttpClientLoadBalancerErrorHandler;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RestTemplateRetryTest.Application.class)
@WebIntegrationTest(randomPort = true, value = {
@SpringBootTest(classes = RestTemplateRetryTest.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=resttemplatetest",
"logging.level.org.springframework.cloud.netflix.resttemplate=DEBUG",
"badClients.ribbon.MaxAutoRetries=0",

View File

@@ -20,7 +20,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.PlainRibbonClientPreprocessorIntegrationTests.TestConfiguration;
import org.springframework.context.annotation.Configuration;
@@ -36,7 +36,7 @@ import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@SpringBootTest(classes = TestConfiguration.class)
@DirtiesContext
public class PlainRibbonClientPreprocessorIntegrationTests {

View File

@@ -16,12 +16,13 @@
package org.springframework.cloud.netflix.ribbon;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfigurationIntegrationTests.TestConfiguration;
import org.springframework.context.annotation.Configuration;
@@ -32,15 +33,12 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@SpringBootTest(classes = TestConfiguration.class, value = {"ribbon.ConnectTimeout=25000"})
@DirtiesContext
@IntegrationTest("ribbon.ConnectTimeout=25000")
public class RibbonAutoConfigurationIntegrationTests {
@Autowired

View File

@@ -16,26 +16,46 @@
package org.springframework.cloud.netflix.ribbon;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import java.net.URI;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.OverrideRestClient;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import org.junit.Test;
import com.netflix.loadbalancer.Server;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;
/**
* @author Spencer Gibb
*/
public class RibbonClientConfigurationTests {
@Test
public void restClientInitCalledOnce() {
CountingConfig config = new CountingConfig();
private CountingConfig config;
@Mock
private ServerIntrospector inspector;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
config = new CountingConfig();
config.setProperty(CommonClientConfigKey.ConnectTimeout, "1");
config.setProperty(CommonClientConfigKey.ReadTimeout, "1");
config.setProperty(CommonClientConfigKey.MaxHttpConnectionsPerHost, "1");
config.setClientName("testClient");
}
@Test
public void restClientInitCalledOnce() {
new TestRestClient(config);
assertThat(config.count, is(equalTo(1)));
}
@@ -44,7 +64,43 @@ public class RibbonClientConfigurationTests {
int count = 0;
}
static class TestRestClient extends RibbonClientConfiguration.OverrideRestClient {
@Test
public void testSecureUriFromClientConfig() throws Exception {
Server server = new Server("foo", 7777);
when(inspector.isSecure(server)).thenReturn(true);
OverrideRestClient overrideRestClient = new OverrideRestClient(this.config,
inspector);
URI uri = overrideRestClient.reconstructURIWithServer(server,
new URI("http://foo/"));
assertThat(uri, is(new URI("https://foo:7777/")));
}
@Test
public void testInSecureUriFromClientConfig() throws Exception {
Server server = new Server("foo", 7777);
when(inspector.isSecure(server)).thenReturn(false);
OverrideRestClient overrideRestClient = new OverrideRestClient(this.config,
inspector);
URI uri = overrideRestClient.reconstructURIWithServer(server,
new URI("http://foo/"));
assertThat(uri, is(new URI("http://foo:7777/")));
}
@Test
public void testNotDoubleEncodedWhenSecure() throws Exception {
Server server = new Server("foo", 7777);
when(inspector.isSecure(server)).thenReturn(true);
OverrideRestClient overrideRestClient = new OverrideRestClient(this.config,
inspector);
URI uri = overrideRestClient.reconstructURIWithServer(server,
new URI("http://foo/%20bar"));
assertThat(uri, is(new URI("https://foo:7777/%20bar")));
}
static class TestRestClient extends OverrideRestClient {
private TestRestClient(IClientConfig ncc) {
super(ncc, new DefaultServerIntrospector());

View File

@@ -16,6 +16,9 @@
package org.springframework.cloud.netflix.ribbon;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.net.URI;
import org.junit.Rule;
@@ -25,8 +28,8 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -51,17 +54,13 @@ import com.netflix.loadbalancer.ServerList;
import lombok.SneakyThrows;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RibbonClientHttpRequestFactoryTests.App.class)
@WebIntegrationTest(value = { "spring.application.name=ribbonclienttest",
"spring.jmx.enabled=true", "spring.cloud.netflix.metrics.enabled=false",
"ribbon.http.client.enabled=true" }, randomPort = true)
@SpringBootTest(classes = RibbonClientHttpRequestFactoryTests.App.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=ribbonclienttest", "spring.jmx.enabled=true",
"spring.cloud.netflix.metrics.enabled=false", "ribbon.http.client.enabled=true" })
@DirtiesContext
public class RibbonClientHttpRequestFactoryTests {
@@ -81,16 +80,16 @@ public class RibbonClientHttpRequestFactoryTests {
@Test
public void vanillaRequestWorks() {
ResponseEntity<String> response = this.restTemplate.getForEntity(
"http://simple/", String.class);
ResponseEntity<String> response = this.restTemplate.getForEntity("http://simple/",
String.class);
assertEquals("wrong response code", HttpStatus.OK, response.getStatusCode());
assertEquals("wrong response body", "hello", response.getBody());
}
@Test
public void requestWithPathParamWorks() {
ResponseEntity<String> response = this.restTemplate.getForEntity(
"http://simple/path/{param}", String.class, "world");
ResponseEntity<String> response = this.restTemplate
.getForEntity("http://simple/path/{param}", String.class, "world");
assertEquals("wrong response code", HttpStatus.OK, response.getStatusCode());
assertEquals("wrong response body", "hello world", response.getBody());
}
@@ -114,16 +113,16 @@ public class RibbonClientHttpRequestFactoryTests {
@Test
public void requestWithPostWorks() {
ResponseEntity<String> response = this.restTemplate.postForEntity(
"http://simple/post", "world", String.class);
ResponseEntity<String> response = this.restTemplate
.postForEntity("http://simple/post", "world", String.class);
assertEquals("wrong response code", HttpStatus.OK, response.getStatusCode());
assertEquals("wrong response body", "hello world", response.getBody());
}
@Test
public void requestWithEmptyPostWorks() {
ResponseEntity<String> response = this.restTemplate.postForEntity(
"http://simple/emptypost", "", String.class);
ResponseEntity<String> response = this.restTemplate
.postForEntity("http://simple/emptypost", "", String.class);
assertEquals("wrong response code", HttpStatus.OK, response.getStatusCode());
assertEquals("wrong response body", "hello empty", response.getBody());
}
@@ -133,8 +132,8 @@ public class RibbonClientHttpRequestFactoryTests {
public void requestWithHeaderWorks() {
RequestEntity<Void> entity = RequestEntity.get(new URI("http://simple/header"))
.header("X-Param", "world").build();
ResponseEntity<String> response = this.restTemplate
.exchange(entity, String.class);
ResponseEntity<String> response = this.restTemplate.exchange(entity,
String.class);
assertEquals("wrong response code", HttpStatus.OK, response.getStatusCode());
assertEquals("wrong response body", "hello world", response.getBody());
}

View File

@@ -20,7 +20,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorIntegrationTests.PlainConfiguration;
import org.springframework.context.annotation.Configuration;
@@ -28,13 +28,17 @@ import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.netflix.loadbalancer.*;
import com.netflix.loadbalancer.ConfigurationBasedServerList;
import com.netflix.loadbalancer.NoOpPing;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
/**
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = PlainConfiguration.class)
@SpringBootTest(classes = PlainConfiguration.class)
@DirtiesContext
public class RibbonClientPreprocessorIntegrationTests {

View File

@@ -16,11 +16,13 @@
package org.springframework.cloud.netflix.ribbon;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.context.annotation.Bean;
@@ -42,13 +44,11 @@ import com.netflix.loadbalancer.ServerList;
import com.netflix.loadbalancer.ServerListFilter;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RibbonClientPreprocessorOverridesIntegrationTests.TestConfiguration.class)
@SpringBootTest(classes = RibbonClientPreprocessorOverridesIntegrationTests.TestConfiguration.class)
@DirtiesContext
public class RibbonClientPreprocessorOverridesIntegrationTests {

View File

@@ -21,20 +21,18 @@ import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
@@ -46,8 +44,8 @@ import com.netflix.client.config.IClientConfig;
* @author Tyler Van Gorder
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RibbonClientPreprocessorOverridesRetryTests.TestConfiguration.class)
@TestPropertySource(properties = { "customRetry.ribbon.MaxAutoRetries=0",
@SpringBootTest(classes = RibbonClientPreprocessorOverridesRetryTests.TestConfiguration.class, value = {
"customRetry.ribbon.MaxAutoRetries=0",
"customRetry.ribbon.MaxAutoRetriesNextServer=1",
"customRetry.ribbon.OkToRetryOnAllOperations=true" })
@DirtiesContext
@@ -64,14 +62,14 @@ public class RibbonClientPreprocessorOverridesRetryTests {
context.getRetryHandler());
Assert.isTrue(context.getRetryHandler().getMaxRetriesOnSameServer() == 0);
Assert.isTrue(context.getRetryHandler().getMaxRetriesOnNextServer() == 1);
Assert.isTrue(context.getRetryHandler().isCircuitTrippingException(
new UnknownHostException("Unknown Host")));
Assert.isTrue(context.getRetryHandler()
.isCircuitTrippingException(new UnknownHostException("Unknown Host")));
}
@Configuration
@RibbonClient(name = "customRetry", configuration = RetryRibbonConfiguration.class)
@Import({ PropertyPlaceholderAutoConfiguration.class,
ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class })
@Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class,
RibbonAutoConfiguration.class })
protected static class TestConfiguration {
}
@@ -87,18 +85,22 @@ class RetryRibbonConfiguration {
class CustomRetryHandler extends DefaultLoadBalancerRetryHandler {
@SuppressWarnings("unchecked")
private List<Class<? extends Throwable>> retriable = new ArrayList(){{
add(UnknownHostException.class);
add(ConnectException.class);
add(SocketTimeoutException.class);
}};
private List<Class<? extends Throwable>> retriable = new ArrayList() {
{
add(UnknownHostException.class);
add(ConnectException.class);
add(SocketTimeoutException.class);
}
};
@SuppressWarnings("unchecked")
private List<Class<? extends Throwable>> circuitRelated = new ArrayList(){{
add(UnknownHostException.class);
add(SocketException.class);
add(SocketTimeoutException.class);
}};
private List<Class<? extends Throwable>> circuitRelated = new ArrayList() {
{
add(UnknownHostException.class);
add(SocketException.class);
add(SocketTimeoutException.class);
}
};
CustomRetryHandler(IClientConfig config) {
super(config);

View File

@@ -16,11 +16,16 @@
package org.springframework.cloud.netflix.ribbon;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assume.assumeThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.test.TestLoadBalancer;
@@ -39,16 +44,11 @@ import com.netflix.loadbalancer.ServerListSubsetFilter;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assume.assumeThat;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(RibbonClientPreprocessorPropertiesOverridesIntegrationTests.TestConfiguration.class)
@SpringBootTest(classes = RibbonClientPreprocessorPropertiesOverridesIntegrationTests.TestConfiguration.class)
@DirtiesContext
public class RibbonClientPreprocessorPropertiesOverridesIntegrationTests {
@@ -62,9 +62,10 @@ public class RibbonClientPreprocessorPropertiesOverridesIntegrationTests {
ZoneAvoidanceRule.class.cast(getLoadBalancer("bar").getRule());
}
//TODO: why do these tests fail in travis?
// TODO: why do these tests fail in travis?
void assumeNotTravis() {
assumeThat("running in travis, skipping", System.getenv("TRAVIS"), is(not(equalTo("true"))));
assumeThat("running in travis, skipping", System.getenv("TRAVIS"),
is(not(equalTo("true"))));
}
@Test
@@ -77,7 +78,8 @@ public class RibbonClientPreprocessorPropertiesOverridesIntegrationTests {
public void serverListOverridesToTest() throws Exception {
assumeNotTravis();
TestServerList.class.cast(getLoadBalancer("foo2").getServerListImpl());
ConfigurationBasedServerList.class.cast(getLoadBalancer("bar").getServerListImpl());
ConfigurationBasedServerList.class
.cast(getLoadBalancer("bar").getServerListImpl());
}
@Test
@@ -101,7 +103,7 @@ public class RibbonClientPreprocessorPropertiesOverridesIntegrationTests {
@Configuration
@RibbonClients
@Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class})
ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class })
protected static class TestConfiguration {
}

View File

@@ -16,11 +16,13 @@
package org.springframework.cloud.netflix.ribbon;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonClientsPreprocessorIntegrationTests.TestConfiguration;
@@ -34,13 +36,11 @@ import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@SpringBootTest(classes = TestConfiguration.class)
@DirtiesContext
public class RibbonClientsPreprocessorIntegrationTests {
@@ -54,21 +54,19 @@ public class RibbonClientsPreprocessorIntegrationTests {
@SuppressWarnings("unchecked")
private ZoneAwareLoadBalancer<Server> getLoadBalancer() {
return (ZoneAwareLoadBalancer<Server>) this.factory
.getLoadBalancer("foo");
return (ZoneAwareLoadBalancer<Server>) this.factory.getLoadBalancer("foo");
}
@Test
public void serverListFilterOverride() throws Exception {
assertEquals("myTestZone",
ZonePreferenceServerListFilter.class.cast(getLoadBalancer().getFilter())
.getZone());
assertEquals("myTestZone", ZonePreferenceServerListFilter.class
.cast(getLoadBalancer().getFilter()).getZone());
}
@Configuration
@RibbonClients(@RibbonClient(name = "foo", configuration = FooConfiguration.class))
@Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class})
ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class })
protected static class TestConfiguration {
}

View File

@@ -19,7 +19,7 @@ package org.springframework.cloud.netflix.ribbon;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.junit.Test;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

View File

@@ -23,8 +23,7 @@ import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.ribbon.test.RibbonClientDefaultConfigurationTestsConfig.BazServiceList;
import org.springframework.test.annotation.DirtiesContext;
@@ -41,8 +40,7 @@ import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RibbonClientDefaultConfigurationTestsConfig.class)
@IntegrationTest("ribbon.eureka.enabled=true")
@SpringBootTest(classes = RibbonClientDefaultConfigurationTestsConfig.class, value = "ribbon.eureka.enabled=true")
@DirtiesContext
public class RibbonClientDefaultConfigurationTests {

View File

@@ -16,6 +16,10 @@
package org.springframework.cloud.netflix.rx;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -25,9 +29,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -35,7 +39,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@@ -44,10 +47,6 @@ import rx.Observable;
import rx.Single;
import rx.functions.Func1;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
/**
* Tests the demonstrate using {@link Observable} with {@link SingleReturnValueHandler} class.
*
@@ -55,9 +54,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
* @author Jakub Narloch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ObservableReturnValueHandlerTest.Application.class)
@WebAppConfiguration
@IntegrationTest({"server.port=0"})
@SpringBootTest(classes = ObservableReturnValueHandlerTest.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class ObservableReturnValueHandlerTest {

View File

@@ -16,6 +16,10 @@
package org.springframework.cloud.netflix.rx;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
@@ -24,15 +28,14 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@@ -43,10 +46,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import rx.Observable;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
/**
* Tests the {@link ObservableSseEmitter} class.
*
@@ -54,88 +53,91 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
* @author Jakub Narloch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ObservableSseEmitterTest.Application.class)
@WebAppConfiguration
@IntegrationTest({"server.port=0"})
@SpringBootTest(classes = ObservableSseEmitterTest.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class ObservableSseEmitterTest {
@Value("${local.server.port}")
private int port = 0;
@Value("${local.server.port}")
private int port = 0;
private TestRestTemplate restTemplate = new TestRestTemplate();
private TestRestTemplate restTemplate = new TestRestTemplate();
@Configuration
@EnableAutoConfiguration
@RestController
protected static class Application {
@Configuration
@EnableAutoConfiguration
@RestController
protected static class Application {
// tag::rx_observable_sse[]
@RequestMapping(method = RequestMethod.GET, value = "/sse")
public SseEmitter single() {
return RxResponse.sse(Observable.just("single value"));
}
@RequestMapping(method = RequestMethod.GET, value = "/sse")
public SseEmitter single() {
return RxResponse.sse(Observable.just("single value"));
}
@RequestMapping(method = RequestMethod.GET, value = "/messages")
public SseEmitter messages() {
return RxResponse.sse(Observable.just("message 1", "message 2", "message 3"));
}
@RequestMapping(method = RequestMethod.GET, value = "/messages")
public SseEmitter messages() {
return RxResponse.sse(Observable.just("message 1", "message 2", "message 3"));
}
@RequestMapping(method = RequestMethod.GET, value = "/events")
public SseEmitter event() {
return RxResponse.sse(APPLICATION_JSON_UTF8, Observable.just(
new EventDto("Spring io", getDate(2016, 5, 19)),
new EventDto("SpringOnePlatform", getDate(2016, 8, 1))
));
}
@RequestMapping(method = RequestMethod.GET, value = "/events")
public SseEmitter event() {
return RxResponse.sse(APPLICATION_JSON_UTF8,
Observable.just(new EventDto("Spring io", getDate(2016, 5, 19)),
new EventDto("SpringOnePlatform", getDate(2016, 8, 1))));
}
// end::rx_observable_sse[]
}
}
@Test
public void shouldRetrieveSse() {
@Test
public void shouldRetrieveSse() {
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/sse"), String.class);
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/sse"),
String.class);
// then
assertNotNull(response);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("data:single value\n\n", response.getBody());
}
// then
assertNotNull(response);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("data:single value\n\n", response.getBody());
}
@Test
public void shouldRetrieveSseWithMultipleMessages() {
@Test
public void shouldRetrieveSseWithMultipleMessages() {
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/messages"), String.class);
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/messages"),
String.class);
// then
assertNotNull(response);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("data:message 1\n\ndata:message 2\n\ndata:message 3\n\n", response.getBody());
}
// then
assertNotNull(response);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("data:message 1\n\ndata:message 2\n\ndata:message 3\n\n",
response.getBody());
}
@Test
public void shouldRetrieveJsonOverSseWithMultipleMessages() {
@Test
public void shouldRetrieveJsonOverSseWithMultipleMessages() {
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/events"), String.class);
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/events"),
String.class);
// then
assertNotNull(response);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("data:{\"name\":\"Spring io\",\"date\":1466337600000}\n\ndata:{\"name\":\"SpringOnePlatform\",\"date\":1472731200000}\n\n", response.getBody());
}
// then
assertNotNull(response);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(
"data:{\"name\":\"Spring io\",\"date\":1466337600000}\n\ndata:{\"name\":\"SpringOnePlatform\",\"date\":1472731200000}\n\n",
response.getBody());
}
private String path(String context) {
return String.format("http://localhost:%d%s", port, context);
}
private String path(String context) {
return String.format("http://localhost:%d%s", port, context);
}
private static Date getDate(int year, int month, int day) {
GregorianCalendar calendar = new GregorianCalendar(year, month, day, 12, 0, 0);
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
return calendar.getTime();
}
private static Date getDate(int year, int month, int day) {
GregorianCalendar calendar = new GregorianCalendar(year, month, day, 12, 0, 0);
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
return calendar.getTime();
}
/**
* A simple DTO used for testing purpose.
@@ -149,7 +151,8 @@ public class ObservableSseEmitterTest {
private final Date date;
@JsonCreator
public EventDto(@JsonProperty("name") String name, @JsonProperty("date") Date date) {
public EventDto(@JsonProperty("name") String name,
@JsonProperty("date") Date date) {
this.name = name;
this.date = date;
}

View File

@@ -16,28 +16,27 @@
package org.springframework.cloud.netflix.rx;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import rx.Single;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Tests the {@link SingleReturnValueHandler} class.
*
@@ -45,76 +44,78 @@ import static org.junit.Assert.assertNotNull;
* @author Jakub Narloch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SingleReturnValueHandlerTest.Application.class)
@WebAppConfiguration
@IntegrationTest({"server.port=0"})
@SpringBootTest(classes = SingleReturnValueHandlerTest.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class SingleReturnValueHandlerTest {
@Value("${local.server.port}")
private int port = 0;
@Value("${local.server.port}")
private int port = 0;
private TestRestTemplate restTemplate = new TestRestTemplate();
private TestRestTemplate restTemplate = new TestRestTemplate();
@Configuration
@EnableAutoConfiguration
@RestController
protected static class Application {
@Configuration
@EnableAutoConfiguration
@RestController
protected static class Application {
// tag::rx_single[]
@RequestMapping(method = RequestMethod.GET, value = "/single")
public Single<String> single() {
return Single.just("single value");
}
@RequestMapping(method = RequestMethod.GET, value = "/single")
public Single<String> single() {
return Single.just("single value");
}
@RequestMapping(method = RequestMethod.GET, value = "/singleWithResponse")
public ResponseEntity<Single<String>> singleWithResponse() {
return new ResponseEntity<>(Single.just("single value"), HttpStatus.NOT_FOUND);
}
@RequestMapping(method = RequestMethod.GET, value = "/singleWithResponse")
public ResponseEntity<Single<String>> singleWithResponse() {
return new ResponseEntity<>(Single.just("single value"),
HttpStatus.NOT_FOUND);
}
@RequestMapping(method = RequestMethod.GET, value = "/throw")
public Single<Object> error() {
return Single.error(new RuntimeException("Unexpected"));
}
@RequestMapping(method = RequestMethod.GET, value = "/throw")
public Single<Object> error() {
return Single.error(new RuntimeException("Unexpected"));
}
// end::rx_single[]
}
@Test
public void shouldRetrieveSingleValue() {
@Test
public void shouldRetrieveSingleValue() {
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/single"), String.class);
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/single"),
String.class);
// then
assertNotNull(response);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("single value", response.getBody());
}
// then
assertNotNull(response);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("single value", response.getBody());
}
@Test
public void shouldRetrieveSingleValueWithStatusCode() {
@Test
public void shouldRetrieveSingleValueWithStatusCode() {
// when
ResponseEntity<String> response = restTemplate.getForEntity(path("/singleWithResponse"), String.class);
// when
ResponseEntity<String> response = restTemplate
.getForEntity(path("/singleWithResponse"), String.class);
// then
assertNotNull(response);
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
assertEquals("single value", response.getBody());
}
// then
assertNotNull(response);
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
assertEquals("single value", response.getBody());
}
@Test
public void shouldRetrieveErrorResponse() {
@Test
public void shouldRetrieveErrorResponse() {
// when
ResponseEntity<Object> response = restTemplate.getForEntity(path("/throw"), Object.class);
// when
ResponseEntity<Object> response = restTemplate.getForEntity(path("/throw"),
Object.class);
// then
assertNotNull(response);
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
}
// then
assertNotNull(response);
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
}
private String path(String context) {
return String.format("http://localhost:%d%s", port, context);
}
private String path(String context) {
return String.format("http://localhost:%d%s", port, context);
}
}

View File

@@ -24,9 +24,9 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator;
import org.springframework.context.annotation.Configuration;
@@ -36,7 +36,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -45,9 +44,8 @@ import org.springframework.web.bind.annotation.RestController;
import com.netflix.zuul.context.RequestContext;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ContextPathZuulProxyApplication.class)
@WebAppConfiguration
@IntegrationTest({ "server.port: 0", "server.contextPath: /app" })
@SpringBootTest(classes = ContextPathZuulProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"server.contextPath: /app" })
@DirtiesContext
public class ContextPathZuulProxyApplicationTests {

View File

@@ -16,12 +16,13 @@
package org.springframework.cloud.netflix.zuul;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
@@ -29,9 +30,9 @@ import org.springframework.boot.actuate.trace.InMemoryTraceRepository;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.netflix.ribbon.StaticServerList;
@@ -45,7 +46,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -59,14 +59,11 @@ import com.netflix.loadbalancer.ServerList;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import static org.junit.Assert.assertEquals;
import lombok.extern.slf4j.Slf4j;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FormZuulProxyApplication.class)
@WebAppConfiguration
@IntegrationTest({ "server.port:0", "zuul.routes.simple:/simple/**" })
@SpringBootTest(classes = FormZuulProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"zuul.routes.simple:/simple/**" })
@DirtiesContext
public class FormZuulProxyApplicationTests {
@@ -93,7 +90,6 @@ public class FormZuulProxyApplicationTests {
assertEquals("Posted! {foo=[bar]}", result.getBody());
}
@Ignore //TODO: fix this test
@Test
public void postWithMultipartForm() {
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();

View File

@@ -16,6 +16,8 @@
package org.springframework.cloud.netflix.zuul;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
@@ -28,9 +30,9 @@ import org.springframework.boot.actuate.trace.InMemoryTraceRepository;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.netflix.ribbon.StaticServerList;
@@ -57,13 +59,10 @@ import com.netflix.loadbalancer.ServerList;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import static org.junit.Assert.assertEquals;
import lombok.extern.slf4j.Slf4j;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FormZuulServletProxyApplication.class)
@WebIntegrationTest(value = "zuul.routes.simple:/simple/**", randomPort = true)
@SpringBootTest(classes = FormZuulServletProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = "zuul.routes.simple:/simple/**")
@DirtiesContext
public class FormZuulServletProxyApplicationTests {

View File

@@ -1,15 +1,16 @@
package org.springframework.cloud.netflix.zuul;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.StaticServerList;
import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator;
@@ -23,7 +24,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
@@ -36,13 +36,10 @@ import com.netflix.loadbalancer.ServerList;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RetryableZuulProxyApplication.class)
@WebAppConfiguration
@IntegrationTest({ "server.port: 0", "zuul.routes.simple.path: /simple/**",
"zuul.routes.simple.retryable: true", "ribbon.OkToRetryOnAllOperations: true" })
@SpringBootTest(classes = RetryableZuulProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"zuul.routes.simple.path: /simple/**", "zuul.routes.simple.retryable: true",
"ribbon.OkToRetryOnAllOperations: true" })
@DirtiesContext
public class RetryableZuulProxyApplicationTests {
@@ -50,9 +47,11 @@ public class RetryableZuulProxyApplicationTests {
private int port;
@Autowired
@SuppressWarnings("unused")
private DiscoveryClientRouteLocator routes;
@Autowired
@SuppressWarnings("unused")
private RoutesEndpoint endpoint;
@Before

View File

@@ -24,9 +24,9 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator;
import org.springframework.context.annotation.Configuration;
@@ -36,7 +36,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -45,9 +44,8 @@ import org.springframework.web.bind.annotation.RestController;
import com.netflix.zuul.context.RequestContext;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ServletPathZuulProxyApplicationTests.ServletPathZuulProxyApplication.class)
@WebAppConfiguration
@IntegrationTest({ "server.port: 0", "server.servletPath: /app" })
@SpringBootTest(classes = ServletPathZuulProxyApplicationTests.ServletPathZuulProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"server.port: 0", "server.servletPath: /app" })
@DirtiesContext
public class ServletPathZuulProxyApplicationTests {
@@ -90,7 +88,6 @@ public class ServletPathZuulProxyApplicationTests {
assertEquals("Gotten strip!", result.getBody());
}
// Don't use @SpringBootApplication because we don't want to component scan
@Configuration
@EnableAutoConfiguration
@@ -100,8 +97,8 @@ public class ServletPathZuulProxyApplicationTests {
@RequestMapping(value = "/local/{id}", method = RequestMethod.GET)
public String get(@PathVariable String id) {
return "Gotten " + id + "!";
}
return "Gotten " + id + "!";
}
}
}

View File

@@ -16,6 +16,9 @@
package org.springframework.cloud.netflix.zuul;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -23,9 +26,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -35,20 +38,14 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SimpleZuulServerApplication.class)
@WebAppConfiguration
@IntegrationTest({ "server.port: 0" })
@SpringBootTest(classes = SimpleZuulServerApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class SimpleZuulServerApplicationTests {

View File

@@ -1,5 +1,9 @@
package org.springframework.cloud.netflix.zuul.filters;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@@ -15,9 +19,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.RoutesEndpoint;
import org.springframework.cloud.netflix.zuul.ZuulProxyConfiguration;
@@ -31,7 +35,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PathVariable;
@@ -43,14 +46,9 @@ import org.springframework.web.client.RestTemplate;
import com.netflix.zuul.context.RequestContext;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleCustomZuulProxyApplication.class)
@WebAppConfiguration
@IntegrationTest({ "server.port: 0", "server.contextPath: /app" })
@SpringBootTest(classes = SampleCustomZuulProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"server.contextPath: /app" })
@DirtiesContext
public class CustomHostRoutingFilterTests {
@@ -192,13 +190,14 @@ class SampleCustomZuulProxyApplication {
@Bean
@Override
public SimpleHostRoutingFilter simpleHostRoutingFilter(
ProxyRequestHelper helper, ZuulProperties zuulProperties) {
public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper,
ZuulProperties zuulProperties) {
return new CustomHostRoutingFilter(helper, zuulProperties);
}
private class CustomHostRoutingFilter extends SimpleHostRoutingFilter {
public CustomHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties zuulProperties) {
public CustomHostRoutingFilter(ProxyRequestHelper helper,
ZuulProperties zuulProperties) {
super(helper, zuulProperties);
}

View File

@@ -46,7 +46,8 @@ public class ZuulPropertiesTests {
@Test
public void defaultIgnoredHeaders() {
assertTrue(this.zuul.getIgnoredHeaders().isEmpty());
assertTrue(this.zuul.getIgnoredHeaders()
.containsAll(ZuulProperties.SECURITY_HEADERS));
}
@Test
@@ -60,8 +61,8 @@ public class ZuulPropertiesTests {
ZuulRoute route = new ZuulRoute("foo");
this.zuul.getRoutes().put("foo", route);
assertTrue(this.zuul.getRoutes().get("foo").getSensitiveHeaders().isEmpty());
assertTrue(this.zuul.getSensitiveHeaders().containsAll(
Arrays.asList("Cookie", "Set-Cookie", "Authorization")));
assertTrue(this.zuul.getSensitiveHeaders()
.containsAll(Arrays.asList("Cookie", "Set-Cookie", "Authorization")));
}
@Test

View File

@@ -1,5 +1,10 @@
package org.springframework.cloud.netflix.zuul.filters.discovery;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperIntegrationTests.SERVICE_ID;
import java.util.ArrayList;
import java.util.List;
@@ -10,9 +15,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.StaticServerList;
@@ -25,7 +30,6 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -36,19 +40,13 @@ import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
import com.netflix.zuul.context.RequestContext;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperIntegrationTests.SERVICE_ID;
/**
* @author Stéphane Leroy
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleCustomZuulProxyApplication.class)
@WebIntegrationTest(value = { "spring.application.name=regex-test-application",
"spring.jmx.enabled=true" }, randomPort = true)
@TestPropertySource(properties = "eureka.client.enabled=false")
@SpringBootTest(classes = SampleCustomZuulProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=regex-test-application", "spring.jmx.enabled=true",
"eureka.client.enabled=false" })
@DirtiesContext
public class PatternServiceRouteMapperIntegrationTests {

View File

@@ -0,0 +1,188 @@
package org.springframework.cloud.netflix.zuul.filters.pre;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.Part;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockMultipartHttpServletRequest;
import com.netflix.zuul.context.RequestContext;
/**
* @author Michael Hartle
*/
public class FormBodyWrapperFilterTests {
private FormBodyWrapperFilter filter;
private MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest();
@Before
public void init() {
this.filter = new FormBodyWrapperFilter();
RequestContext ctx = RequestContext.getCurrentContext();
ctx.clear();
ctx.setRequest(this.request);
}
@Test
public void multiplePartNamesWithMultipleParts() throws IOException, ServletException {
this.request.setRequestURI("/api/foo/1");
this.request.setRemoteAddr("5.6.7.8");
final Map<String, List<String>> firstPartHeaders = new HashMap<>();
final byte[] firstPartBody = "{ \"u\" : 1 }".getBytes();
final Part firstPart = new MockPart("a", "application/json", null, firstPartHeaders, firstPartBody);
this.request.addPart(firstPart);
final Map<String, List<String>> secondPartHeaders = new HashMap<>();
final byte[] secondPartBody = "%PDF...1".getBytes();
final Part secondPart = new MockPart("b", "application/pdf", "document.pdf", secondPartHeaders, secondPartBody);
this.request.addPart(secondPart);
final Map<String, List<String>> thirdPartHeaders = new HashMap<>();
final byte[] thirdPartBody = "%PDF...2".getBytes();
final Part thirdPart = new MockPart("c", "application/pdf", "attachment1.pdf", thirdPartHeaders, thirdPartBody);
this.request.addPart(thirdPart);
final Map<String, List<String>> fourthPartHeaders = new HashMap<>();
final byte[] fourthPartBody = "%PDF...3".getBytes();
final Part fourthPart = new MockPart("c", "application/pdf", "attachment2.pdf", fourthPartHeaders, fourthPartBody);
this.request.addPart(fourthPart);
final Map<String, List<String>> fifthPartHeaders = new HashMap<>();
final byte[] fifthPartBody = "%PDF...4".getBytes();
final Part fifthPart = new MockPart("c", "application/pdf", "attachment3.pdf", fifthPartHeaders, fifthPartBody);
this.request.addPart(fifthPart);
this.filter.run();
final RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/api/foo/1", ctx.getRequest().getRequestURI());
assertEquals("5.6.7.8", ctx.getRequest().getRemoteAddr());
assertEquals(5, ctx.getRequest().getParts().size());
final Part[] parts = ctx.getRequest().getParts().toArray(new Part[0]);
assertEquals("a", parts[0].getName());
assertEquals(null, parts[0].getSubmittedFileName());
assertEquals("application/json", parts[0].getContentType());
assertArrayEquals(firstPartBody, IOUtils.toByteArray(parts[0].getInputStream()));
assertEquals("b", parts[1].getName());
assertEquals("document.pdf", parts[1].getSubmittedFileName());
assertEquals("application/pdf", parts[1].getContentType());
assertArrayEquals(secondPartBody, IOUtils.toByteArray(parts[1].getInputStream()));
assertEquals("c", parts[2].getName());
assertEquals("attachment1.pdf", parts[2].getSubmittedFileName());
assertEquals("application/pdf", parts[2].getContentType());
assertArrayEquals(thirdPartBody, IOUtils.toByteArray(parts[2].getInputStream()));
assertEquals("c", parts[3].getName());
assertEquals("attachment2.pdf", parts[3].getSubmittedFileName());
assertEquals("application/pdf", parts[3].getContentType());
assertArrayEquals(fourthPartBody, IOUtils.toByteArray(parts[3].getInputStream()));
assertEquals("c", parts[4].getName());
assertEquals("attachment3.pdf", parts[4].getSubmittedFileName());
assertEquals("application/pdf", parts[4].getContentType());
assertArrayEquals(fifthPartBody, IOUtils.toByteArray(parts[4].getInputStream()));
}
private class MockPart implements Part {
private final String name;
private final String contentType;
private final String submittedFileName;
private final Map<String, List<String>> headers;
private final byte[] body;
public MockPart(final String name, final String contentType, final String submittedFileName, final Map<String, List<String>> headers, final byte[] body) {
this.name = name;
this.contentType = contentType;
this.submittedFileName = submittedFileName;
this.headers = headers;
this.body = body;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(this.body);
}
@Override
public String getContentType() {
return this.contentType;
}
@Override
public String getName() {
return this.name;
}
@Override
public String getSubmittedFileName() {
return this.submittedFileName;
}
@Override
public long getSize() {
return this.body != null ? this.body.length : 0;
}
@Override
public void write(String fileName) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void delete() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public String getHeader(String name) {
if (this.headers == null) {
return null;
}
final List<String> values = this.headers.get(name);
if (values == null || values.size() == 0) {
return null;
}
return values.get(0);
}
@Override
public Collection<String> getHeaders(String name) {
if (this.headers == null) {
return null;
}
return this.headers.get(name);
}
@Override
public Collection<String> getHeaderNames() {
if (this.headers == null) {
return null;
}
return this.headers.keySet();
}
}
}

View File

@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment;
/**
* @author Andreas Kluth

View File

@@ -17,20 +17,24 @@
package org.springframework.cloud.netflix.zuul.filters.route.apache;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.http.HttpHeaders.SET_COOKIE;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
@@ -54,24 +58,21 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.WebUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.http.HttpHeaders.SET_COOKIE;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = HttpClientRibbonCommandIntegrationTests.TestConfig.class)
@WebIntegrationTest(randomPort = true, value = {
@SpringBootTest(classes = HttpClientRibbonCommandIntegrationTests.TestConfig.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"zuul.routes.other: /test/**=http://localhost:7777/local",
"zuul.routes.another: /another/twolevel/**", "zuul.routes.simple: /simple/**",
"zuul.routes.singleton: /singleton/**", "zuul.routes.singleton.sensitiveHeaders: " })
"zuul.routes.singleton: /singleton/**",
"zuul.routes.singleton.sensitiveHeaders: " })
@DirtiesContext
public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
@@ -115,26 +116,27 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
@Test
public void ribbonLoadBalancingHttpClientCookiePolicy() {
ResponseEntity<String> result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/simple/downstream_cookie", HttpMethod.POST,
new HttpEntity<>((Void) null), String.class);
"http://localhost:" + this.port + "/simple/downstream_cookie",
HttpMethod.POST, new HttpEntity<>((Void) null), String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Cookie 434354454!", result.getBody());
assertNull(result.getHeaders().getFirst(SET_COOKIE));
// if new instance of RibbonLoadBalancingHttpClient is getting created every time
// and HttpClient is not reused then there are no concerns for the shared cookie storage
// but since https://github.com/spring-cloud/spring-cloud-netflix/issues/1150 is on the way a
// and HttpClient is not reused then there are no concerns for the shared cookie
// storage
// but since https://github.com/spring-cloud/spring-cloud-netflix/issues/1150 is
// on the way a
result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/singleton/downstream_cookie", HttpMethod.POST,
new HttpEntity<>((Void) null), String.class);
"http://localhost:" + this.port + "/singleton/downstream_cookie",
HttpMethod.POST, new HttpEntity<>((Void) null), String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Cookie 434354454!", result.getBody());
assertEquals("jsessionid=434354454", result.getHeaders().getFirst(SET_COOKIE));
result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/singleton/downstream_cookie", HttpMethod.GET,
new HttpEntity<>((Void) null), String.class);
"http://localhost:" + this.port + "/singleton/downstream_cookie",
HttpMethod.GET, new HttpEntity<>((Void) null), String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Cookie null!", result.getBody());
}
@@ -144,6 +146,7 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
assertTrue("ribbonCommandFactory not a HttpClientRibbonCommandFactory",
this.ribbonCommandFactory instanceof HttpClientRibbonCommandFactory);
}
// Don't use @SpringBootApplication because we don't want to component scan
@Configuration
@EnableAutoConfiguration
@@ -152,29 +155,27 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
@RibbonClients({
@RibbonClient(name = "simple", configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class),
@RibbonClient(name = "another", configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class),
@RibbonClient(name = "singleton", configuration = SingletonRibbonClientConfiguration.class) })
@RibbonClient(name = "singleton", configuration = SingletonRibbonClientConfiguration.class) })
static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication {
@RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH)
public String patch(@PathVariable final String id, @RequestBody final String body) {
public String patch(@PathVariable final String id,
@RequestBody final String body) {
return "Patched " + id + "!";
}
@RequestMapping(value = "/downstream_cookie", method = RequestMethod.POST)
public String setDownstreamCookie(HttpServletResponse response)
{
public String setDownstreamCookie(HttpServletResponse response) {
response.addCookie(new Cookie("jsessionid", "434354454"));
return "Cookie 434354454!";
}
@RequestMapping(value = "/downstream_cookie", method = RequestMethod.GET)
public String readDownstreamCookie(HttpServletRequest request)
{
public String readDownstreamCookie(HttpServletRequest request) {
final Cookie cookie = WebUtils.getCookie(request, "jsessionid");
return "Cookie " + cookie + "!";
}
@Bean
public RibbonCommandFactory<?> ribbonCommandFactory(
final SpringClientFactory clientFactory) {
@@ -182,7 +183,8 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
}
@Bean
public ZuulProxyTestBase.MyErrorController myErrorController(ErrorAttributes errorAttributes) {
public ZuulProxyTestBase.MyErrorController myErrorController(
ErrorAttributes errorAttributes) {
return new ZuulProxyTestBase.MyErrorController(errorAttributes);
}
}
@@ -200,8 +202,8 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
}
@Bean
public RibbonLoadBalancingHttpClient ribbonClient(IClientConfig config, ILoadBalancer loadBalancer, RetryHandler retryHandler)
{
public RibbonLoadBalancingHttpClient ribbonClient(IClientConfig config,
ILoadBalancer loadBalancer, RetryHandler retryHandler) {
final RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient();
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);

View File

@@ -25,9 +25,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
@@ -45,8 +45,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.RestController;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = OkHttpRibbonCommandIntegrationTests.TestConfig.class)
@WebIntegrationTest(randomPort = true, value = {
@SpringBootTest(classes = OkHttpRibbonCommandIntegrationTests.TestConfig.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"zuul.routes.other: /test/**=http://localhost:7777/local",
"zuul.routes.another: /another/twolevel/**", "zuul.routes.simple: /simple/**" })
@DirtiesContext
@@ -89,7 +88,6 @@ public class OkHttpRibbonCommandIntegrationTests extends ZuulProxyTestBase {
assertEquals("Deleted 1!", result.getBody());
}
@Test
public void ribbonCommandFactoryOverridden() {
assertTrue("ribbonCommandFactory not a OkHttpRibbonCommandFactory",

View File

@@ -24,6 +24,8 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
@@ -34,23 +36,24 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.ribbon.StaticServerList;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommand;
import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory;
import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext;
import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory;
import org.springframework.cloud.netflix.zuul.filters.route.support.NoEncodingFormHttpMessageConverter;
import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
@@ -59,10 +62,13 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.mock.http.client.MockClientHttpResponse;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.MatrixVariable;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -77,9 +83,7 @@ import com.netflix.niws.client.http.RestClient;
import lombok.SneakyThrows;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = RestClientRibbonCommandIntegrationTests.TestConfig.class)
@WebAppConfiguration
@IntegrationTest({ "server.port: 0",
@SpringBootTest(classes = RestClientRibbonCommandIntegrationTests.TestConfig.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"zuul.routes.other: /test/**=http://localhost:7777/local",
"zuul.routes.another: /another/twolevel/**", "zuul.routes.simple: /simple/**",
"zuul.routes.badhost: /badhost/**", "zuul.ignoredHeaders: X-Header",
@@ -229,6 +233,24 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
assertTrue("ribbonCommandFactory not a MyRibbonCommandFactory",
this.ribbonCommandFactory instanceof TestConfig.MyRibbonCommandFactory);
}
@Override
@SuppressWarnings("deprecation")
@Test
public void javascriptEncodedFormParams() {
TestRestTemplate testRestTemplate = new TestRestTemplate();
ArrayList<HttpMessageConverter<?>> converters = new ArrayList<>();
converters.addAll(Arrays.asList(new StringHttpMessageConverter(),
new NoEncodingFormHttpMessageConverter()));
testRestTemplate.getRestTemplate().setMessageConverters(converters);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("foo", "(bar)");
ResponseEntity<String> result = testRestTemplate.postForEntity(
"http://localhost:" + this.port + "/simple/local", map, String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Posted [(bar)] and Content-Length was: -1!", result.getBody());
}
@Test
public void routeLocatorOverridden() {
@@ -236,7 +258,6 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
this.routeLocator instanceof TestConfig.MyRouteLocator);
}
// Don't use @SpringBootApplication because we don't want to component scan
@Configuration
@EnableAutoConfiguration
@@ -250,8 +271,8 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
@RequestMapping("/trailing-slash")
public String trailingSlash(HttpServletRequest request) {
return request.getRequestURI();
}
return request.getRequestURI();
}
@RequestMapping("/content-type")
public String contentType(HttpServletRequest request) {
@@ -289,7 +310,8 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
}
@Bean
public RouteLocator routeLocator(DiscoveryClient discoveryClient, ZuulProperties zuulProperties) {
public RouteLocator routeLocator(DiscoveryClient discoveryClient,
ZuulProperties zuulProperties) {
return new MyRouteLocator("/", discoveryClient, zuulProperties);
}
@@ -299,10 +321,11 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
}
public static void main(String[] args) {
SpringApplication.run(TestConfig.class, args);
}
SpringApplication.run(TestConfig.class, args);
}
public static class MyRibbonCommandFactory extends RestClientRibbonCommandFactory {
public static class MyRibbonCommandFactory
extends RestClientRibbonCommandFactory {
private SpringClientFactory clientFactory;
@@ -352,14 +375,16 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
static class BadHostRibbonClientConfiguration {
@Bean
public ServerList<Server> ribbonServerList() {
return new StaticServerList<>(new Server(UUID.randomUUID().toString(), 4322));
return new StaticServerList<>(
new Server(UUID.randomUUID().toString(), 4322));
}
}
static class MyRouteLocator extends DiscoveryClientRouteLocator {
public MyRouteLocator(String servletPath, DiscoveryClient discovery, ZuulProperties properties) {
public MyRouteLocator(String servletPath, DiscoveryClient discovery,
ZuulProperties properties) {
super(servletPath, discovery, properties);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2013-2016 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.zuul.filters.route.support;
import java.io.IOException;
import java.util.Iterator;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;
/**
* @author Jacques-Etienne Beaudet
*/
public class NoEncodingFormHttpMessageConverter extends FormHttpMessageConverter {
@SuppressWarnings("unchecked")
@Override
public void write(MultiValueMap<String, ?> map, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
MultiValueMap<String, String> form = (MultiValueMap<String, String>) map;
StringBuilder builder = new StringBuilder();
for (Iterator<String> nameIterator = form.keySet().iterator(); nameIterator.hasNext();) {
String name = nameIterator.next();
for (Iterator<String> valueIterator = form.get(name).iterator(); valueIterator.hasNext();) {
String value = valueIterator.next();
builder.append(name);
if (value != null) {
builder.append('=');
builder.append(value);
if (valueIterator.hasNext()) {
builder.append('&');
}
}
}
if (nameIterator.hasNext()) {
builder.append('&');
}
}
final byte[] bytes = builder.toString().getBytes(FormHttpMessageConverter.DEFAULT_CHARSET);
outputMessage.getHeaders().setContentLength(bytes.length);
outputMessage.getHeaders().setContentType(MediaType.APPLICATION_FORM_URLENCODED);
StreamUtils.copy(bytes, outputMessage.getBody());
}
}

View File

@@ -17,6 +17,13 @@
package org.springframework.cloud.netflix.zuul.filters.route.support;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assume.assumeThat;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -25,7 +32,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.http.HttpServletRequest;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -33,7 +39,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.web.BasicErrorController;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.netflix.ribbon.StaticServerList;
import org.springframework.cloud.netflix.zuul.RoutesEndpoint;
import org.springframework.cloud.netflix.zuul.filters.Route;
@@ -45,7 +51,12 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@@ -53,6 +64,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import com.netflix.loadbalancer.Server;
@@ -60,11 +72,6 @@ import com.netflix.loadbalancer.ServerList;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assume.assumeThat;
/**
* @author Spencer Gibb
*/
@@ -247,6 +254,23 @@ public abstract class ZuulProxyTestBase {
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Patched 1!", result.getBody());
}
@SuppressWarnings("deprecation")
@Test
public void javascriptEncodedFormParams() {
TestRestTemplate testRestTemplate = new TestRestTemplate();
ArrayList<HttpMessageConverter<?>> converters = new ArrayList<>();
converters.addAll(Arrays.asList(new StringHttpMessageConverter(),
new NoEncodingFormHttpMessageConverter()));
testRestTemplate.getRestTemplate().setMessageConverters(converters);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("foo", "(bar)");
ResponseEntity<String> result = testRestTemplate.postForEntity(
"http://localhost:" + this.port + "/simple/local", map, String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Posted [(bar)] and Content-Length was: 13!", result.getBody());
}
protected abstract boolean supportsPatch();
@@ -268,6 +292,12 @@ public abstract class ZuulProxyTestBase {
public String local() {
return "Hello local";
}
@RequestMapping(value = "/local", method = RequestMethod.POST)
public String postWithFormParam(HttpServletRequest request,
@RequestBody MultiValueMap<String, String> body) {
return "Posted " + body.get("foo") + " and Content-Length was: " + request.getContentLength() + "!";
}
@RequestMapping(value = "/local/{id}", method = RequestMethod.DELETE)
public String delete(@PathVariable String id) {
@@ -341,6 +371,19 @@ public abstract class ZuulProxyTestBase {
return mapping;
}
}
@Configuration
public class FormEncodedMessageConverterConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FormHttpMessageConverter converter = new FormHttpMessageConverter();
MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", Charset.forName("UTF-8"));
converter.setSupportedMediaTypes(Arrays.asList(mediaType));
converters.add(converter);
super.configureMessageConverters(converters);
}
}
// Load balancer with fixed server list for "simple" pointing to localhost
@Configuration

View File

@@ -53,7 +53,15 @@ zuul:
stores:
url: http://localhost:8081
path: /stores/**
hystrix:
shareSecurityContext: true
feignClient:
localappName: localapp
methodLevelRequestMappingPath: /hello2
myPlaceholderHeader: myPlaceholderHeaderValue
security:
basic:
path: /proxy-username
user:
username: user
password: password