Merge branch 'master' of https://github.com/spring-cloud/spring-cloud-netflix
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 + "!";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user