Added checkstyle
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,13 +12,20 @@
|
||||
* 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.openfeign;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.optionals.OptionalDecoder;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -30,14 +37,6 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.optionals.OptionalDecoder;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -51,8 +50,7 @@ public class EnableFeignClientsTests {
|
||||
|
||||
@Test
|
||||
public void decoderDefaultCorrect() {
|
||||
OptionalDecoder.class
|
||||
.cast(this.feignContext.getInstance("foo", Decoder.class));
|
||||
OptionalDecoder.class.cast(this.feignContext.getInstance("foo", Decoder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -81,6 +79,7 @@ public class EnableFeignClientsTests {
|
||||
@Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class,
|
||||
FeignAutoConfiguration.class })
|
||||
protected static class PlainConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -25,16 +25,18 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.cloud.openfeign.testclients.TestClient;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Sven Döring
|
||||
*/
|
||||
@@ -65,14 +67,14 @@ public class FeignClientBuilderTests {
|
||||
fieldName);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
final Object value = ReflectionUtils.getField(field, factoryBean);
|
||||
Assert.assertEquals("Expected value for the field '" + fieldName + "':",
|
||||
expectedValue, value);
|
||||
assertThat(value).as("Expected value for the field '" + fieldName + "':")
|
||||
.isEqualTo(expectedValue);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.applicationContext = Mockito.mock(ApplicationContext.class);
|
||||
this.feignClientBuilder = new FeignClientBuilder(applicationContext);
|
||||
this.feignClientBuilder = new FeignClientBuilder(this.applicationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -91,18 +93,18 @@ public class FeignClientBuilderTests {
|
||||
// on this builder class.
|
||||
// (2) Or a new field was added and the builder class has to be extended with this
|
||||
// new field.
|
||||
Assert.assertThat(methodNames, Matchers.contains("contextId", "decode404", "fallback",
|
||||
"fallbackFactory", "name", "path", "url"));
|
||||
assertThat(methodNames).containsExactly("contextId", "decode404", "fallback",
|
||||
"fallbackFactory", "name", "path", "url");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forType_preinitializedBuilder() {
|
||||
// when:
|
||||
final FeignClientBuilder.Builder builder = feignClientBuilder
|
||||
final FeignClientBuilder.Builder builder = this.feignClientBuilder
|
||||
.forType(FeignClientBuilderTests.class, "TestClient");
|
||||
|
||||
// then:
|
||||
assertFactoryBeanField(builder, "applicationContext", applicationContext);
|
||||
assertFactoryBeanField(builder, "applicationContext", this.applicationContext);
|
||||
assertFactoryBeanField(builder, "type", FeignClientBuilderTests.class);
|
||||
assertFactoryBeanField(builder, "name", "TestClient");
|
||||
assertFactoryBeanField(builder, "contextId", "TestClient");
|
||||
@@ -123,13 +125,13 @@ public class FeignClientBuilderTests {
|
||||
@Test
|
||||
public void forType_allFieldsSetOnBuilder() {
|
||||
// when:
|
||||
final FeignClientBuilder.Builder builder = feignClientBuilder
|
||||
final FeignClientBuilder.Builder builder = this.feignClientBuilder
|
||||
.forType(FeignClientBuilderTests.class, "TestClient").decode404(true)
|
||||
.fallback(Object.class).fallbackFactory(Object.class).path("Path/")
|
||||
.url("Url/");
|
||||
|
||||
// then:
|
||||
assertFactoryBeanField(builder, "applicationContext", applicationContext);
|
||||
assertFactoryBeanField(builder, "applicationContext", this.applicationContext);
|
||||
assertFactoryBeanField(builder, "type", FeignClientBuilderTests.class);
|
||||
assertFactoryBeanField(builder, "name", "TestClient");
|
||||
|
||||
@@ -144,16 +146,17 @@ public class FeignClientBuilderTests {
|
||||
@Test
|
||||
public void forType_build() {
|
||||
// given:
|
||||
Mockito.when(applicationContext.getBean(FeignContext.class))
|
||||
Mockito.when(this.applicationContext.getBean(FeignContext.class))
|
||||
.thenThrow(new ClosedFileSystemException()); // throw an unusual exception
|
||||
// in the
|
||||
// FeignClientFactoryBean
|
||||
final FeignClientBuilder.Builder builder = feignClientBuilder
|
||||
final FeignClientBuilder.Builder builder = this.feignClientBuilder
|
||||
.forType(TestClient.class, "TestClient");
|
||||
|
||||
// expect: 'the build will fail right after calling build() with the mocked
|
||||
// unusual exception'
|
||||
thrown.expect(Matchers.isA(ClosedFileSystemException.class));
|
||||
this.thrown.expect(Matchers.isA(ClosedFileSystemException.class));
|
||||
builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -16,16 +16,14 @@
|
||||
|
||||
package org.springframework.cloud.openfeign;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -42,33 +40,43 @@ public class FeignClientFactoryTests {
|
||||
getSpec("bar", BarConfig.class)));
|
||||
|
||||
Foo foo = context.getInstance("foo", Foo.class);
|
||||
assertThat("foo was null", foo, is(notNullValue()));
|
||||
assertThat(foo).as("foo was null").isNotNull();
|
||||
|
||||
Bar bar = context.getInstance("bar", Bar.class);
|
||||
assertThat("bar was null", bar, is(notNullValue()));
|
||||
assertThat(bar).as("bar was null").isNotNull();
|
||||
|
||||
Bar foobar = context.getInstance("foo", Bar.class);
|
||||
assertThat("bar was not null", foobar, is(nullValue()));
|
||||
assertThat(foobar).as("bar was not null").isNull();
|
||||
}
|
||||
|
||||
private FeignClientSpecification getSpec(String name, Class<?> configClass) {
|
||||
return new FeignClientSpecification(name, new Class[]{configClass});
|
||||
return new FeignClientSpecification(name, new Class[] { configClass });
|
||||
}
|
||||
|
||||
static class FooConfig {
|
||||
|
||||
@Bean
|
||||
Foo foo() {
|
||||
return new Foo();
|
||||
}
|
||||
|
||||
}
|
||||
static class Foo{}
|
||||
|
||||
static class Foo {
|
||||
|
||||
}
|
||||
|
||||
static class BarConfig {
|
||||
|
||||
@Bean
|
||||
Bar bar() {
|
||||
return new Bar();
|
||||
}
|
||||
|
||||
}
|
||||
static class Bar{}
|
||||
|
||||
static class Bar {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,31 +12,10 @@
|
||||
* 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.openfeign;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||
import org.springframework.cloud.openfeign.support.SpringMvcContract;
|
||||
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.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;
|
||||
@@ -52,6 +31,24 @@ import feign.codec.ErrorDecoder;
|
||||
import feign.hystrix.HystrixFeign;
|
||||
import feign.optionals.OptionalDecoder;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||
import org.springframework.cloud.openfeign.support.SpringMvcContract;
|
||||
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.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -72,8 +69,8 @@ public class FeignClientOverrideDefaultsTests {
|
||||
|
||||
@Test
|
||||
public void clientsAvailable() {
|
||||
assertNotNull(this.foo);
|
||||
assertNotNull(this.bar);
|
||||
assertThat(this.foo).isNotNull();
|
||||
assertThat(this.bar).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,45 +99,62 @@ public class FeignClientOverrideDefaultsTests {
|
||||
|
||||
@Test
|
||||
public void overrideLoggerLevel() {
|
||||
assertNull(this.context.getInstance("foo", Logger.Level.class));
|
||||
assertEquals(Logger.Level.HEADERS,
|
||||
this.context.getInstance("bar", Logger.Level.class));
|
||||
assertThat(this.context.getInstance("foo", Logger.Level.class)).isNull();
|
||||
assertThat(this.context.getInstance("bar", Logger.Level.class))
|
||||
.isEqualTo(Logger.Level.HEADERS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideRetryer() {
|
||||
assertEquals(Retryer.NEVER_RETRY, this.context.getInstance("foo", Retryer.class));
|
||||
assertThat(this.context.getInstance("foo", Retryer.class))
|
||||
.isEqualTo(Retryer.NEVER_RETRY);
|
||||
Retryer.Default.class.cast(this.context.getInstance("bar", Retryer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideErrorDecoder() {
|
||||
assertNull(this.context.getInstance("foo", ErrorDecoder.class));
|
||||
assertThat(this.context.getInstance("foo", ErrorDecoder.class)).isNull();
|
||||
ErrorDecoder.Default.class
|
||||
.cast(this.context.getInstance("bar", ErrorDecoder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideBuilder() {
|
||||
HystrixFeign.Builder.class.cast(this.context.getInstance("foo", Feign.Builder.class));
|
||||
Feign.Builder.class
|
||||
.cast(this.context.getInstance("bar", Feign.Builder.class));
|
||||
HystrixFeign.Builder.class
|
||||
.cast(this.context.getInstance("foo", Feign.Builder.class));
|
||||
Feign.Builder.class.cast(this.context.getInstance("bar", Feign.Builder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideRequestOptions() {
|
||||
assertNull(this.context.getInstance("foo", Request.Options.class));
|
||||
assertThat(this.context.getInstance("foo", Request.Options.class)).isNull();
|
||||
Request.Options options = this.context.getInstance("bar", Request.Options.class);
|
||||
assertEquals(1, options.connectTimeoutMillis());
|
||||
assertEquals(1, options.readTimeoutMillis());
|
||||
assertThat(options.connectTimeoutMillis()).isEqualTo(1);
|
||||
assertThat(options.readTimeoutMillis()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addRequestInterceptor() {
|
||||
assertEquals(1,
|
||||
this.context.getInstances("foo", RequestInterceptor.class).size());
|
||||
assertEquals(2,
|
||||
this.context.getInstances("bar", RequestInterceptor.class).size());
|
||||
assertThat(this.context.getInstances("foo", RequestInterceptor.class).size())
|
||||
.isEqualTo(1);
|
||||
assertThat(this.context.getInstances("bar", RequestInterceptor.class).size())
|
||||
.isEqualTo(2);
|
||||
}
|
||||
|
||||
@FeignClient(name = "foo", url = "http://foo", configuration = FooConfiguration.class)
|
||||
interface FooClient {
|
||||
|
||||
@RequestLine("GET /")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "bar", url = "http://bar", configuration = BarConfiguration.class)
|
||||
interface BarClient {
|
||||
|
||||
@RequestMapping(value = "/", method = RequestMethod.GET)
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -148,6 +162,7 @@ public class FeignClientOverrideDefaultsTests {
|
||||
@Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class,
|
||||
FeignAutoConfiguration.class })
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
RequestInterceptor defaultRequestInterceptor() {
|
||||
return new RequestInterceptor() {
|
||||
@@ -156,16 +171,11 @@ public class FeignClientOverrideDefaultsTests {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@FeignClient(name = "foo", url = "http://foo", configuration = FooConfiguration.class)
|
||||
interface FooClient {
|
||||
@RequestLine("GET /")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
public static class FooConfiguration {
|
||||
|
||||
@Bean
|
||||
public Decoder feignDecoder() {
|
||||
return new Decoder.Default();
|
||||
@@ -190,15 +200,11 @@ public class FeignClientOverrideDefaultsTests {
|
||||
public Feign.Builder feignBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
}
|
||||
|
||||
@FeignClient(name = "bar", url = "http://bar", configuration = BarConfiguration.class)
|
||||
interface BarClient {
|
||||
@RequestMapping(value = "/", method = RequestMethod.GET)
|
||||
String get();
|
||||
}
|
||||
|
||||
public static class BarConfiguration {
|
||||
|
||||
@Bean
|
||||
Logger.Level feignLevel() {
|
||||
return Logger.Level.HEADERS;
|
||||
@@ -223,5 +229,7 @@ public class FeignClientOverrideDefaultsTests {
|
||||
RequestInterceptor feignRequestInterceptor() {
|
||||
return new BasicAuthRequestInterceptor("user", "pass");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -37,7 +37,6 @@ 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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -52,14 +51,15 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Eko Kurniawan Khannedy
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = FeignClientUsingPropertiesTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@SpringBootTest(classes = FeignClientUsingPropertiesTests.Application.class, webEnvironment = RANDOM_PORT)
|
||||
@TestPropertySource("classpath:feign-properties.properties")
|
||||
@DirtiesContext
|
||||
public class FeignClientUsingPropertiesTests {
|
||||
@@ -80,38 +80,41 @@ public class FeignClientUsingPropertiesTests {
|
||||
private FeignClientFactoryBean formFactoryBean;
|
||||
|
||||
public FeignClientUsingPropertiesTests() {
|
||||
fooFactoryBean = new FeignClientFactoryBean();
|
||||
fooFactoryBean.setContextId("foo");
|
||||
fooFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
this.fooFactoryBean = new FeignClientFactoryBean();
|
||||
this.fooFactoryBean.setContextId("foo");
|
||||
this.fooFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
|
||||
barFactoryBean = new FeignClientFactoryBean();
|
||||
barFactoryBean.setContextId("bar");
|
||||
barFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
this.barFactoryBean = new FeignClientFactoryBean();
|
||||
this.barFactoryBean.setContextId("bar");
|
||||
this.barFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
|
||||
formFactoryBean = new FeignClientFactoryBean();
|
||||
formFactoryBean.setContextId("form");
|
||||
formFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
this.formFactoryBean = new FeignClientFactoryBean();
|
||||
this.formFactoryBean.setContextId("form");
|
||||
this.formFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
}
|
||||
|
||||
public FooClient fooClient() {
|
||||
fooFactoryBean.setApplicationContext(applicationContext);
|
||||
return fooFactoryBean.feign(context).target(FooClient.class, "http://localhost:" + this.port);
|
||||
this.fooFactoryBean.setApplicationContext(this.applicationContext);
|
||||
return this.fooFactoryBean.feign(this.context).target(FooClient.class,
|
||||
"http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
public BarClient barClient() {
|
||||
barFactoryBean.setApplicationContext(applicationContext);
|
||||
return barFactoryBean.feign(context).target(BarClient.class, "http://localhost:" + this.port);
|
||||
this.barFactoryBean.setApplicationContext(this.applicationContext);
|
||||
return this.barFactoryBean.feign(this.context).target(BarClient.class,
|
||||
"http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
public FormClient formClient() {
|
||||
formFactoryBean.setApplicationContext(applicationContext);
|
||||
return formFactoryBean.feign(context).target(FormClient.class, "http://localhost:" + this.port);
|
||||
this.formFactoryBean.setApplicationContext(this.applicationContext);
|
||||
return this.formFactoryBean.feign(this.context).target(FormClient.class,
|
||||
"http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFoo() {
|
||||
String response = fooClient().foo();
|
||||
assertEquals("OK", response);
|
||||
assertThat(response).isEqualTo("OK");
|
||||
}
|
||||
|
||||
@Test(expected = RetryableException.class)
|
||||
@@ -124,25 +127,26 @@ public class FeignClientUsingPropertiesTests {
|
||||
public void testForm() {
|
||||
Map<String, String> request = Collections.singletonMap("form", "Data");
|
||||
String response = formClient().form(request);
|
||||
assertEquals("Data", response);
|
||||
assertThat(response).isEqualTo("Data");
|
||||
}
|
||||
|
||||
protected interface FooClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/foo")
|
||||
String foo();
|
||||
|
||||
}
|
||||
|
||||
protected interface BarClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/bar")
|
||||
String bar();
|
||||
|
||||
}
|
||||
|
||||
protected interface FormClient {
|
||||
|
||||
@RequestMapping(value = "/form", method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
@RequestMapping(value = "/form", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
String form(Map<String, String> form);
|
||||
|
||||
}
|
||||
@@ -155,10 +159,11 @@ public class FeignClientUsingPropertiesTests {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/foo")
|
||||
public String foo(HttpServletRequest request) throws IllegalAccessException {
|
||||
if ("Foo".equals(request.getHeader("Foo")) &&
|
||||
"Bar".equals(request.getHeader("Bar"))) {
|
||||
if ("Foo".equals(request.getHeader("Foo"))
|
||||
&& "Bar".equals(request.getHeader("Bar"))) {
|
||||
return "OK";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new IllegalAccessException("It should has Foo and Bar header");
|
||||
}
|
||||
}
|
||||
@@ -169,8 +174,7 @@ public class FeignClientUsingPropertiesTests {
|
||||
return "OK";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/form", method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
@RequestMapping(value = "/form", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
public String form(HttpServletRequest request) {
|
||||
return request.getParameter("form");
|
||||
}
|
||||
@@ -178,17 +182,21 @@ public class FeignClientUsingPropertiesTests {
|
||||
}
|
||||
|
||||
public static class FooRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
template.header("Foo", "Foo");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class BarRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
template.header("Bar", "Bar");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class NoRetryer implements Retryer {
|
||||
@@ -202,24 +210,29 @@ public class FeignClientUsingPropertiesTests {
|
||||
public Retryer clone() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DefaultErrorDecoder extends ErrorDecoder.Default {
|
||||
|
||||
}
|
||||
|
||||
public static class FormEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public void encode(Object o, Type type, RequestTemplate requestTemplate) throws EncodeException {
|
||||
public void encode(Object o, Type type, RequestTemplate requestTemplate)
|
||||
throws EncodeException {
|
||||
Map<String, String> form = (Map<String, String>) o;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
form.forEach((key, value) -> {
|
||||
builder.append(key + "=" + value + "&");
|
||||
});
|
||||
|
||||
requestTemplate.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
requestTemplate.header(HttpHeaders.CONTENT_TYPE,
|
||||
MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
requestTemplate.body(Request.Body.bodyTemplate(builder.toString(), UTF_8));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,7 +12,6 @@
|
||||
* 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.openfeign;
|
||||
@@ -20,6 +19,7 @@ package org.springframework.cloud.openfeign;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -27,8 +27,7 @@ import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -41,7 +40,6 @@ public class FeignClientsRegistrarTests {
|
||||
testGetName("http://bad_hostname");
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void badNameHttpsPrefix() {
|
||||
testGetName("https://bad_hostname");
|
||||
@@ -60,19 +58,19 @@ public class FeignClientsRegistrarTests {
|
||||
@Test
|
||||
public void goodName() {
|
||||
String name = testGetName("good-name");
|
||||
assertThat("name was wrong", name, is("good-name"));
|
||||
assertThat(name).as("name was wrong").isEqualTo("good-name");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void goodNameHttpPrefix() {
|
||||
String name = testGetName("http://good-name");
|
||||
assertThat("name was wrong", name, is("http://good-name"));
|
||||
assertThat(name).as("name was wrong").isEqualTo("http://good-name");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void goodNameHttpsPrefix() {
|
||||
String name = testGetName("https://goodname");
|
||||
assertThat("name was wrong", name, is("https://goodname"));
|
||||
assertThat(name).as("name was wrong").isEqualTo("https://goodname");
|
||||
}
|
||||
|
||||
private String testGetName(String name) {
|
||||
@@ -81,7 +79,6 @@ public class FeignClientsRegistrarTests {
|
||||
return registrar.getName(Collections.<String, Object>singletonMap("name", name));
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testFallback() {
|
||||
new AnnotationConfigApplicationContext(FallbackTestConfig.class);
|
||||
@@ -92,30 +89,35 @@ public class FeignClientsRegistrarTests {
|
||||
new AnnotationConfigApplicationContext(FallbackFactoryTestConfig.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableFeignClients(clients = { FeignClientsRegistrarTests.FallbackClient.class})
|
||||
protected static class FallbackTestConfig {
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "fallbackTestClient", url = "http://localhost:8080/", fallback = FallbackClient.class)
|
||||
protected interface FallbackClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
String fallbackTest();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableFeignClients(clients = { FeignClientsRegistrarTests.FallbackFactoryClient.class})
|
||||
protected static class FallbackFactoryTestConfig {
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "fallbackFactoryTestClient", url = "http://localhost:8081/", fallbackFactory = FallbackFactoryClient.class)
|
||||
protected interface FallbackFactoryClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
String fallbackFactoryTest();
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableFeignClients(clients = { FeignClientsRegistrarTests.FallbackClient.class })
|
||||
protected static class FallbackTestConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableFeignClients(clients = {
|
||||
FeignClientsRegistrarTests.FallbackFactoryClient.class })
|
||||
protected static class FallbackFactoryTestConfig {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,15 +12,18 @@
|
||||
* 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.openfeign;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import feign.Client;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
@@ -35,10 +38,6 @@ import org.springframework.cloud.test.ModifiedClassPathRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import feign.Client;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
@@ -90,7 +89,9 @@ public class FeignCompressionTests {
|
||||
* a bean here of type ApacheHttpClient so that the configuration will be
|
||||
* loaded correctly.
|
||||
*/
|
||||
return (ApacheHttpClient) client;
|
||||
return (ApacheHttpClient) this.client;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,14 +12,16 @@
|
||||
* 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.openfeign;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.net.ssl.SSLContextSpi;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.apache.http.config.Lookup;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
@@ -28,6 +30,7 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
|
||||
@@ -36,8 +39,7 @@ import org.springframework.cloud.test.ModifiedClassPathRunner;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
@@ -50,8 +52,8 @@ public class FeignHttpClientConfigurationTests {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
context = new SpringApplicationBuilder()
|
||||
.properties("debug=true","feign.httpclient.disableSslValidation=true")
|
||||
this.context = new SpringApplicationBuilder()
|
||||
.properties("debug=true", "feign.httpclient.disableSslValidation=true")
|
||||
.web(WebApplicationType.NONE)
|
||||
.sources(HttpClientConfiguration.class, FeignAutoConfiguration.class)
|
||||
.run();
|
||||
@@ -59,29 +61,38 @@ public class FeignHttpClientConfigurationTests {
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if(context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableSslTest() throws Exception {
|
||||
HttpClientConnectionManager connectionManager = context.getBean(HttpClientConnectionManager.class);
|
||||
Lookup<ConnectionSocketFactory> socketFactoryRegistry = getConnectionSocketFactoryLookup(connectionManager);
|
||||
assertNotNull(socketFactoryRegistry.lookup("https"));
|
||||
assertNull(this.getX509TrustManager(socketFactoryRegistry).getAcceptedIssuers());
|
||||
HttpClientConnectionManager connectionManager = this.context
|
||||
.getBean(HttpClientConnectionManager.class);
|
||||
Lookup<ConnectionSocketFactory> socketFactoryRegistry = getConnectionSocketFactoryLookup(
|
||||
connectionManager);
|
||||
assertThat(socketFactoryRegistry.lookup("https")).isNotNull();
|
||||
assertThat(this.getX509TrustManager(socketFactoryRegistry).getAcceptedIssuers())
|
||||
.isNull();
|
||||
}
|
||||
|
||||
private Lookup<ConnectionSocketFactory> getConnectionSocketFactoryLookup(HttpClientConnectionManager connectionManager) {
|
||||
DefaultHttpClientConnectionOperator connectionOperator = (DefaultHttpClientConnectionOperator)this.getField(connectionManager, "connectionOperator");
|
||||
return (Lookup)this.getField(connectionOperator, "socketFactoryRegistry");
|
||||
private Lookup<ConnectionSocketFactory> getConnectionSocketFactoryLookup(
|
||||
HttpClientConnectionManager connectionManager) {
|
||||
DefaultHttpClientConnectionOperator connectionOperator = (DefaultHttpClientConnectionOperator) this
|
||||
.getField(connectionManager, "connectionOperator");
|
||||
return (Lookup) this.getField(connectionOperator, "socketFactoryRegistry");
|
||||
}
|
||||
|
||||
private X509TrustManager getX509TrustManager(Lookup<ConnectionSocketFactory> socketFactoryRegistry) {
|
||||
ConnectionSocketFactory connectionSocketFactory = (ConnectionSocketFactory)socketFactoryRegistry.lookup("https");
|
||||
SSLSocketFactory sslSocketFactory = (SSLSocketFactory)this.getField(connectionSocketFactory, "socketfactory");
|
||||
SSLContextSpi sslContext = (SSLContextSpi)this.getField(sslSocketFactory, "context");
|
||||
return (X509TrustManager)this.getField(sslContext, "trustManager");
|
||||
private X509TrustManager getX509TrustManager(
|
||||
Lookup<ConnectionSocketFactory> socketFactoryRegistry) {
|
||||
ConnectionSocketFactory connectionSocketFactory = (ConnectionSocketFactory) socketFactoryRegistry
|
||||
.lookup("https");
|
||||
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) this
|
||||
.getField(connectionSocketFactory, "socketfactory");
|
||||
SSLContextSpi sslContext = (SSLContextSpi) this.getField(sslSocketFactory,
|
||||
"context");
|
||||
return (X509TrustManager) this.getField(sslContext, "trustManager");
|
||||
}
|
||||
|
||||
protected <T> Object getField(Object target, String name) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,28 +12,25 @@
|
||||
* 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.openfeign;
|
||||
|
||||
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.assertThat;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.Target;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -46,16 +43,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.Target;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = FeignHttpClientUrlTests.TestConfig.class, webEnvironment = WebEnvironment.DEFINED_PORT, value = {
|
||||
@SpringBootTest(classes = FeignHttpClientUrlTests.TestConfig.class, webEnvironment = DEFINED_PORT, value = {
|
||||
"spring.application.name=feignclienturltest", "feign.hystrix.enabled=false",
|
||||
"feign.okhttp.enabled=false" })
|
||||
@DirtiesContext
|
||||
@@ -63,6 +58,15 @@ public class FeignHttpClientUrlTests {
|
||||
|
||||
static int port;
|
||||
|
||||
@Autowired
|
||||
BeanUrlClientNoProtocol beanClientNoProtocol;
|
||||
|
||||
@Autowired
|
||||
private UrlClient urlClient;
|
||||
|
||||
@Autowired
|
||||
private BeanUrlClient beanClient;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
port = SocketUtils.findAvailableTcpPort();
|
||||
@@ -74,37 +78,61 @@ public class FeignHttpClientUrlTests {
|
||||
System.clearProperty("server.port");
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private UrlClient urlClient;
|
||||
@Test
|
||||
public void testUrlHttpClient() {
|
||||
assertThat(this.urlClient).as("UrlClient was null").isNotNull();
|
||||
Hello hello = this.urlClient.getHello();
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match")
|
||||
.isEqualTo(new Hello("hello world 1"));
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private BeanUrlClient beanClient;
|
||||
@Test
|
||||
public void testBeanUrl() {
|
||||
Hello hello = this.beanClient.getHello();
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match")
|
||||
.isEqualTo(new Hello("hello world 1"));
|
||||
}
|
||||
|
||||
@Autowired BeanUrlClientNoProtocol beanClientNoProtocol;
|
||||
@Test
|
||||
public void testBeanUrlNoProtocol() {
|
||||
Hello hello = this.beanClientNoProtocol.getHello();
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match")
|
||||
.isEqualTo(new Hello("hello world 1"));
|
||||
}
|
||||
|
||||
// this tests that
|
||||
@FeignClient(name = "localappurl", url = "http://localhost:${server.port}/")
|
||||
protected interface UrlClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "beanappurl", url = "#{SERVER_URL}path")
|
||||
protected interface BeanUrlClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "beanappurlnoprotocol", url = "#{SERVER_URL_NO_PROTOCOL}path")
|
||||
protected interface BeanUrlClientNoProtocol {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@EnableFeignClients(clients = { UrlClient.class, BeanUrlClient.class, BeanUrlClientNoProtocol.class })
|
||||
@EnableFeignClients(clients = { UrlClient.class, BeanUrlClient.class,
|
||||
BeanUrlClientNoProtocol.class })
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
protected static class TestConfig {
|
||||
|
||||
@@ -118,12 +146,12 @@ public class FeignHttpClientUrlTests {
|
||||
return getHello();
|
||||
}
|
||||
|
||||
@Bean(name="SERVER_URL")
|
||||
@Bean(name = "SERVER_URL")
|
||||
public String serverUrl() {
|
||||
return "http://localhost:" + port + "/";
|
||||
}
|
||||
|
||||
@Bean(name="SERVER_URL_NO_PROTOCOL")
|
||||
@Bean(name = "SERVER_URL_NO_PROTOCOL")
|
||||
public String serverUrlNoProtocol() {
|
||||
return "localhost:" + port + "/";
|
||||
}
|
||||
@@ -139,8 +167,8 @@ public class FeignHttpClientUrlTests {
|
||||
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).isInstanceOf(ApacheHttpClient.class)
|
||||
.as("client was wrong type");
|
||||
}
|
||||
return feign.target(target);
|
||||
}
|
||||
@@ -149,29 +177,8 @@ public class FeignHttpClientUrlTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUrlHttpClient() {
|
||||
assertNotNull("UrlClient was null", this.urlClient);
|
||||
Hello hello = this.urlClient.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeanUrl() {
|
||||
Hello hello = this.beanClient.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeanUrlNoProtocol() {
|
||||
Hello hello = this.beanClientNoProtocol.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
|
||||
private String message;
|
||||
|
||||
public Hello() {
|
||||
@@ -182,7 +189,7 @@ public class FeignHttpClientUrlTests {
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
@@ -191,15 +198,21 @@ public class FeignHttpClientUrlTests {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Hello that = (Hello) o;
|
||||
return Objects.equals(message, that.message);
|
||||
return Objects.equals(this.message, that.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(message);
|
||||
return Objects.hash(this.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2019 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.
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.openfeign;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import feign.Logger;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
@@ -26,8 +25,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import feign.Logger;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Venil Noronha
|
||||
@@ -36,12 +34,38 @@ public class FeignLoggerFactoryTests {
|
||||
|
||||
@Test
|
||||
public void testDefaultLogger() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration1.class);
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
SampleConfiguration1.class);
|
||||
FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class);
|
||||
assertNotNull(loggerFactory);
|
||||
assertThat(loggerFactory).isNotNull();
|
||||
Logger logger = loggerFactory.create(Object.class);
|
||||
assertNotNull(logger);
|
||||
assertTrue(logger instanceof Slf4jLogger);
|
||||
assertThat(logger).isNotNull();
|
||||
assertThat(logger instanceof Slf4jLogger).isTrue();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomLogger() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
SampleConfiguration2.class);
|
||||
FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class);
|
||||
assertThat(loggerFactory).isNotNull();
|
||||
Logger logger = loggerFactory.create(Object.class);
|
||||
assertThat(logger).isNotNull();
|
||||
assertThat(logger instanceof LoggerImpl1).isTrue();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomLoggerFactory() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
SampleConfiguration3.class);
|
||||
FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class);
|
||||
assertThat(loggerFactory).isNotNull();
|
||||
assertThat(loggerFactory instanceof LoggerFactoryImpl).isTrue();
|
||||
Logger logger = loggerFactory.create(Object.class);
|
||||
assertThat(logger).isNotNull();
|
||||
assertThat(logger instanceof LoggerImpl2).isTrue();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -51,17 +75,6 @@ public class FeignLoggerFactoryTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomLogger() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration2.class);
|
||||
FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class);
|
||||
assertNotNull(loggerFactory);
|
||||
Logger logger = loggerFactory.create(Object.class);
|
||||
assertNotNull(logger);
|
||||
assertTrue(logger instanceof LoggerImpl1);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(FeignClientsConfiguration.class)
|
||||
protected static class SampleConfiguration2 {
|
||||
@@ -82,18 +95,6 @@ public class FeignLoggerFactoryTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomLoggerFactory() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration3.class);
|
||||
FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class);
|
||||
assertNotNull(loggerFactory);
|
||||
assertTrue(loggerFactory instanceof LoggerFactoryImpl);
|
||||
Logger logger = loggerFactory.create(Object.class);
|
||||
assertNotNull(logger);
|
||||
assertTrue(logger instanceof LoggerImpl2);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(FeignClientsConfiguration.class)
|
||||
protected static class SampleConfiguration3 {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,19 +12,20 @@
|
||||
* 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.openfeign;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
|
||||
@@ -34,6 +35,8 @@ import org.springframework.cloud.test.ModifiedClassPathRunner;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@@ -45,23 +48,29 @@ public class FeignOkHttpConfigurationTests {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
context = new SpringApplicationBuilder().properties("debug=true","feign.httpclient.disableSslValidation=true",
|
||||
"feign.okhttp.enabled=true", "feign.httpclient.enabled=false").web(WebApplicationType.NONE)
|
||||
.sources(HttpClientConfiguration.class, FeignAutoConfiguration.class).run();
|
||||
this.context = new SpringApplicationBuilder()
|
||||
.properties("debug=true", "feign.httpclient.disableSslValidation=true",
|
||||
"feign.okhttp.enabled=true", "feign.httpclient.enabled=false")
|
||||
.web(WebApplicationType.NONE)
|
||||
.sources(HttpClientConfiguration.class, FeignAutoConfiguration.class)
|
||||
.run();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if(context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableSslTest() throws Exception {
|
||||
OkHttpClient httpClient = context.getBean(OkHttpClient.class);
|
||||
HostnameVerifier hostnameVerifier = (HostnameVerifier)this.getField(httpClient, "hostnameVerifier");
|
||||
Assert.assertTrue(OkHttpClientFactory.TrustAllHostnames.class.isInstance(hostnameVerifier));
|
||||
OkHttpClient httpClient = this.context.getBean(OkHttpClient.class);
|
||||
HostnameVerifier hostnameVerifier = (HostnameVerifier) this.getField(httpClient,
|
||||
"hostnameVerifier");
|
||||
assertThat(
|
||||
OkHttpClientFactory.TrustAllHostnames.class.isInstance(hostnameVerifier))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
protected <T> Object getField(Object target, String name) {
|
||||
@@ -70,4 +79,5 @@ public class FeignOkHttpConfigurationTests {
|
||||
Object value = ReflectionUtils.getField(field, target);
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -23,6 +23,7 @@ import java.util.Objects;
|
||||
|
||||
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;
|
||||
@@ -40,10 +41,7 @@ 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 static org.junit.Assert.assertTrue;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -72,66 +70,73 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
|
||||
public TestClient testClient(boolean decode404) {
|
||||
setType(this.getClass());
|
||||
setDecode404(decode404);
|
||||
return feign(context).target(TestClient.class, "http://localhost:" + this.port);
|
||||
return feign(this.context).target(TestClient.class,
|
||||
"http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseEntity() {
|
||||
ResponseEntity<Hello> response = testClient().getHelloResponse();
|
||||
assertNotNull("response was null", response);
|
||||
assertEquals("wrong status code", HttpStatus.OK, response.getStatusCode());
|
||||
assertThat(response).as("response was null").isNotNull();
|
||||
assertThat(response.getStatusCode()).as("wrong status code")
|
||||
.isEqualTo(HttpStatus.OK);
|
||||
Hello hello = response.getBody();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world via response"),
|
||||
hello);
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match")
|
||||
.isEqualTo(new Hello("hello world via response"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = testClient().getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match")
|
||||
.isEqualTo(new Hello("hello world 1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserParameterizedTypeDecode() {
|
||||
List<Hello> hellos = testClient().getHellos();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"),
|
||||
hellos.get(0));
|
||||
assertThat(hellos).as("hellos was null").isNotNull();
|
||||
assertThat(hellos.size()).as("hellos was not the right size").isEqualTo(2);
|
||||
assertThat(hellos.get(0)).as("first hello didn't match")
|
||||
.isEqualTo(new Hello("hello world 1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleParameterizedTypeDecode() {
|
||||
List<String> hellos = testClient().getHelloStrings();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", "hello world 1", hellos.get(0));
|
||||
assertThat(hellos).as("hellos was null").isNotNull();
|
||||
assertThat(hellos.size()).as("hellos was not the right size").isEqualTo(2);
|
||||
assertThat(hellos.get(0)).as("first hello didn't match")
|
||||
.isEqualTo("hello world 1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testWildcardTypeDecode() {
|
||||
ResponseEntity<?> wildcard = testClient().getWildcard();
|
||||
assertNotNull("wildcard was null", wildcard);
|
||||
assertEquals("wrong status code", HttpStatus.OK, wildcard.getStatusCode());
|
||||
assertThat(wildcard).as("wildcard was null").isNotNull();
|
||||
assertThat(wildcard.getStatusCode()).as("wrong status code")
|
||||
.isEqualTo(HttpStatus.OK);
|
||||
Object wildcardBody = wildcard.getBody();
|
||||
assertNotNull("wildcardBody was null", wildcardBody);
|
||||
assertTrue("wildcard not an instance of Map", wildcardBody instanceof Map);
|
||||
assertThat(wildcardBody).as("wildcardBody was null").isNotNull();
|
||||
assertThat(wildcardBody instanceof Map).as("wildcard not an instance of Map")
|
||||
.isTrue();
|
||||
Map<String, String> hello = (Map<String, String>) wildcardBody;
|
||||
assertEquals("first hello didn't match", "wildcard", hello.get("message"));
|
||||
assertThat(hello.get("message")).as("first hello didn't match")
|
||||
.isEqualTo("wildcard");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseEntityVoid() {
|
||||
ResponseEntity<Void> response = testClient().getHelloVoid();
|
||||
assertNotNull("response was null", response);
|
||||
assertThat(response).as("response was null").isNotNull();
|
||||
List<String> headerVals = response.getHeaders().get("X-test-header");
|
||||
assertNotNull("headerVals was null", headerVals);
|
||||
assertEquals("headerVals size was wrong", 1, headerVals.size());
|
||||
assertThat(headerVals).as("headerVals was null").isNotNull();
|
||||
assertThat(headerVals.size()).as("headerVals size was wrong").isEqualTo(1);
|
||||
String header = headerVals.get(0);
|
||||
assertEquals("header was wrong", "myval", header);
|
||||
assertThat(header).as("header was wrong").isEqualTo("myval");
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
@@ -142,43 +147,12 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
|
||||
@Test
|
||||
public void testDecodes404() {
|
||||
final ResponseEntity<String> response = testClient(true).getNotFound();
|
||||
assertNotNull("response was null", response);
|
||||
assertNull("response body was not null", response.getBody());
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
private String message;
|
||||
|
||||
public Hello() {
|
||||
}
|
||||
|
||||
public Hello(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Hello that = (Hello) o;
|
||||
return Objects.equals(message, that.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(message);
|
||||
}
|
||||
assertThat(response).as("response was null").isNotNull();
|
||||
assertThat(response.getBody()).as("response body was not null").isNull();
|
||||
}
|
||||
|
||||
protected interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/helloresponse")
|
||||
ResponseEntity<Hello> getHelloResponse();
|
||||
|
||||
@@ -199,6 +173,45 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
|
||||
|
||||
@GetMapping("/helloWildcard")
|
||||
ResponseEntity<?> getWildcard();
|
||||
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
|
||||
private String message;
|
||||
|
||||
public Hello() {
|
||||
}
|
||||
|
||||
public Hello(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Hello that = (Hello) o;
|
||||
return Objects.equals(this.message, that.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -247,7 +260,7 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
|
||||
public ResponseEntity<?> getWildcard() {
|
||||
return ResponseEntity.ok(new Hello("wildcard"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -14,62 +14,64 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.springframework.cloud.openfeign;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
|
||||
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
|
||||
import org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer;
|
||||
import org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.ribbon.RetryableFeignLoadBalancer;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
|
||||
import org.springframework.cloud.test.ClassPathExclusions;
|
||||
import org.springframework.cloud.test.ModifiedClassPathRunner;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(ModifiedClassPathRunner.class)
|
||||
@ClassPathExclusions({"spring-retry-*.jar", "spring-boot-starter-aop-*.jar"})
|
||||
@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" })
|
||||
public class SpringRetryDisabledTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
|
||||
.sources(RibbonAutoConfiguration.class, LoadBalancerAutoConfiguration.class, RibbonClientConfiguration.class,
|
||||
FeignRibbonClientAutoConfiguration.class).run();
|
||||
this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
|
||||
.sources(RibbonAutoConfiguration.class,
|
||||
LoadBalancerAutoConfiguration.class,
|
||||
RibbonClientConfiguration.class,
|
||||
FeignRibbonClientAutoConfiguration.class)
|
||||
.run();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if(context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadBalancedRetryFactoryBean() throws Exception {
|
||||
Map<String, CachingSpringLoadBalancerFactory> lbFactorys = context.getBeansOfType(CachingSpringLoadBalancerFactory.class);
|
||||
assertThat(lbFactorys.values(), hasSize(1));
|
||||
FeignLoadBalancer lb =lbFactorys.values().iterator().next().create("foo");
|
||||
assertThat(lb, instanceOf(FeignLoadBalancer.class));
|
||||
assertThat(lb, is(not(instanceOf(RetryableFeignLoadBalancer.class))));
|
||||
Map<String, CachingSpringLoadBalancerFactory> lbFactorys = this.context
|
||||
.getBeansOfType(CachingSpringLoadBalancerFactory.class);
|
||||
assertThat(lbFactorys.values()).hasSize(1);
|
||||
FeignLoadBalancer lb = lbFactorys.values().iterator().next().create("foo");
|
||||
assertThat(lb).isInstanceOf(FeignLoadBalancer.class);
|
||||
assertThat(lb).isNotInstanceOf(RetryableFeignLoadBalancer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -17,46 +17,49 @@
|
||||
package org.springframework.cloud.openfeign;
|
||||
|
||||
import java.util.Map;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
|
||||
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
|
||||
import org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer;
|
||||
import org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.ribbon.RetryableFeignLoadBalancer;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {RibbonAutoConfiguration.class, RibbonClientConfiguration.class, LoadBalancerAutoConfiguration.class,
|
||||
FeignRibbonClientAutoConfiguration.class, HttpClientConfiguration.class})
|
||||
@ContextConfiguration(classes = { RibbonAutoConfiguration.class,
|
||||
RibbonClientConfiguration.class, LoadBalancerAutoConfiguration.class,
|
||||
FeignRibbonClientAutoConfiguration.class, HttpClientConfiguration.class })
|
||||
public class SpringRetryEnabledTests implements ApplicationContextAware {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testLoadBalancedRetryFactoryBean() throws Exception {
|
||||
Map<String, CachingSpringLoadBalancerFactory> lbFactorys = context.getBeansOfType(CachingSpringLoadBalancerFactory.class);
|
||||
assertThat(lbFactorys.values(), Matchers.hasSize(1));
|
||||
FeignLoadBalancer lb =lbFactorys.values().iterator().next().create("foo");
|
||||
assertThat(lb, instanceOf(RetryableFeignLoadBalancer.class));
|
||||
Map<String, CachingSpringLoadBalancerFactory> lbFactorys = this.context
|
||||
.getBeansOfType(CachingSpringLoadBalancerFactory.class);
|
||||
assertThat(lbFactorys.values()).hasSize(1);
|
||||
FeignLoadBalancer lb = lbFactorys.values().iterator().next().create("foo");
|
||||
assertThat(lb).isInstanceOf(RetryableFeignLoadBalancer.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -23,6 +23,7 @@ import java.util.Objects;
|
||||
|
||||
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;
|
||||
@@ -42,8 +43,7 @@ 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 static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -73,6 +73,44 @@ public class FeignClientTests {
|
||||
@Autowired
|
||||
private TestClient buildByBuilder;
|
||||
|
||||
@Test
|
||||
public void testAnnotations() {
|
||||
Map<String, Object> beans = this.context
|
||||
.getBeansWithAnnotation(FeignClient.class);
|
||||
assertThat(beans.containsKey(TestClient.class.getName()))
|
||||
.as("Wrong clients: " + beans).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertThat(this.testClient).as("testClient was null").isNotNull();
|
||||
assertThat(this.extraClient).as("extraClient was null").isNotNull();
|
||||
assertThat(Proxy.isProxyClass(this.testClient.getClass()))
|
||||
.as("testClient is not a java Proxy").isTrue();
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient);
|
||||
assertThat(invocationHandler).as("invocationHandler was null").isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extraClient() {
|
||||
assertThat(this.extraClient).as("extraClient was null").isNotNull();
|
||||
assertThat(Proxy.isProxyClass(this.extraClient.getClass()))
|
||||
.as("extraClient is not a java Proxy").isTrue();
|
||||
InvocationHandler invocationHandler = Proxy
|
||||
.getInvocationHandler(this.extraClient);
|
||||
assertThat(invocationHandler).as("invocationHandler was null").isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildByBuilder() {
|
||||
assertThat(this.buildByBuilder).as("buildByBuilder was null").isNotNull();
|
||||
assertThat(Proxy.isProxyClass(this.buildByBuilder.getClass()))
|
||||
.as("buildByBuilder is not a java Proxy").isTrue();
|
||||
InvocationHandler invocationHandler = Proxy
|
||||
.getInvocationHandler(this.buildByBuilder);
|
||||
assertThat(invocationHandler).as("invocationHandler was null").isNotNull();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@@ -82,18 +120,18 @@ public class FeignClientTests {
|
||||
|
||||
@Bean("build-by-builder")
|
||||
public TestClient buildByBuilder(final FeignClientBuilder feignClientBuilder) {
|
||||
return feignClientBuilder
|
||||
.forType(TestClient.class, "builderapp")
|
||||
.build();
|
||||
return feignClientBuilder.forType(TestClient.class, "builderapp").build();
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
|
||||
private String message;
|
||||
|
||||
public Hello() {
|
||||
@@ -104,7 +142,7 @@ public class FeignClientTests {
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
@@ -113,56 +151,27 @@ public class FeignClientTests {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Hello that = (Hello) o;
|
||||
|
||||
return Objects.equals(message, that.message);
|
||||
return Objects.equals(this.message, that.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return message != null ? message.hashCode() : 0;
|
||||
return this.message != null ? this.message.hashCode() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotations() {
|
||||
Map<String, Object> beans = this.context
|
||||
.getBeansWithAnnotation(FeignClient.class);
|
||||
assertTrue("Wrong clients: " + beans,
|
||||
beans.containsKey(TestClient.class.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertNotNull("testClient was null", this.testClient);
|
||||
assertNotNull("extraClient was null", this.extraClient);
|
||||
assertTrue("testClient is not a java Proxy",
|
||||
Proxy.isProxyClass(this.testClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extraClient() {
|
||||
assertNotNull("extraClient was null", this.extraClient);
|
||||
assertTrue("extraClient is not a java Proxy",
|
||||
Proxy.isProxyClass(this.extraClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.extraClient);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildByBuilder() {
|
||||
assertNotNull("buildByBuilder was null", this.buildByBuilder);
|
||||
assertTrue("buildByBuilder is not a java Proxy",
|
||||
Proxy.isProxyClass(this.buildByBuilder.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.buildByBuilder);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class TestDefaultFeignConfig {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -23,8 +23,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@Primary
|
||||
@FeignClient(value = "localapp")
|
||||
@FeignClient("localapp")
|
||||
public interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -23,6 +23,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@FeignClient(value = "otherapp", qualifier = "uniquequalifier")
|
||||
public interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -22,7 +22,6 @@ import java.util.List;
|
||||
import com.netflix.loadbalancer.BaseLoadBalancer;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -30,11 +29,10 @@ 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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.encoding.app.client.InvoiceClient;
|
||||
import org.springframework.cloud.openfeign.encoding.app.domain.Invoice;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -44,15 +42,15 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* Tests the response compression.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
@SpringBootTest(classes = FeignAcceptEncodingTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
|
||||
@SpringBootTest(classes = FeignAcceptEncodingTests.Application.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"feign.compression.response.enabled=true" })
|
||||
@RunWith(SpringRunner.class)
|
||||
@DirtiesContext
|
||||
@@ -68,10 +66,10 @@ public class FeignAcceptEncodingTests {
|
||||
final ResponseEntity<List<Invoice>> invoices = this.invoiceClient.getInvoices();
|
||||
|
||||
// then
|
||||
assertNotNull(invoices);
|
||||
assertEquals(HttpStatus.OK, invoices.getStatusCode());
|
||||
assertNotNull(invoices.getBody());
|
||||
assertEquals(100, invoices.getBody().size());
|
||||
assertThat(invoices).isNotNull();
|
||||
assertThat(invoices.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(invoices.getBody()).isNotNull();
|
||||
assertThat(invoices.getBody().size()).isEqualTo(100);
|
||||
|
||||
}
|
||||
|
||||
@@ -80,6 +78,7 @@ public class FeignAcceptEncodingTests {
|
||||
@SpringBootApplication(scanBasePackages = "org.springframework.cloud.openfeign.encoding.app")
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
public static class Application {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -95,5 +94,7 @@ public class FeignAcceptEncodingTests {
|
||||
Collections.singletonList(new Server("localhost", this.port)));
|
||||
return balancer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -16,23 +16,23 @@
|
||||
|
||||
package org.springframework.cloud.openfeign.encoding;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.netflix.loadbalancer.BaseLoadBalancer;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
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.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.encoding.app.client.InvoiceClient;
|
||||
import org.springframework.cloud.openfeign.encoding.app.domain.Invoice;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -41,16 +41,15 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.netflix.loadbalancer.BaseLoadBalancer;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* Tests the response compression.
|
||||
*
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
@SpringBootTest(classes = FeignContentEncodingTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
|
||||
@SpringBootTest(classes = FeignContentEncodingTests.Application.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"feign.compression.request.enabled=true",
|
||||
"hystrix.command.default.execution.isolation.strategy=SEMAPHORE",
|
||||
"ribbon.OkToRetryOnAllOperations=false" })
|
||||
@@ -71,10 +70,10 @@ public class FeignContentEncodingTests {
|
||||
.saveInvoices(invoices);
|
||||
|
||||
// then
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||
assertNotNull(response.getBody());
|
||||
assertEquals(invoices.size(), response.getBody().size());
|
||||
assertThat(response).isNotNull();
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().size()).isEqualTo(invoices.size());
|
||||
|
||||
}
|
||||
|
||||
@@ -83,6 +82,7 @@ public class FeignContentEncodingTests {
|
||||
@SpringBootApplication(scanBasePackages = "org.springframework.cloud.openfeign.encoding.app")
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
public static class Application {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -98,5 +98,7 @@ public class FeignContentEncodingTests {
|
||||
Collections.singletonList(new Server("localhost", this.port)));
|
||||
return balancer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.openfeign.encoding;
|
||||
|
||||
import org.springframework.cloud.openfeign.encoding.app.domain.Invoice;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.cloud.openfeign.encoding.app.domain.Invoice;
|
||||
|
||||
/**
|
||||
* Utility class used for testing.
|
||||
*
|
||||
@@ -35,9 +35,11 @@ final class Invoices {
|
||||
for (int ind = 0; ind < count; ind++) {
|
||||
final Invoice invoice = new Invoice();
|
||||
invoice.setTitle("Invoice " + (ind + 1));
|
||||
invoice.setAmount(new BigDecimal(String.format(Locale.US, "%.2f", Math.random() * 1000)));
|
||||
invoice.setAmount(new BigDecimal(
|
||||
String.format(Locale.US, "%.2f", Math.random() * 1000)));
|
||||
invoices.add(invoice);
|
||||
}
|
||||
return invoices;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -38,4 +38,5 @@ public interface InvoiceClient {
|
||||
|
||||
@RequestMapping(value = "invoices", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
ResponseEntity<List<Invoice>> saveInvoices(List<Invoice> invoices);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -30,7 +30,7 @@ public class Invoice {
|
||||
private BigDecimal amount;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
return this.title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
@@ -38,10 +38,11 @@ public class Invoice {
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package org.springframework.cloud.openfeign.encoding.app.resource;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.cloud.openfeign.encoding.app.domain.Invoice;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -24,11 +29,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* An sample REST controller, that potentially returns large response - used for testing.
|
||||
*
|
||||
@@ -43,8 +43,7 @@ public class InvoiceResource {
|
||||
return ResponseEntity.ok(createInvoiceList(100));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "invoices", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequestMapping(value = "invoices", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
ResponseEntity<List<Invoice>> saveInvoices(@RequestBody List<Invoice> invoices) {
|
||||
|
||||
return ResponseEntity.ok(invoices);
|
||||
@@ -55,9 +54,11 @@ public class InvoiceResource {
|
||||
for (int ind = 0; ind < count; ind++) {
|
||||
final Invoice invoice = new Invoice();
|
||||
invoice.setTitle("Invoice " + (ind + 1));
|
||||
invoice.setAmount(new BigDecimal(String.format(Locale.US, "%.2f", Math.random() * 1000)));
|
||||
invoice.setAmount(new BigDecimal(
|
||||
String.format(Locale.US, "%.2f", Math.random() * 1000)));
|
||||
invoices.add(invoice);
|
||||
}
|
||||
return invoices;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -39,17 +39,17 @@ import static feign.Request.HttpMethod.POST;
|
||||
@ClassPathExclusions("protobuf-*.jar")
|
||||
public class ProtobufNotInClasspathTest {
|
||||
|
||||
@Test
|
||||
public void testEncodeWhenProtobufNotInClasspath() {
|
||||
ObjectFactory<HttpMessageConverters> converters = new ObjectFactory<HttpMessageConverters>() {
|
||||
@Override
|
||||
public HttpMessageConverters getObject() throws BeansException {
|
||||
return new HttpMessageConverters(new StringHttpMessageConverter());
|
||||
}
|
||||
};
|
||||
RequestTemplate requestTemplate = new RequestTemplate();
|
||||
requestTemplate.method(POST);
|
||||
new SpringEncoder(converters).encode("a=b", String.class, requestTemplate);
|
||||
}
|
||||
@Test
|
||||
public void testEncodeWhenProtobufNotInClasspath() {
|
||||
ObjectFactory<HttpMessageConverters> converters = new ObjectFactory<HttpMessageConverters>() {
|
||||
@Override
|
||||
public HttpMessageConverters getObject() throws BeansException {
|
||||
return new HttpMessageConverters(new StringHttpMessageConverter());
|
||||
}
|
||||
};
|
||||
RequestTemplate requestTemplate = new RequestTemplate();
|
||||
requestTemplate.method(POST);
|
||||
new SpringEncoder(converters).encode("a=b", String.class, requestTemplate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -35,7 +35,6 @@ import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
@@ -53,6 +52,8 @@ import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
|
||||
|
||||
import static feign.Request.Body.encoded;
|
||||
import static feign.Request.HttpMethod.POST;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Test {@link SpringEncoder} with {@link ProtobufHttpMessageConverter}
|
||||
@@ -62,87 +63,92 @@ import static feign.Request.HttpMethod.POST;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ProtobufSpringEncoderTest {
|
||||
|
||||
@Mock
|
||||
private HttpClient httpClient;
|
||||
@Mock
|
||||
private HttpClient httpClient;
|
||||
|
||||
// a protobuf object with some content
|
||||
private org.springframework.cloud.openfeign.encoding.proto.Request request = org.springframework.cloud.openfeign.encoding.proto.Request.newBuilder()
|
||||
.setId(1000000)
|
||||
.setMsg("Erlang/OTP 最初是爱立信为开发电信设备系统设计的编程语言平台," +
|
||||
"电信设备(路由器、接入网关、…)典型设计是通过背板连接主控板卡与多块业务板卡的分布式系统。")
|
||||
.build();
|
||||
// a protobuf object with some content
|
||||
private org.springframework.cloud.openfeign.encoding.proto.Request request = org.springframework.cloud.openfeign.encoding.proto.Request
|
||||
.newBuilder().setId(1000000).setMsg("Erlang/OTP 最初是爱立信为开发电信设备系统设计的编程语言平台,"
|
||||
+ "电信设备(路由器、接入网关、…)典型设计是通过背板连接主控板卡与多块业务板卡的分布式系统。")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void testProtobuf() throws IOException, URISyntaxException {
|
||||
// protobuf convert to request by feign and ProtobufHttpMessageConverter
|
||||
RequestTemplate requestTemplate = newRequestTemplate();
|
||||
newEncoder().encode(request, Request.class, requestTemplate);
|
||||
HttpEntity entity = toApacheHttpEntity(requestTemplate);
|
||||
byte[] bytes = read(entity.getContent(), (int) entity.getContentLength());
|
||||
@Test
|
||||
public void testProtobuf() throws IOException, URISyntaxException {
|
||||
// protobuf convert to request by feign and ProtobufHttpMessageConverter
|
||||
RequestTemplate requestTemplate = newRequestTemplate();
|
||||
newEncoder().encode(this.request, Request.class, requestTemplate);
|
||||
HttpEntity entity = toApacheHttpEntity(requestTemplate);
|
||||
byte[] bytes = read(entity.getContent(), (int) entity.getContentLength());
|
||||
|
||||
Assert.assertArrayEquals(bytes, request.toByteArray());
|
||||
org.springframework.cloud.openfeign.encoding.proto.Request copy = org.springframework.cloud.openfeign.encoding.proto.Request.parseFrom(bytes);
|
||||
Assert.assertEquals(request, copy);
|
||||
}
|
||||
assertThat(this.request.toByteArray()).isEqualTo(bytes);
|
||||
org.springframework.cloud.openfeign.encoding.proto.Request copy = org.springframework.cloud.openfeign.encoding.proto.Request
|
||||
.parseFrom(bytes);
|
||||
assertThat(copy).isEqualTo(this.request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProtobufWithCharsetWillFail() throws IOException, URISyntaxException {
|
||||
// protobuf convert to request by feign and ProtobufHttpMessageConverter
|
||||
RequestTemplate requestTemplate = newRequestTemplate();
|
||||
newEncoder().encode(request, Request.class, requestTemplate);
|
||||
// set a charset
|
||||
requestTemplate
|
||||
.body(encoded(requestTemplate.requestBody()
|
||||
.asBytes(), StandardCharsets.UTF_8));
|
||||
HttpEntity entity = toApacheHttpEntity(requestTemplate);
|
||||
byte[] bytes = read(entity.getContent(), (int) entity.getContentLength());
|
||||
@Test
|
||||
public void testProtobufWithCharsetWillFail() throws IOException, URISyntaxException {
|
||||
// protobuf convert to request by feign and ProtobufHttpMessageConverter
|
||||
RequestTemplate requestTemplate = newRequestTemplate();
|
||||
newEncoder().encode(this.request, Request.class, requestTemplate);
|
||||
// set a charset
|
||||
requestTemplate.body(
|
||||
encoded(requestTemplate.requestBody().asBytes(), StandardCharsets.UTF_8));
|
||||
HttpEntity entity = toApacheHttpEntity(requestTemplate);
|
||||
byte[] bytes = read(entity.getContent(), (int) entity.getContentLength());
|
||||
|
||||
// http request-body is different with original protobuf body
|
||||
Assert.assertNotEquals(bytes.length, request.toByteArray().length);
|
||||
try {
|
||||
org.springframework.cloud.openfeign.encoding.proto.Request copy = org.springframework.cloud.openfeign.encoding.proto.Request.parseFrom(bytes);
|
||||
Assert.fail("Expected an InvalidProtocolBufferException to be thrown");
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
// http request-body is different with original protobuf body
|
||||
assertThat(this.request.toByteArray().length).isNotEqualTo(bytes.length);
|
||||
try {
|
||||
org.springframework.cloud.openfeign.encoding.proto.Request copy = org.springframework.cloud.openfeign.encoding.proto.Request
|
||||
.parseFrom(bytes);
|
||||
fail("Expected an InvalidProtocolBufferException to be thrown");
|
||||
}
|
||||
catch (InvalidProtocolBufferException e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
|
||||
private SpringEncoder newEncoder() {
|
||||
ObjectFactory<HttpMessageConverters> converters = new ObjectFactory<HttpMessageConverters>() {
|
||||
@Override
|
||||
public HttpMessageConverters getObject() throws BeansException {
|
||||
return new HttpMessageConverters(new ProtobufHttpMessageConverter());
|
||||
}
|
||||
};
|
||||
return new SpringEncoder(converters);
|
||||
}
|
||||
private SpringEncoder newEncoder() {
|
||||
ObjectFactory<HttpMessageConverters> converters = new ObjectFactory<HttpMessageConverters>() {
|
||||
@Override
|
||||
public HttpMessageConverters getObject() throws BeansException {
|
||||
return new HttpMessageConverters(new ProtobufHttpMessageConverter());
|
||||
}
|
||||
};
|
||||
return new SpringEncoder(converters);
|
||||
}
|
||||
|
||||
private RequestTemplate newRequestTemplate() {
|
||||
RequestTemplate requestTemplate = new RequestTemplate();
|
||||
requestTemplate.method(POST);
|
||||
return requestTemplate;
|
||||
}
|
||||
private RequestTemplate newRequestTemplate() {
|
||||
RequestTemplate requestTemplate = new RequestTemplate();
|
||||
requestTemplate.method(POST);
|
||||
return requestTemplate;
|
||||
}
|
||||
|
||||
private HttpEntity toApacheHttpEntity(RequestTemplate requestTemplate) throws IOException, URISyntaxException {
|
||||
final List<HttpUriRequest> request = new ArrayList<>(1);
|
||||
BDDMockito.given(httpClient.execute(ArgumentMatchers.<HttpUriRequest>any()))
|
||||
.will(new Answer<HttpResponse>() {
|
||||
@Override
|
||||
public HttpResponse answer(InvocationOnMock invocationOnMock) throws Throwable {
|
||||
request.add((HttpUriRequest) invocationOnMock.getArguments()[0]);
|
||||
return new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion("http", 1, 1), 200, null));
|
||||
}
|
||||
});
|
||||
new ApacheHttpClient(httpClient).execute(requestTemplate.resolve(new HashMap<>())
|
||||
.request(), new feign.Request.Options());
|
||||
HttpUriRequest httpUriRequest = request.get(0);
|
||||
return ((HttpEntityEnclosingRequestBase)httpUriRequest).getEntity();
|
||||
}
|
||||
private HttpEntity toApacheHttpEntity(RequestTemplate requestTemplate)
|
||||
throws IOException, URISyntaxException {
|
||||
final List<HttpUriRequest> request = new ArrayList<>(1);
|
||||
BDDMockito.given(this.httpClient.execute(ArgumentMatchers.<HttpUriRequest>any()))
|
||||
.will(new Answer<HttpResponse>() {
|
||||
@Override
|
||||
public HttpResponse answer(InvocationOnMock invocationOnMock)
|
||||
throws Throwable {
|
||||
request.add((HttpUriRequest) invocationOnMock.getArguments()[0]);
|
||||
return new BasicHttpResponse(new BasicStatusLine(
|
||||
new ProtocolVersion("http", 1, 1), 200, null));
|
||||
}
|
||||
});
|
||||
new ApacheHttpClient(this.httpClient).execute(
|
||||
requestTemplate.resolve(new HashMap<>()).request(),
|
||||
new feign.Request.Options());
|
||||
HttpUriRequest httpUriRequest = request.get(0);
|
||||
return ((HttpEntityEnclosingRequestBase) httpUriRequest).getEntity();
|
||||
}
|
||||
|
||||
private byte[] read(InputStream in, int length) throws IOException {
|
||||
byte[] bytes = new byte[length];
|
||||
in.read(bytes);
|
||||
return bytes;
|
||||
}
|
||||
private byte[] read(InputStream in, int length) throws IOException {
|
||||
byte[] bytes = new byte[length];
|
||||
in.read(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -20,53 +20,48 @@
|
||||
package org.springframework.cloud.openfeign.encoding.proto;
|
||||
|
||||
public final class ProtobufTest {
|
||||
private ProtobufTest() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions(
|
||||
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
static final com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_Request_descriptor;
|
||||
static final
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||
internal_static_Request_fieldAccessorTable;
|
||||
static final com.google.protobuf.Descriptors.Descriptor internal_static_Request_descriptor;
|
||||
static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_Request_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
String[] descriptorData = {
|
||||
"\n\023protobuf_test.proto\"\"\n\007Request\022\n\n\002id\030\001" +
|
||||
" \001(\005\022\013\n\003msg\030\002 \001(\tB\024\n\020feign.httpclientP\001b" +
|
||||
"\006proto3"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
|
||||
public com.google.protobuf.ExtensionRegistry assignDescriptors(
|
||||
com.google.protobuf.Descriptors.FileDescriptor root) {
|
||||
descriptor = root;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
}, assigner);
|
||||
internal_static_Request_descriptor =
|
||||
getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_Request_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||
internal_static_Request_descriptor,
|
||||
new String[] { "Id", "Msg", });
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor descriptor;
|
||||
|
||||
static {
|
||||
String[] descriptorData = {
|
||||
"\n\023protobuf_test.proto\"\"\n\007Request\022\n\n\002id\030\001"
|
||||
+ " \001(\005\022\013\n\003msg\030\002 \001(\tB\024\n\020feign.httpclientP\001b"
|
||||
+ "\006proto3" };
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
public com.google.protobuf.ExtensionRegistry assignDescriptors(
|
||||
com.google.protobuf.Descriptors.FileDescriptor root) {
|
||||
descriptor = root;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(
|
||||
descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] {},
|
||||
assigner);
|
||||
internal_static_Request_descriptor = getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_Request_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||
internal_static_Request_descriptor, new String[] { "Id", "Msg", });
|
||||
}
|
||||
|
||||
private ProtobufTest() {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -20,21 +20,22 @@
|
||||
package org.springframework.cloud.openfeign.encoding.proto;
|
||||
|
||||
public interface RequestOrBuilder extends
|
||||
// @@protoc_insertion_point(interface_extends:Request)
|
||||
com.google.protobuf.MessageOrBuilder {
|
||||
// @@protoc_insertion_point(interface_extends:Request)
|
||||
com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
/**
|
||||
* <code>int32 id = 1;</code>
|
||||
*/
|
||||
int getId();
|
||||
/**
|
||||
* <code>int32 id = 1;</code>
|
||||
*/
|
||||
int getId();
|
||||
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
String getMsg();
|
||||
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString getMsgBytes();
|
||||
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
String getMsg();
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getMsgBytes();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -51,50 +51,27 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* 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(SpringRunner.class)
|
||||
@DirtiesContext
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "feign.hystrix.enabled=true"})
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
|
||||
"feign.hystrix.enabled=true" })
|
||||
@ActiveProfiles("proxysecurity")
|
||||
public class HystrixSecurityTests {
|
||||
|
||||
@Autowired
|
||||
private CustomConcurrenyStrategy customConcurrenyStrategy;
|
||||
|
||||
@LocalServerPort
|
||||
private String serverPort;
|
||||
|
||||
//TODO: move to constants in TestAutoConfiguration
|
||||
// TODO: move to constants in TestAutoConfiguration
|
||||
private String username = "user";
|
||||
|
||||
private String password = "password";
|
||||
|
||||
@Test
|
||||
public void testSecurityConcurrencyStrategyInstalled() {
|
||||
HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
|
||||
assertThat(concurrencyStrategy).isInstanceOf(SecurityContextConcurrencyStrategy.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignHystrixSecurity() {
|
||||
HttpHeaders headers = createBasicAuthHeader(username, password);
|
||||
|
||||
ResponseEntity<String> entity = new RestTemplate()
|
||||
.exchange("http://localhost:" + serverPort + "/proxy-username",
|
||||
HttpMethod.GET, new HttpEntity<Void>(headers), String.class);
|
||||
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
assertThat(entity.getBody())
|
||||
.as("Username should have been intercepted by feign interceptor.")
|
||||
.isEqualTo(username);
|
||||
|
||||
assertThat(customConcurrenyStrategy.isHookCalled())
|
||||
.as("Custom hook should have been called.")
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
public static HttpHeaders createBasicAuthHeader(final String username,
|
||||
final String password) {
|
||||
return new HttpHeaders() {
|
||||
@@ -109,10 +86,38 @@ public class HystrixSecurityTests {
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityConcurrencyStrategyInstalled() {
|
||||
HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance()
|
||||
.getConcurrencyStrategy();
|
||||
assertThat(concurrencyStrategy)
|
||||
.isInstanceOf(SecurityContextConcurrencyStrategy.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignHystrixSecurity() {
|
||||
HttpHeaders headers = createBasicAuthHeader(this.username, this.password);
|
||||
|
||||
ResponseEntity<String> entity = new RestTemplate().exchange(
|
||||
"http://localhost:" + this.serverPort + "/proxy-username", HttpMethod.GET,
|
||||
new HttpEntity<Void>(headers), String.class);
|
||||
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
assertThat(entity.getBody())
|
||||
.as("Username should have been intercepted by feign interceptor.")
|
||||
.isEqualTo(this.username);
|
||||
|
||||
assertThat(this.customConcurrenyStrategy.isHookCalled())
|
||||
.as("Custom hook should have been called.").isTrue();
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@Import(HystrixSecurityApplication.class)
|
||||
@RibbonClient(name = "username", configuration = LocalRibbonClientConfiguration.class)
|
||||
protected static class TestConfig { }
|
||||
protected static class TestConfig {
|
||||
|
||||
}
|
||||
|
||||
protected static class LocalRibbonClientConfiguration {
|
||||
|
||||
@@ -125,4 +130,5 @@ public class HystrixSecurityTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
package org.springframework.cloud.openfeign.hystrix.security.app;
|
||||
/*
|
||||
* Copyright 2013-2019 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.
|
||||
*/
|
||||
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
package org.springframework.cloud.openfeign.hystrix.security.app;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
|
||||
public class CustomConcurrenyStrategy extends HystrixConcurrencyStrategy {
|
||||
|
||||
private boolean hookCalled;
|
||||
|
||||
@Override
|
||||
@@ -15,6 +32,7 @@ public class CustomConcurrenyStrategy extends HystrixConcurrencyStrategy {
|
||||
}
|
||||
|
||||
public boolean isHookCalled() {
|
||||
return hookCalled;
|
||||
return this.hookCalled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -26,11 +26,13 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RestController
|
||||
@RequestMapping("/proxy-username")
|
||||
public class ProxyUsernameController {
|
||||
|
||||
@Autowired
|
||||
private UsernameClient usernameClient;
|
||||
|
||||
@RequestMapping
|
||||
public String getUsername() {
|
||||
return usernameClient.getUsername();
|
||||
return this.usernameClient.getUsername();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -24,15 +24,17 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public class TestInterceptor implements RequestInterceptor {
|
||||
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
if (SecurityContextHolder.getContext().getAuthentication() != null)
|
||||
if (SecurityContextHolder.getContext().getAuthentication() != null) {
|
||||
template.header("username",
|
||||
SecurityContextHolder.getContext().getAuthentication().getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -27,4 +27,5 @@ public interface UsernameClient {
|
||||
|
||||
@RequestMapping("/username")
|
||||
String getUsername();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -26,8 +26,10 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RestController
|
||||
@RequestMapping("/username")
|
||||
public class UsernameController {
|
||||
|
||||
@RequestMapping
|
||||
public String getUsername(@RequestHeader String username){
|
||||
public String getUsername(@RequestHeader String username) {
|
||||
return username;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -19,10 +19,10 @@ package org.springframework.cloud.openfeign.invalid;
|
||||
import feign.Feign;
|
||||
import feign.hystrix.FallbackFactory;
|
||||
import feign.hystrix.HystrixFeign;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
@@ -37,7 +37,7 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -53,6 +53,81 @@ public class FeignClientValidationTests {
|
||||
new AnnotationConfigApplicationContext(NameAndValueConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceIdAndValue() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
LoadBalancerAutoConfiguration.class, RibbonAutoConfiguration.class,
|
||||
FeignRibbonClientAutoConfiguration.class,
|
||||
NameAndServiceIdConfiguration.class);
|
||||
assertThat(context.getBean(NameAndServiceIdConfiguration.Client.class))
|
||||
.isNotNull();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicatedClientNames() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.setAllowBeanDefinitionOverriding(false);
|
||||
context.register(LoadBalancerAutoConfiguration.class,
|
||||
RibbonAutoConfiguration.class, FeignRibbonClientAutoConfiguration.class,
|
||||
DuplicatedFeignClientNamesConfiguration.class);
|
||||
context.refresh();
|
||||
assertThat(
|
||||
context.getBean(DuplicatedFeignClientNamesConfiguration.FooClient.class))
|
||||
.isNotNull();
|
||||
assertThat(
|
||||
context.getBean(DuplicatedFeignClientNamesConfiguration.BarClient.class))
|
||||
.isNotNull();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotLegalHostname() {
|
||||
this.expected.expectMessage("not legal hostname (foo_bar)");
|
||||
new AnnotationConfigApplicationContext(BadHostnameConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingFallback() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
MissingFallbackConfiguration.class)) {
|
||||
this.expected.expectMessage("No fallback instance of type");
|
||||
assertThat(context.getBean(MissingFallbackConfiguration.Client.class))
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongFallbackType() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
WrongFallbackTypeConfiguration.class)) {
|
||||
this.expected.expectMessage("Incompatible fallback instance");
|
||||
assertThat(context.getBean(WrongFallbackTypeConfiguration.Client.class))
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingFallbackFactory() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
MissingFallbackFactoryConfiguration.class)) {
|
||||
this.expected.expectMessage("No fallbackFactory instance of type");
|
||||
assertThat(context.getBean(MissingFallbackFactoryConfiguration.Client.class))
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongFallbackFactoryType() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
WrongFallbackFactoryTypeConfiguration.class)) {
|
||||
this.expected.expectMessage("Incompatible fallbackFactory instance");
|
||||
assertThat(
|
||||
context.getBean(WrongFallbackFactoryTypeConfiguration.Client.class))
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(FeignAutoConfiguration.class)
|
||||
@EnableFeignClients(clients = NameAndValueConfiguration.Client.class)
|
||||
@@ -60,75 +135,53 @@ public class FeignClientValidationTests {
|
||||
|
||||
@FeignClient(value = "foo", name = "bar")
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceIdAndValue() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
LoadBalancerAutoConfiguration.class,
|
||||
RibbonAutoConfiguration.class,
|
||||
FeignRibbonClientAutoConfiguration.class,
|
||||
NameAndServiceIdConfiguration.class);
|
||||
assertNotNull(context.getBean(NameAndServiceIdConfiguration.Client.class));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({FeignAutoConfiguration.class, HttpClientConfiguration.class})
|
||||
@Import({ FeignAutoConfiguration.class, HttpClientConfiguration.class })
|
||||
@EnableFeignClients(clients = NameAndServiceIdConfiguration.Client.class)
|
||||
protected static class NameAndServiceIdConfiguration {
|
||||
|
||||
@FeignClient(name = "bar", serviceId = "foo")
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicatedClientNames() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.setAllowBeanDefinitionOverriding(false);
|
||||
context.register(
|
||||
LoadBalancerAutoConfiguration.class,
|
||||
RibbonAutoConfiguration.class,
|
||||
FeignRibbonClientAutoConfiguration.class,
|
||||
DuplicatedFeignClientNamesConfiguration.class
|
||||
);
|
||||
context.refresh();
|
||||
assertNotNull(context.getBean(DuplicatedFeignClientNamesConfiguration.FooClient.class));
|
||||
assertNotNull(context.getBean(DuplicatedFeignClientNamesConfiguration.BarClient.class));
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@Import({FeignAutoConfiguration.class, HttpClientConfiguration.class})
|
||||
@EnableFeignClients(clients = {DuplicatedFeignClientNamesConfiguration.FooClient.class,
|
||||
DuplicatedFeignClientNamesConfiguration.BarClient.class})
|
||||
@Import({ FeignAutoConfiguration.class, HttpClientConfiguration.class })
|
||||
@EnableFeignClients(clients = {
|
||||
DuplicatedFeignClientNamesConfiguration.FooClient.class,
|
||||
DuplicatedFeignClientNamesConfiguration.BarClient.class })
|
||||
protected static class DuplicatedFeignClientNamesConfiguration {
|
||||
|
||||
@FeignClient(contextId = "foo", name = "bar")
|
||||
interface FooClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "bar")
|
||||
interface BarClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotLegalHostname() {
|
||||
this.expected.expectMessage("not legal hostname (foo_bar)");
|
||||
new AnnotationConfigApplicationContext(BadHostnameConfiguration.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -138,53 +191,41 @@ public class FeignClientValidationTests {
|
||||
|
||||
@FeignClient("foo_bar")
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingFallback() {
|
||||
try (
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
MissingFallbackConfiguration.class)) {
|
||||
this.expected.expectMessage("No fallback instance of type");
|
||||
assertNotNull(context.getBean(MissingFallbackConfiguration.Client.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(FeignAutoConfiguration.class)
|
||||
@EnableFeignClients(clients = MissingFallbackConfiguration.Client.class)
|
||||
protected static class MissingFallbackConfiguration {
|
||||
|
||||
@FeignClient(name = "foobar", url = "http://localhost", fallback = ClientFallback.class)
|
||||
interface Client {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
}
|
||||
|
||||
class ClientFallback implements Client {
|
||||
@Override
|
||||
public String get() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Feign.Builder feignBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongFallbackType() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
WrongFallbackTypeConfiguration.class)) {
|
||||
this.expected.expectMessage("Incompatible fallback instance");
|
||||
assertNotNull(context.getBean(WrongFallbackTypeConfiguration.Client.class));
|
||||
@FeignClient(name = "foobar", url = "http://localhost", fallback = ClientFallback.class)
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
class ClientFallback implements Client {
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -192,34 +233,28 @@ public class FeignClientValidationTests {
|
||||
@EnableFeignClients(clients = WrongFallbackTypeConfiguration.Client.class)
|
||||
protected static class WrongFallbackTypeConfiguration {
|
||||
|
||||
@FeignClient(name = "foobar", url = "http://localhost", fallback = Dummy.class)
|
||||
interface Client {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
}
|
||||
|
||||
@Bean
|
||||
Dummy dummy() {
|
||||
return new Dummy();
|
||||
}
|
||||
|
||||
class Dummy {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Feign.Builder feignBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
|
||||
}
|
||||
@FeignClient(name = "foobar", url = "http://localhost", fallback = Dummy.class)
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
|
||||
@Test
|
||||
public void testMissingFallbackFactory() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
MissingFallbackFactoryConfiguration.class)) {
|
||||
this.expected.expectMessage("No fallbackFactory instance of type");
|
||||
assertNotNull(context.getBean(MissingFallbackFactoryConfiguration.Client.class));
|
||||
}
|
||||
|
||||
class Dummy {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -227,10 +262,17 @@ public class FeignClientValidationTests {
|
||||
@EnableFeignClients(clients = MissingFallbackFactoryConfiguration.Client.class)
|
||||
protected static class MissingFallbackFactoryConfiguration {
|
||||
|
||||
@Bean
|
||||
public Feign.Builder feignBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
|
||||
@FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = ClientFallback.class)
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
class ClientFallback implements FallbackFactory<Client> {
|
||||
@@ -239,21 +281,9 @@ public class FeignClientValidationTests {
|
||||
public Client create(Throwable cause) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Feign.Builder feignBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongFallbackFactoryType() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
WrongFallbackFactoryTypeConfiguration.class)) {
|
||||
this.expected.expectMessage("Incompatible fallbackFactory instance");
|
||||
assertNotNull(context.getBean(WrongFallbackFactoryTypeConfiguration.Client.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -261,24 +291,28 @@ public class FeignClientValidationTests {
|
||||
@EnableFeignClients(clients = WrongFallbackFactoryTypeConfiguration.Client.class)
|
||||
protected static class WrongFallbackFactoryTypeConfiguration {
|
||||
|
||||
@FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = Dummy.class)
|
||||
interface Client {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
}
|
||||
|
||||
@Bean
|
||||
Dummy dummy() {
|
||||
return new Dummy();
|
||||
}
|
||||
|
||||
class Dummy {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Feign.Builder feignBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
|
||||
@FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = Dummy.class)
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
class Dummy {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -23,10 +23,11 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -56,13 +57,13 @@ public class CachingSpringLoadBalancerFactoryTests {
|
||||
when(this.delegate.getClientConfig("client2")).thenReturn(config);
|
||||
|
||||
this.factory = new CachingSpringLoadBalancerFactory(this.delegate,
|
||||
loadBalancedRetryFactory);
|
||||
this.loadBalancedRetryFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delegateCreatesWhenMissing() {
|
||||
FeignLoadBalancer client = this.factory.create("client1");
|
||||
assertNotNull("client was null", client);
|
||||
assertThat(client).as("client was null").isNotNull();
|
||||
|
||||
verify(this.delegate, times(1)).getClientConfig("client1");
|
||||
}
|
||||
@@ -70,10 +71,10 @@ public class CachingSpringLoadBalancerFactoryTests {
|
||||
@Test
|
||||
public void cacheWorks() {
|
||||
FeignLoadBalancer client = this.factory.create("client2");
|
||||
assertNotNull("client was null", client);
|
||||
assertThat(client).as("client was null").isNotNull();
|
||||
|
||||
client = this.factory.create("client2");
|
||||
assertNotNull("client was null", client);
|
||||
assertThat(client).as("client was null").isNotNull();
|
||||
|
||||
verify(this.delegate, times(1)).getClientConfig("client2");
|
||||
}
|
||||
@@ -84,9 +85,10 @@ public class CachingSpringLoadBalancerFactoryTests {
|
||||
config.set(CommonClientConfigKey.ConnectTimeout, 1000);
|
||||
config.set(CommonClientConfigKey.ReadTimeout, 500);
|
||||
when(this.delegate.getClientConfig("retry")).thenReturn(config);
|
||||
CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(this.delegate);
|
||||
CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(
|
||||
this.delegate);
|
||||
FeignLoadBalancer client = this.factory.create("retry");
|
||||
assertNotNull("client was null", client);
|
||||
assertThat(client).as("client was null").isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -95,8 +97,10 @@ public class CachingSpringLoadBalancerFactoryTests {
|
||||
config.set(CommonClientConfigKey.ConnectTimeout, 1000);
|
||||
config.set(CommonClientConfigKey.ReadTimeout, 500);
|
||||
when(this.delegate.getClientConfig("retry")).thenReturn(config);
|
||||
CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(this.delegate, loadBalancedRetryFactory);
|
||||
CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(
|
||||
this.delegate, this.loadBalancedRetryFactory);
|
||||
FeignLoadBalancer client = this.factory.create("retry");
|
||||
assertNotNull("client was null", client);
|
||||
assertThat(client).as("client was null").isNotNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,7 +12,6 @@
|
||||
* 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.openfeign.ribbon;
|
||||
@@ -53,8 +52,7 @@ import static com.netflix.client.config.CommonClientConfigKey.ReadTimeout;
|
||||
import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES;
|
||||
import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER;
|
||||
import static feign.Request.HttpMethod.GET;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -64,8 +62,10 @@ public class FeignLoadBalancerTests {
|
||||
|
||||
@Mock
|
||||
private Client delegate;
|
||||
|
||||
@Mock
|
||||
private ILoadBalancer lb;
|
||||
|
||||
@Mock
|
||||
private IClientConfig config;
|
||||
|
||||
@@ -74,6 +74,7 @@ public class FeignLoadBalancerTests {
|
||||
private ServerIntrospector inspector = new DefaultServerIntrospector();
|
||||
|
||||
private Integer defaultConnectTimeout = 10000;
|
||||
|
||||
private Integer defaultReadTimeout = 10000;
|
||||
|
||||
@Before
|
||||
@@ -95,27 +96,19 @@ public class FeignLoadBalancerTests {
|
||||
|
||||
this.feignLoadBalancer = new FeignLoadBalancer(this.lb, this.config,
|
||||
this.inspector);
|
||||
Request request = new RequestTemplate()
|
||||
.method(GET)
|
||||
.target("http://foo/")
|
||||
.resolve(new HashMap<>())
|
||||
.request();
|
||||
Request request = new RequestTemplate().method(GET).target("http://foo/")
|
||||
.resolve(new HashMap<>()).request();
|
||||
RibbonRequest ribbonRequest = new RibbonRequest(this.delegate, request,
|
||||
new URI(request.url()));
|
||||
|
||||
Response response = Response.builder()
|
||||
.request(request)
|
||||
.status(200)
|
||||
.reason("Test")
|
||||
.headers(Collections.emptyMap())
|
||||
.body(new byte[0])
|
||||
.build();
|
||||
Response response = Response.builder().request(request).status(200).reason("Test")
|
||||
.headers(Collections.emptyMap()).body(new byte[0]).build();
|
||||
when(this.delegate.execute(any(Request.class), any(Options.class)))
|
||||
.thenReturn(response);
|
||||
|
||||
RibbonResponse resp = this.feignLoadBalancer.execute(ribbonRequest, null);
|
||||
|
||||
assertThat(resp.getRequestedURI(), is(new URI("http://foo")));
|
||||
assertThat(resp.getRequestedURI()).isEqualTo(new URI("http://foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,7 +119,7 @@ public class FeignLoadBalancerTests {
|
||||
Server server = new Server("foo", 7777);
|
||||
URI uri = this.feignLoadBalancer.reconstructURIWithServer(server,
|
||||
new URI("http://foo/"));
|
||||
assertThat(uri, is(new URI("https://foo:7777/")));
|
||||
assertThat(uri).isEqualTo(new URI("https://foo:7777/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,7 +141,7 @@ public class FeignLoadBalancerTests {
|
||||
Server server = new Server("foo", 7777);
|
||||
URI uri = this.feignLoadBalancer.reconstructURIWithServer(server,
|
||||
new URI("http://foo/"));
|
||||
assertThat(uri, is(new URI("http://foo:7777/")));
|
||||
assertThat(uri).isEqualTo(new URI("http://foo:7777/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -160,21 +153,22 @@ public class FeignLoadBalancerTests {
|
||||
when(server.getHost()).thenReturn("foo");
|
||||
URI uri = this.feignLoadBalancer.reconstructURIWithServer(server,
|
||||
new URI("http://bar/"));
|
||||
assertThat(uri, is(new URI("https://foo:443/")));
|
||||
assertThat(uri).isEqualTo(new URI("https://foo:443/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRibbonRequestURLEncode() throws Exception {
|
||||
String url = "http://foo/?name=%7bcookie";//name={cookie
|
||||
String url = "http://foo/?name=%7bcookie"; // name={cookie
|
||||
Request request = Request.create(GET, url, new HashMap<>(), null, null);
|
||||
|
||||
assertThat(request.url(),is(url));
|
||||
assertThat(request.url()).isEqualTo(url);
|
||||
|
||||
RibbonRequest ribbonRequest = new RibbonRequest(this.delegate,request,new URI(request.url()));
|
||||
RibbonRequest ribbonRequest = new RibbonRequest(this.delegate, request,
|
||||
new URI(request.url()));
|
||||
|
||||
Request cloneRequest = ribbonRequest.toRequest();
|
||||
|
||||
assertThat(cloneRequest.url(),is(url));
|
||||
assertThat(cloneRequest.url()).isEqualTo(url);
|
||||
|
||||
}
|
||||
|
||||
@@ -193,23 +187,23 @@ public class FeignLoadBalancerTests {
|
||||
|
||||
this.feignLoadBalancer = new FeignLoadBalancer(baseLoadBalancer, this.config,
|
||||
this.inspector) {
|
||||
protected void customizeLoadBalancerCommandBuilder(final FeignLoadBalancer.RibbonRequest request, final IClientConfig config,
|
||||
final LoadBalancerCommand.Builder<FeignLoadBalancer.RibbonResponse> builder) {
|
||||
protected void customizeLoadBalancerCommandBuilder(
|
||||
final FeignLoadBalancer.RibbonRequest request,
|
||||
final IClientConfig config,
|
||||
final LoadBalancerCommand.Builder<FeignLoadBalancer.RibbonResponse> builder) {
|
||||
builder.withServerLocator(request.getRequest().headers().get("c_ip"));
|
||||
}
|
||||
};
|
||||
Request request = new RequestTemplate().method(GET).resolve(new HashMap<>()).request();
|
||||
RibbonResponse resp = this.feignLoadBalancer.executeWithLoadBalancer(new RibbonRequest(this.delegate, request,
|
||||
new URI(request.url())), null);
|
||||
assertThat(resp.getRequestedURI().getPort(), is(7777));
|
||||
request = new RequestTemplate()
|
||||
.method(GET)
|
||||
.header("c_ip", "666")
|
||||
.resolve(new HashMap<>())
|
||||
Request request = new RequestTemplate().method(GET).resolve(new HashMap<>())
|
||||
.request();
|
||||
resp = this.feignLoadBalancer.executeWithLoadBalancer(new RibbonRequest(this.delegate, request,
|
||||
new URI(request.url())), null);
|
||||
assertThat(resp.getRequestedURI().getPort(), is(6666));
|
||||
RibbonResponse resp = this.feignLoadBalancer.executeWithLoadBalancer(
|
||||
new RibbonRequest(this.delegate, request, new URI(request.url())), null);
|
||||
assertThat(resp.getRequestedURI().getPort()).isEqualTo(7777);
|
||||
request = new RequestTemplate().method(GET).header("c_ip", "666")
|
||||
.resolve(new HashMap<>()).request();
|
||||
resp = this.feignLoadBalancer.executeWithLoadBalancer(
|
||||
new RibbonRequest(this.delegate, request, new URI(request.url())), null);
|
||||
assertThat(resp.getRequestedURI().getPort()).isEqualTo(6666);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -25,7 +25,6 @@ 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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
@@ -40,21 +39,18 @@ 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.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Venil Noronha
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = FeignRibbonClientPathTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT,value = {
|
||||
"spring.application.name=feignribbonclientpathtest",
|
||||
"feign.okhttp.enabled=false",
|
||||
"feign.httpclient.enabled=false",
|
||||
"feign.hystrix.enabled=false",
|
||||
@SpringBootTest(classes = FeignRibbonClientPathTests.Application.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"spring.application.name=feignribbonclientpathtest", "feign.okhttp.enabled=false",
|
||||
"feign.httpclient.enabled=false", "feign.hystrix.enabled=false",
|
||||
"test.path.prefix=/base/path" // For pathWithPlaceholder test
|
||||
}
|
||||
)
|
||||
})
|
||||
@DirtiesContext
|
||||
public class FeignRibbonClientPathTests {
|
||||
|
||||
@@ -72,51 +68,10 @@ public class FeignRibbonClientPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestClient4 testClient4;
|
||||
|
||||
|
||||
@Autowired
|
||||
private TestClient5 testClient5;
|
||||
|
||||
protected interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "localapp", path = "/base/path")
|
||||
protected interface TestClient1 extends TestClient { }
|
||||
|
||||
@FeignClient(name = "localapp1", path = "base/path")
|
||||
protected interface TestClient2 extends TestClient { }
|
||||
|
||||
@FeignClient(name = "localapp2", path = "base/path/")
|
||||
protected interface TestClient3 extends TestClient { }
|
||||
|
||||
@FeignClient(name = "localapp3", path = "/base/path/")
|
||||
protected interface TestClient4 extends TestClient { }
|
||||
|
||||
@FeignClient(name = "localapp4", path = "${test.path.prefix}")
|
||||
protected interface TestClient5 extends TestClient { }
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@RequestMapping("/base/path")
|
||||
@EnableFeignClients(clients = {
|
||||
TestClient1.class, TestClient2.class, TestClient3.class, TestClient4.class,
|
||||
TestClient5.class
|
||||
})
|
||||
@RibbonClients(defaultConfiguration = LocalRibbonClientConfiguration.class)
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
public static class Application {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pathWithLeadingButNotTrailingSlash() {
|
||||
testClientPath(this.testClient1);
|
||||
@@ -144,27 +99,79 @@ public class FeignRibbonClientPathTests {
|
||||
|
||||
private void testClientPath(TestClient testClient) {
|
||||
Hello hello = testClient.getHello();
|
||||
assertNotNull("Object returned was null", hello);
|
||||
assertEquals("Response object value didn't match", "hello world",
|
||||
hello.getMessage());
|
||||
assertThat(hello).as("Object returned was null").isNotNull();
|
||||
assertThat(hello.getMessage()).as("Response object value didn't match")
|
||||
.isEqualTo("hello world");
|
||||
}
|
||||
|
||||
protected interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "localapp", path = "/base/path")
|
||||
protected interface TestClient1 extends TestClient {
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "localapp1", path = "base/path")
|
||||
protected interface TestClient2 extends TestClient {
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "localapp2", path = "base/path/")
|
||||
protected interface TestClient3 extends TestClient {
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "localapp3", path = "/base/path/")
|
||||
protected interface TestClient4 extends TestClient {
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "localapp4", path = "${test.path.prefix}")
|
||||
protected interface TestClient5 extends TestClient {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@RequestMapping("/base/path")
|
||||
@EnableFeignClients(clients = { TestClient1.class, TestClient2.class,
|
||||
TestClient3.class, TestClient4.class, TestClient5.class })
|
||||
@RibbonClients(defaultConfiguration = LocalRibbonClientConfiguration.class)
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
public static class Application {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
|
||||
private String message;
|
||||
|
||||
public Hello() {}
|
||||
public Hello() {
|
||||
}
|
||||
|
||||
public Hello(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -20,17 +20,19 @@ import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -41,22 +43,20 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* Tests the Feign Retryer, not ribbon retry.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = FeignRibbonClientRetryTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
|
||||
@SpringBootTest(classes = FeignRibbonClientRetryTests.Application.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"spring.application.name=feignclientretrytest", "feign.okhttp.enabled=false",
|
||||
"feign.httpclient.enabled=false", "feign.hystrix.enabled=false", "localapp.ribbon.MaxAutoRetries=2",
|
||||
"localapp.ribbon.MaxAutoRetriesNextServer=3"})
|
||||
"feign.httpclient.enabled=false", "feign.hystrix.enabled=false",
|
||||
"localapp.ribbon.MaxAutoRetries=2",
|
||||
"localapp.ribbon.MaxAutoRetriesNextServer=3" })
|
||||
@DirtiesContext
|
||||
public class FeignRibbonClientRetryTests {
|
||||
|
||||
@@ -66,13 +66,32 @@ public class FeignRibbonClientRetryTests {
|
||||
@Autowired
|
||||
private TestClient testClient;
|
||||
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertThat(this.testClient).as("testClient was null").isNotNull();
|
||||
assertThat(Proxy.isProxyClass(this.testClient.getClass()))
|
||||
.as("testClient is not a java Proxy").isTrue();
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient);
|
||||
assertThat(invocationHandler).as("invocationHandler was null").isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetries() {
|
||||
int retryMe = this.testClient.retryMe();
|
||||
assertThat(1).as("retryCount didn't match").isEqualTo(retryMe);
|
||||
// TODO: not sure how to verify retry happens. Debugging through it, it works
|
||||
// maybe the assertEquals above is enough because of the bogus servers
|
||||
}
|
||||
|
||||
@FeignClient("localapp")
|
||||
protected interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/retryme")
|
||||
int retryMe();
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -94,27 +113,11 @@ public class FeignRibbonClientRetryTests {
|
||||
public int retryMe() {
|
||||
return this.retries.getAndIncrement();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertNotNull("testClient was null", this.testClient);
|
||||
assertTrue("testClient is not a java Proxy",
|
||||
Proxy.isProxyClass(this.testClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetries() {
|
||||
int retryMe = this.testClient.retryMe();
|
||||
assertEquals("retryCount didn't match", retryMe, 1);
|
||||
// TODO: not sure how to verify retry happens. Debugging through it, it works
|
||||
// maybe the assertEquals above is enough because of the bogus servers
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
|
||||
private String message;
|
||||
|
||||
public Hello() {
|
||||
@@ -125,13 +128,15 @@ public class FeignRibbonClientRetryTests {
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Load balancer with fixed server list for "local" pointing to localhost
|
||||
@@ -145,8 +150,8 @@ class LocalRibbonClientConfiguration {
|
||||
@Bean
|
||||
public ServerList<Server> ribbonServerList() {
|
||||
return new StaticServerList<>(new Server("mybadhost", 80),
|
||||
new Server("mybadhost2", 10002),
|
||||
new Server("mybadhost3", 10003), new Server("localhost", this.port));
|
||||
new Server("mybadhost2", 10002), new Server("mybadhost3", 10003),
|
||||
new Server("localhost", this.port));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -52,6 +52,7 @@ import static org.mockito.hamcrest.MockitoHamcrest.argThat;
|
||||
public class FeignRibbonClientTests {
|
||||
|
||||
private AbstractLoadBalancer loadBalancer = mock(AbstractLoadBalancer.class);
|
||||
|
||||
private Client delegate = mock(Client.class);
|
||||
|
||||
private SpringClientFactory factory = new SpringClientFactory() {
|
||||
@@ -81,71 +82,58 @@ public class FeignRibbonClientTests {
|
||||
|
||||
// Even though we don't maintain FeignRibbonClient, keep these tests
|
||||
// around to make sure the expected behaviour doesn't break
|
||||
private Client client = new LoadBalancerFeignClient(this.delegate, new CachingSpringLoadBalancerFactory(this.factory), this.factory);
|
||||
private Client client = new LoadBalancerFeignClient(this.delegate,
|
||||
new CachingSpringLoadBalancerFactory(this.factory), this.factory);
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
when(this.loadBalancer.chooseServer(any())).thenReturn(
|
||||
new Server("foo.com", 8000));
|
||||
//to fix NPE
|
||||
when(this.loadBalancer.chooseServer(any()))
|
||||
.thenReturn(new Server("foo.com", 8000));
|
||||
// to fix NPE
|
||||
LoadBalancerStats stats = mock(LoadBalancerStats.class);
|
||||
when(this.loadBalancer.getLoadBalancerStats()).thenReturn(stats);
|
||||
when(stats.getSingleServerStat(any(Server.class))).thenReturn(mock(ServerStats.class));
|
||||
when(stats.getSingleServerStat(any(Server.class)))
|
||||
.thenReturn(mock(ServerStats.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remoteRequestIsSentAtRoot() throws Exception {
|
||||
Request request = new RequestTemplate()
|
||||
.method(GET)
|
||||
.target("http://foo")
|
||||
.resolve(new HashMap<>())
|
||||
.request();
|
||||
Request request = new RequestTemplate().method(GET).target("http://foo")
|
||||
.resolve(new HashMap<>()).request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("http://foo.com:8000/");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
verify(this.delegate).execute(argThat(matcher), any(Options.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remoteRequestIsSent() throws Exception {
|
||||
Request request = new RequestTemplate()
|
||||
.method(GET)
|
||||
.target("http://foo/")
|
||||
.resolve(new HashMap<>())
|
||||
.request();
|
||||
Request request = new RequestTemplate().method(GET).target("http://foo/")
|
||||
.resolve(new HashMap<>()).request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("http://foo.com:8000/");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
verify(this.delegate).execute(argThat(matcher), any(Options.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyCleanUrl() throws Exception {
|
||||
Request request = new RequestTemplate()
|
||||
.method(GET)
|
||||
.target("http://tp/abc/bcd.json")
|
||||
.resolve(new HashMap<>())
|
||||
.request();
|
||||
Request request = new RequestTemplate().method(GET)
|
||||
.target("http://tp/abc/bcd.json").resolve(new HashMap<>()).request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("http://foo.com:8000/abc/bcd.json");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
verify(this.delegate).execute(argThat(matcher), any(Options.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remoteRequestIsSecure() throws Exception {
|
||||
Request request = new RequestTemplate()
|
||||
.method(GET)
|
||||
.target("https://foo/")
|
||||
.resolve(new HashMap<>())
|
||||
.request();
|
||||
Request request = new RequestTemplate().method(GET).target("https://foo/")
|
||||
.resolve(new HashMap<>()).request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("https://foo.com:8000/");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
verify(this.delegate).execute(argThat(matcher), any(Options.class));
|
||||
}
|
||||
|
||||
private final static class RequestMatcher extends CustomMatcher<Request> {
|
||||
|
||||
private String url;
|
||||
|
||||
private RequestMatcher(String url) {
|
||||
@@ -158,6 +146,7 @@ public class FeignRibbonClientTests {
|
||||
Request request = (Request) item;
|
||||
return request.url().equals(this.url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,40 +12,40 @@
|
||||
* 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.openfeign.ribbon;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.net.ssl.SSLContextSpi;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.apache.http.config.Lookup;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.impl.conn.DefaultHttpClientConnectionOperator;
|
||||
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.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.openfeign.ribbon.FeignRibbonClientRetryTests;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = FeignRibbonHttpClientConfigurationTests.FeignRibbonHttpClientConfigurationTestsApplication.class,
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = {"debug=true","feign.httpclient.disableSslValidation=true"})
|
||||
@SpringBootTest(classes = FeignRibbonHttpClientConfigurationTests.FeignRibbonHttpClientConfigurationTestsApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
|
||||
"debug=true", "feign.httpclient.disableSslValidation=true" })
|
||||
@DirtiesContext
|
||||
public class FeignRibbonHttpClientConfigurationTests {
|
||||
|
||||
@@ -54,21 +54,29 @@ public class FeignRibbonHttpClientConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void disableSslTest() throws Exception {
|
||||
Lookup<ConnectionSocketFactory> socketFactoryRegistry = getConnectionSocketFactoryLookup(connectionManager);
|
||||
assertNotNull(socketFactoryRegistry.lookup("https"));
|
||||
assertNull(this.getX509TrustManager(socketFactoryRegistry).getAcceptedIssuers());
|
||||
Lookup<ConnectionSocketFactory> socketFactoryRegistry = getConnectionSocketFactoryLookup(
|
||||
this.connectionManager);
|
||||
assertThat(socketFactoryRegistry.lookup("https")).isNotNull();
|
||||
assertThat(this.getX509TrustManager(socketFactoryRegistry).getAcceptedIssuers())
|
||||
.isNull();
|
||||
}
|
||||
|
||||
private Lookup<ConnectionSocketFactory> getConnectionSocketFactoryLookup(HttpClientConnectionManager connectionManager) {
|
||||
DefaultHttpClientConnectionOperator connectionOperator = (DefaultHttpClientConnectionOperator)this.getField(connectionManager, "connectionOperator");
|
||||
return (Lookup)this.getField(connectionOperator, "socketFactoryRegistry");
|
||||
private Lookup<ConnectionSocketFactory> getConnectionSocketFactoryLookup(
|
||||
HttpClientConnectionManager connectionManager) {
|
||||
DefaultHttpClientConnectionOperator connectionOperator = (DefaultHttpClientConnectionOperator) this
|
||||
.getField(connectionManager, "connectionOperator");
|
||||
return (Lookup) this.getField(connectionOperator, "socketFactoryRegistry");
|
||||
}
|
||||
|
||||
private X509TrustManager getX509TrustManager(Lookup<ConnectionSocketFactory> socketFactoryRegistry) {
|
||||
ConnectionSocketFactory connectionSocketFactory = (ConnectionSocketFactory)socketFactoryRegistry.lookup("https");
|
||||
SSLSocketFactory sslSocketFactory = (SSLSocketFactory)this.getField(connectionSocketFactory, "socketfactory");
|
||||
SSLContextSpi sslContext = (SSLContextSpi)this.getField(sslSocketFactory, "context");
|
||||
return (X509TrustManager)this.getField(sslContext, "trustManager");
|
||||
private X509TrustManager getX509TrustManager(
|
||||
Lookup<ConnectionSocketFactory> socketFactoryRegistry) {
|
||||
ConnectionSocketFactory connectionSocketFactory = (ConnectionSocketFactory) socketFactoryRegistry
|
||||
.lookup("https");
|
||||
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) this
|
||||
.getField(connectionSocketFactory, "socketfactory");
|
||||
SSLContextSpi sslContext = (SSLContextSpi) this.getField(sslSocketFactory,
|
||||
"context");
|
||||
return (X509TrustManager) this.getField(sslContext, "trustManager");
|
||||
}
|
||||
|
||||
protected <T> Object getField(Object target, String name) {
|
||||
@@ -81,9 +89,12 @@ public class FeignRibbonHttpClientConfigurationTests {
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class FeignRibbonHttpClientConfigurationTestsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(FeignRibbonClientRetryTests.Application.class)
|
||||
.run(args);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,36 +12,37 @@
|
||||
* 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.openfeign.ribbon;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import org.junit.Assert;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
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.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
|
||||
import org.springframework.cloud.openfeign.ribbon.FeignRibbonClientRetryTests;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = FeignRibbonOkHttpClientConfigurationTests.FeignRibbonOkHttpClientConfigurationTestsApplication.class,
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = {"debug=true","feign.httpclient.disableSslValidation=true",
|
||||
"feign.okhttp.enabled=true", "feign.httpclient.enabled=false"})
|
||||
@SpringBootTest(classes = FeignRibbonOkHttpClientConfigurationTests.FeignRibbonOkHttpClientConfigurationTestsApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
|
||||
"debug=true", "feign.httpclient.disableSslValidation=true",
|
||||
"feign.okhttp.enabled=true", "feign.httpclient.enabled=false" })
|
||||
@DirtiesContext
|
||||
public class FeignRibbonOkHttpClientConfigurationTests {
|
||||
|
||||
@@ -50,8 +51,11 @@ public class FeignRibbonOkHttpClientConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void disableSslTest() throws Exception {
|
||||
HostnameVerifier hostnameVerifier = (HostnameVerifier)this.getField(httpClient, "hostnameVerifier");
|
||||
Assert.assertTrue(OkHttpClientFactory.TrustAllHostnames.class.isInstance(hostnameVerifier));
|
||||
HostnameVerifier hostnameVerifier = (HostnameVerifier) this
|
||||
.getField(this.httpClient, "hostnameVerifier");
|
||||
assertThat(
|
||||
OkHttpClientFactory.TrustAllHostnames.class.isInstance(hostnameVerifier))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
protected <T> Object getField(Object target, String name) {
|
||||
@@ -64,9 +68,12 @@ public class FeignRibbonOkHttpClientConfigurationTests {
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class FeignRibbonOkHttpClientConfigurationTestsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(FeignRibbonClientRetryTests.Application.class)
|
||||
.run(args);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
package org.springframework.cloud.openfeign.ribbon;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import feign.Request;
|
||||
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.context.SpringBootTest;
|
||||
@@ -33,10 +35,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
|
||||
import feign.Request;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -56,20 +55,20 @@ public class LoadBalancerFeignClientOverrideTests {
|
||||
// specific ribbon 'bar' configuration via spring bean
|
||||
Request.Options barOptions = this.context.getInstance("bar",
|
||||
Request.Options.class);
|
||||
assertEquals(1, barOptions.connectTimeoutMillis());
|
||||
assertEquals(2, barOptions.readTimeoutMillis());
|
||||
assertThat(barOptions.connectTimeoutMillis()).isEqualTo(1);
|
||||
assertThat(barOptions.readTimeoutMillis()).isEqualTo(2);
|
||||
assertOptions(barOptions, "bar", 1, 2);
|
||||
|
||||
// specific ribbon 'foo' configuration via application.yml
|
||||
Request.Options fooOptions = this.context.getInstance("foo",
|
||||
Request.Options.class);
|
||||
assertEquals(LoadBalancerFeignClient.DEFAULT_OPTIONS, fooOptions);
|
||||
assertThat(fooOptions).isEqualTo(LoadBalancerFeignClient.DEFAULT_OPTIONS);
|
||||
assertOptions(fooOptions, "foo", 7, 17);
|
||||
|
||||
// generic ribbon default configuration
|
||||
Request.Options bazOptions = this.context.getInstance("baz",
|
||||
Request.Options.class);
|
||||
assertEquals(LoadBalancerFeignClient.DEFAULT_OPTIONS, bazOptions);
|
||||
assertThat(bazOptions).isEqualTo(LoadBalancerFeignClient.DEFAULT_OPTIONS);
|
||||
assertOptions(bazOptions, "baz", 3001, 60001);
|
||||
}
|
||||
|
||||
@@ -78,44 +77,54 @@ public class LoadBalancerFeignClientOverrideTests {
|
||||
LoadBalancerFeignClient client = this.context.getInstance(name,
|
||||
LoadBalancerFeignClient.class);
|
||||
IClientConfig config = client.getClientConfig(options, name);
|
||||
assertEquals("connect was wrong for " + name, expectedConnect,
|
||||
config.get(CommonClientConfigKey.ConnectTimeout, -1).intValue());
|
||||
assertEquals("read was wrong for " + name, expectedRead,
|
||||
config.get(CommonClientConfigKey.ReadTimeout, -1).intValue());
|
||||
assertThat(config.get(CommonClientConfigKey.ConnectTimeout, -1).intValue())
|
||||
.as("connect was wrong for " + name).isEqualTo(expectedConnect);
|
||||
assertThat(config.get(CommonClientConfigKey.ReadTimeout, -1).intValue())
|
||||
.as("read was wrong for " + name).isEqualTo(expectedRead);
|
||||
}
|
||||
|
||||
@FeignClient(value = "foo", configuration = FooConfiguration.class)
|
||||
interface FooClient {
|
||||
|
||||
@RequestMapping("/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(value = "bar", configuration = BarConfiguration.class)
|
||||
interface BarClient {
|
||||
|
||||
@RequestMapping("/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient("baz")
|
||||
interface BazClient {
|
||||
|
||||
@RequestMapping("/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableFeignClients(clients = { FooClient.class, BarClient.class, BazClient.class })
|
||||
@EnableAutoConfiguration
|
||||
protected static class TestConfiguration {
|
||||
}
|
||||
|
||||
@FeignClient(value = "foo", configuration = FooConfiguration.class)
|
||||
interface FooClient {
|
||||
@RequestMapping("/")
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
public static class FooConfiguration {
|
||||
}
|
||||
|
||||
@FeignClient(value = "bar", configuration = BarConfiguration.class)
|
||||
interface BarClient {
|
||||
@RequestMapping("/")
|
||||
String get();
|
||||
}
|
||||
|
||||
public static class BarConfiguration {
|
||||
|
||||
@Bean
|
||||
public Request.Options feignRequestOptions() {
|
||||
return new Request.Options(1, 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FeignClient("baz")
|
||||
interface BazClient {
|
||||
@RequestMapping("/")
|
||||
String get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,7 +12,6 @@
|
||||
* 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.openfeign.ribbon;
|
||||
@@ -36,7 +35,6 @@ import com.netflix.loadbalancer.Server;
|
||||
import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
@@ -69,10 +67,7 @@ import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_AUTO
|
||||
import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER;
|
||||
import static feign.Request.HttpMethod.GET;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
@@ -90,13 +85,17 @@ import static org.mockito.Mockito.when;
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
public class RetryableFeignLoadBalancerTests {
|
||||
|
||||
@Mock
|
||||
private ILoadBalancer lb;
|
||||
|
||||
@Mock
|
||||
private IClientConfig config;
|
||||
|
||||
private ServerIntrospector inspector = new DefaultServerIntrospector();
|
||||
|
||||
private Integer defaultConnectTimeout = 10000;
|
||||
|
||||
private Integer defaultReadTimeout = 10000;
|
||||
|
||||
@Before
|
||||
@@ -114,31 +113,38 @@ public class RetryableFeignLoadBalancerTests {
|
||||
|
||||
@Test
|
||||
public void executeNoFailure() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404,502,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer),
|
||||
anyInt());
|
||||
doReturn(true).when(config)
|
||||
.get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(this.defaultConnectTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(this.defaultReadTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404,502,foo, ,").when(config).getPropertyAsString(
|
||||
eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory);
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory);
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder()
|
||||
.status(200)
|
||||
.request(feignRequest)
|
||||
.headers(new HashMap<>())
|
||||
.build();
|
||||
doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().status(200).request(feignRequest)
|
||||
.headers(new HashMap<>()).build();
|
||||
doReturn(response).when(client).execute(any(Request.class),
|
||||
any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
config, this.inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
assertThat(ribbonResponse.toResponse().status()).isEqualTo(200);
|
||||
verify(client, times(1)).execute(any(Request.class), any(Request.Options.class));
|
||||
}
|
||||
|
||||
@@ -147,48 +153,62 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
doThrow(new IOException("boom")).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, new LoadBalancedRetryFactory() {
|
||||
@Override
|
||||
public LoadBalancedRetryPolicy createRetryPolicy(String s, ServiceInstanceChooser serviceInstanceChooser) {
|
||||
return null;
|
||||
}
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://foo"));
|
||||
doThrow(new IOException("boom")).when(client).execute(any(Request.class),
|
||||
any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
this.config, this.inspector, new LoadBalancedRetryFactory() {
|
||||
@Override
|
||||
public LoadBalancedRetryPolicy createRetryPolicy(String s,
|
||||
ServiceInstanceChooser serviceInstanceChooser) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[0];
|
||||
}
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
try {
|
||||
feignLb.execute(request, null);
|
||||
} catch(Exception e) {
|
||||
assertThat(e, instanceOf(IOException.class));
|
||||
} finally {
|
||||
verify(client, times(1)).execute(any(Request.class), any(Request.Options.class));
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e).isInstanceOf(IOException.class);
|
||||
}
|
||||
finally {
|
||||
verify(client, times(1)).execute(any(Request.class),
|
||||
any(Request.Options.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executeRetry() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer),
|
||||
anyInt());
|
||||
doReturn(true).when(config)
|
||||
.get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(this.defaultConnectTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(this.defaultReadTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("").when(config).getPropertyAsString(
|
||||
eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory) {
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
@@ -197,36 +217,43 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder()
|
||||
.status(200)
|
||||
.request(feignRequest)
|
||||
.headers(new HashMap<>())
|
||||
.build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().status(200).request(feignRequest)
|
||||
.headers(new HashMap<>()).build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client)
|
||||
.execute(any(Request.class), any(Request.Options.class));
|
||||
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
config, this.inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
assertThat(ribbonResponse.toResponse().status()).isEqualTo(200);
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
assertThat(backOffPolicy.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executeRetryOnStatusCode() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer),
|
||||
anyInt());
|
||||
doReturn(true).when(config)
|
||||
.get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(this.defaultConnectTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(this.defaultReadTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404").when(config).getPropertyAsString(
|
||||
eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory) {
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
@@ -235,168 +262,182 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response
|
||||
.builder()
|
||||
.request(feignRequest)
|
||||
.status(200)
|
||||
.headers(new HashMap<>())
|
||||
.build();
|
||||
Response fourOFourResponse = Response.builder()
|
||||
.request(feignRequest)
|
||||
.status(404)
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().request(feignRequest).status(200)
|
||||
.headers(new HashMap<>()).build();
|
||||
doReturn(fourOFourResponse).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
Response fourOFourResponse = Response.builder().request(feignRequest).status(404)
|
||||
.headers(new HashMap<>()).build();
|
||||
doReturn(fourOFourResponse).doReturn(response).when(client)
|
||||
.execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
config, this.inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
assertThat(ribbonResponse.toResponse().status()).isEqualTo(200);
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
assertThat(backOffPolicy.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void executeRetryOnStatusCodeWithEmptyBody() throws Exception {
|
||||
int retriesNextServer = 0;
|
||||
when(this.config.get(MaxAutoRetriesNextServer,
|
||||
DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER)).thenReturn(retriesNextServer);
|
||||
doReturn(new Server("foo", 80)).when(lb).chooseServer(any());
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(retriesNextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder()
|
||||
.request(feignRequest)
|
||||
.status(404)
|
||||
.headers(new HashMap<>())
|
||||
.build();
|
||||
Response fourOFourResponse = Response.builder()
|
||||
.request(feignRequest)
|
||||
.status(404)
|
||||
.headers(new HashMap<>())
|
||||
.build();
|
||||
doReturn(fourOFourResponse).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(404, ribbonResponse.toResponse().status());
|
||||
assertEquals(Integer.valueOf(0), ribbonResponse.toResponse().body().length());
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
int retriesNextServer = 0;
|
||||
when(this.config.get(MaxAutoRetriesNextServer,
|
||||
DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER)).thenReturn(retriesNextServer);
|
||||
doReturn(new Server("foo", 80)).when(this.lb).chooseServer(any());
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(retriesNextServer).when(config)
|
||||
.get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config)
|
||||
.get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(this.defaultConnectTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(this.defaultReadTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404").when(config).getPropertyAsString(
|
||||
eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory) {
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().request(feignRequest).status(404)
|
||||
.headers(new HashMap<>()).build();
|
||||
Response fourOFourResponse = Response.builder().request(feignRequest).status(404)
|
||||
.headers(new HashMap<>()).build();
|
||||
doReturn(fourOFourResponse).doReturn(response).when(client)
|
||||
.execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
config, this.inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertThat(ribbonResponse.toResponse().status()).isEqualTo(404);
|
||||
assertThat(ribbonResponse.toResponse().body().length())
|
||||
.isEqualTo(Integer.valueOf(0));
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertThat(backOffPolicy.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestSpecificRetryHandler() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory);
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory);
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder()
|
||||
.request(feignRequest)
|
||||
.status(200)
|
||||
.headers(new HashMap<>())
|
||||
.build();
|
||||
doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
RequestSpecificRetryHandler retryHandler = feignLb.getRequestSpecificRetryHandler(request, config);
|
||||
assertEquals(1, retryHandler.getMaxRetriesOnNextServer());
|
||||
assertEquals(1, retryHandler.getMaxRetriesOnSameServer());
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().request(feignRequest).status(200)
|
||||
.headers(new HashMap<>()).build();
|
||||
doReturn(response).when(client).execute(any(Request.class),
|
||||
any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
this.config, this.inspector, loadBalancedRetryFactory);
|
||||
RequestSpecificRetryHandler retryHandler = feignLb
|
||||
.getRequestSpecificRetryHandler(request, this.config);
|
||||
assertThat(retryHandler.getMaxRetriesOnNextServer()).isEqualTo(1);
|
||||
assertThat(retryHandler.getMaxRetriesOnSameServer()).isEqualTo(1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void choose() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory);
|
||||
Request feignRequest = Request
|
||||
.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory);
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder()
|
||||
.request(feignRequest)
|
||||
.status(200).headers(new HashMap<>())
|
||||
.build();
|
||||
doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().request(feignRequest).status(200)
|
||||
.headers(new HashMap<>()).build();
|
||||
doReturn(response).when(client).execute(any(Request.class),
|
||||
any(Request.Options.class));
|
||||
final Server server = new Server("foo", 80);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(new ILoadBalancer() {
|
||||
@Override
|
||||
public void addServers(List<Server> list) {
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(
|
||||
new ILoadBalancer() {
|
||||
@Override
|
||||
public void addServers(List<Server> list) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Server chooseServer(Object o) {
|
||||
return server;
|
||||
}
|
||||
@Override
|
||||
public Server chooseServer(Object o) {
|
||||
return server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markServerDown(Server server) {
|
||||
@Override
|
||||
public void markServerDown(Server server) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getServerList(boolean b) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public List<Server> getServerList(boolean b) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getReachableServers() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public List<Server> getReachableServers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getAllServers() {
|
||||
return null;
|
||||
}
|
||||
}, config, inspector, loadBalancedRetryFactory);
|
||||
@Override
|
||||
public List<Server> getAllServers() {
|
||||
return null;
|
||||
}
|
||||
}, this.config, this.inspector, loadBalancedRetryFactory);
|
||||
ServiceInstance serviceInstance = feignLb.choose("foo");
|
||||
assertEquals("foo", serviceInstance.getHost());
|
||||
assertEquals(80, serviceInstance.getPort());
|
||||
assertThat(serviceInstance.getHost()).isEqualTo("foo");
|
||||
assertThat(serviceInstance.getPort()).isEqualTo(80);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryListenerTest() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer),
|
||||
anyInt());
|
||||
doReturn(true).when(config)
|
||||
.get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(this.defaultConnectTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(this.defaultReadTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("").when(config).getPropertyAsString(
|
||||
eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
MyRetryListener myRetryListener = new MyRetryListener();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory) {
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory) {
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[]{myRetryListener};
|
||||
return new RetryListener[] { myRetryListener };
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -407,41 +448,48 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Request feignRequest = Request.create(GET, "http://listener", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener"));
|
||||
Response response = Response.builder()
|
||||
.request(feignRequest)
|
||||
.status(200)
|
||||
.headers(new HashMap<>())
|
||||
.build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://listener"));
|
||||
Response response = Response.builder().request(feignRequest).status(200)
|
||||
.headers(new HashMap<>()).build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client)
|
||||
.execute(any(Request.class), any(Request.Options.class));
|
||||
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
config, this.inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
assertThat(ribbonResponse.toResponse().status()).isEqualTo(200);
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
assertEquals(1, myRetryListener.getOnError());
|
||||
assertThat(backOffPolicy.getCount()).isEqualTo(1);
|
||||
assertThat(myRetryListener.getOnError()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test(expected = TerminatedRetryException.class)
|
||||
public void retryListenerTestNoRetry() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer),
|
||||
anyInt());
|
||||
doReturn(true).when(config)
|
||||
.get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(this.defaultConnectTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(this.defaultReadTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("").when(config).getPropertyAsString(
|
||||
eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
MyRetryListenerNotRetry myRetryListenerNotRetry = new MyRetryListenerNotRetry();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory) {
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[]{myRetryListenerNotRetry};
|
||||
return new RetryListener[] { myRetryListenerNotRetry };
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -452,26 +500,35 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Request feignRequest = Request.create(GET, "http://listener", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener"));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://listener"));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
config, this.inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryWithDefaultConstructorTest() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer),
|
||||
anyInt());
|
||||
doReturn(true).when(config)
|
||||
.get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(this.defaultConnectTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(this.defaultReadTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("").when(config).getPropertyAsString(
|
||||
eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory) {
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
@@ -480,36 +537,43 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Request feignRequest = Request.create(GET, "http://listener", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener"));
|
||||
Response response = Response.builder()
|
||||
.request(feignRequest)
|
||||
.status(200)
|
||||
.headers(new HashMap<>())
|
||||
.build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://listener"));
|
||||
Response response = Response.builder().request(feignRequest).status(200)
|
||||
.headers(new HashMap<>()).build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client)
|
||||
.execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
config, this.inspector, loadBalancedRetryPolicyFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
assertThat(ribbonResponse.toResponse().status()).isEqualTo(200);
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
assertThat(backOffPolicy.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executeRetryFail() throws Exception {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(this.lb,
|
||||
this.config);
|
||||
lbContext.setRetryHandler(new DefaultLoadBalancerRetryHandler(1, 0, true));
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(0).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(0).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer),
|
||||
anyInt());
|
||||
doReturn(true).when(config)
|
||||
.get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(this.defaultConnectTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(this.defaultReadTimeout).when(config)
|
||||
.get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404").when(config).getPropertyAsString(
|
||||
eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(
|
||||
clientFactory) {
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
@@ -518,12 +582,11 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Request feignRequest = Request.create(GET, "http://foo", new HashMap<>(),
|
||||
new byte[] {}, UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response fourOFourResponse = Response.builder()
|
||||
.request(feignRequest)
|
||||
.status(404)
|
||||
.headers(new HashMap<>())
|
||||
.body(new Response.Body() { //set content into response
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(
|
||||
client, feignRequest, new URI("http://foo"));
|
||||
Response fourOFourResponse = Response.builder().request(feignRequest).status(404)
|
||||
.headers(new HashMap<>()).body(new Response.Body() { // set content into
|
||||
// response
|
||||
@Override
|
||||
public Integer length() {
|
||||
return "test".getBytes().length;
|
||||
@@ -553,15 +616,17 @@ public class RetryableFeignLoadBalancerTests {
|
||||
public void close() throws IOException {
|
||||
}
|
||||
}).build();
|
||||
doReturn(fourOFourResponse).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
doReturn(fourOFourResponse).when(client).execute(any(Request.class),
|
||||
any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(this.lb,
|
||||
config, this.inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
assertThat(backOffPolicy.getCount()).isEqualTo(1);
|
||||
InputStream inputStream = ribbonResponse.toResponse().body().asInputStream();
|
||||
byte[] buf = new byte[100];
|
||||
int read = inputStream.read(buf);
|
||||
Assert.assertThat(new String(buf, 0, read), is("test"));
|
||||
assertThat(new String(buf, 0, read)).isEqualTo("test");
|
||||
}
|
||||
|
||||
class MyBackOffPolicy implements BackOffPolicy {
|
||||
@@ -574,12 +639,13 @@ public class RetryableFeignLoadBalancerTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void backOff(BackOffContext backOffContext) throws BackOffInterruptedException {
|
||||
count++;
|
||||
public void backOff(BackOffContext backOffContext)
|
||||
throws BackOffInterruptedException {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
return this.count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -589,39 +655,48 @@ public class RetryableFeignLoadBalancerTests {
|
||||
private int onError = 0;
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
|
||||
public <T, E extends Throwable> boolean open(RetryContext context,
|
||||
RetryCallback<T, E> callback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
public <T, E extends Throwable> void close(RetryContext context,
|
||||
RetryCallback<T, E> callback, Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
onError++;
|
||||
public <T, E extends Throwable> void onError(RetryContext context,
|
||||
RetryCallback<T, E> callback, Throwable throwable) {
|
||||
this.onError++;
|
||||
}
|
||||
|
||||
public int getOnError() {
|
||||
return onError;
|
||||
return this.onError;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MyRetryListenerNotRetry implements RetryListener {
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
|
||||
public <T, E extends Throwable> boolean open(RetryContext context,
|
||||
RetryCallback<T, E> callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
public <T, E extends Throwable> void close(RetryContext context,
|
||||
RetryCallback<T, E> callback, Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {}
|
||||
public <T, E extends Throwable> void onError(RetryContext context,
|
||||
RetryCallback<T, E> callback, Throwable throwable) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.openfeign.ribbon;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -33,7 +34,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static feign.Request.HttpMethod.GET;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
@@ -48,15 +49,19 @@ public class RibbonResponseStatusCodeExceptionTest {
|
||||
fooValues.add("bar");
|
||||
headers.put("foo", fooValues);
|
||||
Request request = Request.create(GET, "http://service.com",
|
||||
new HashMap<String, Collection<String>>(), new byte[]{}, Charset.defaultCharset());
|
||||
new HashMap<String, Collection<String>>(), new byte[] {},
|
||||
Charset.defaultCharset());
|
||||
byte[] body = "foo".getBytes();
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(body);
|
||||
Response response = Response.builder().status(200).reason("Success").request(request).body(is, body.length).headers(headers).build();
|
||||
RibbonResponseStatusCodeException ex = new RibbonResponseStatusCodeException("service", response, body,
|
||||
new URI(request.url()));
|
||||
assertEquals(200, ex.getResponse().status());
|
||||
assertEquals(request, ex.getResponse().request());
|
||||
assertEquals("Success", ex.getResponse().reason());
|
||||
assertEquals("foo", StreamUtils.copyToString(ex.getResponse().body().asInputStream(), Charset.defaultCharset()));
|
||||
Response response = Response.builder().status(200).reason("Success")
|
||||
.request(request).body(is, body.length).headers(headers).build();
|
||||
RibbonResponseStatusCodeException ex = new RibbonResponseStatusCodeException(
|
||||
"service", response, body, new URI(request.url()));
|
||||
assertThat(ex.getResponse().status()).isEqualTo(200);
|
||||
assertThat(ex.getResponse().request()).isEqualTo(request);
|
||||
assertThat(ex.getResponse().reason()).isEqualTo("Success");
|
||||
assertThat(StreamUtils.copyToString(ex.getResponse().body().asInputStream(),
|
||||
Charset.defaultCharset())).isEqualTo("foo");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* * 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.
|
||||
* 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.openfeign.support;
|
||||
@@ -21,6 +19,7 @@ package org.springframework.cloud.openfeign.support;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
@@ -30,9 +29,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
@@ -53,12 +50,18 @@ public class FeignHttpClientPropertiesTests {
|
||||
@Test
|
||||
public void testDefaults() {
|
||||
setupContext();
|
||||
assertEquals(FeignHttpClientProperties.DEFAULT_CONNECTION_TIMEOUT, getProperties().getConnectionTimeout());
|
||||
assertEquals(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS, getProperties().getMaxConnections());
|
||||
assertEquals(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS_PER_ROUTE, getProperties().getMaxConnectionsPerRoute());
|
||||
assertEquals(FeignHttpClientProperties.DEFAULT_TIME_TO_LIVE, getProperties().getTimeToLive());
|
||||
assertEquals(FeignHttpClientProperties.DEFAULT_DISABLE_SSL_VALIDATION, getProperties().isDisableSslValidation());
|
||||
assertEquals(FeignHttpClientProperties.DEFAULT_FOLLOW_REDIRECTS, getProperties().isFollowRedirects());
|
||||
assertThat(getProperties().getConnectionTimeout())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_CONNECTION_TIMEOUT);
|
||||
assertThat(getProperties().getMaxConnections())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS);
|
||||
assertThat(getProperties().getMaxConnectionsPerRoute())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
|
||||
assertThat(getProperties().getTimeToLive())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_TIME_TO_LIVE);
|
||||
assertThat(getProperties().isDisableSslValidation())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_DISABLE_SSL_VALIDATION);
|
||||
assertThat(getProperties().isFollowRedirects())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_FOLLOW_REDIRECTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -70,16 +73,17 @@ public class FeignHttpClientPropertiesTests {
|
||||
"feign.httpclient.disableSslValidation=true",
|
||||
"feign.httpclient.followRedirects=false").applyTo(this.context);
|
||||
setupContext();
|
||||
assertEquals(2, getProperties().getMaxConnections());
|
||||
assertEquals(2, getProperties().getConnectionTimeout());
|
||||
assertEquals(2, getProperties().getMaxConnectionsPerRoute());
|
||||
assertEquals(2L, getProperties().getTimeToLive());
|
||||
assertTrue(getProperties().isDisableSslValidation());
|
||||
assertFalse(getProperties().isFollowRedirects());
|
||||
assertThat(getProperties().getMaxConnections()).isEqualTo(2);
|
||||
assertThat(getProperties().getConnectionTimeout()).isEqualTo(2);
|
||||
assertThat(getProperties().getMaxConnectionsPerRoute()).isEqualTo(2);
|
||||
assertThat(getProperties().getTimeToLive()).isEqualTo(2L);
|
||||
assertThat(getProperties().isDisableSslValidation()).isTrue();
|
||||
assertThat(getProperties().isFollowRedirects()).isFalse();
|
||||
}
|
||||
|
||||
private void setupContext() {
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@@ -90,9 +94,12 @@ public class FeignHttpClientPropertiesTests {
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
FeignHttpClientProperties zuulProperties() {
|
||||
return new FeignHttpClientProperties() ;
|
||||
return new FeignHttpClientProperties();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,7 +12,6 @@
|
||||
* 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.openfeign.support;
|
||||
@@ -50,12 +49,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.http.HttpHeaders.ACCEPT;
|
||||
import static org.springframework.http.HttpHeaders.CONTENT_LENGTH;
|
||||
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
|
||||
@@ -82,110 +76,93 @@ public class SpringEncoderTests {
|
||||
@Test
|
||||
public void testCustomHttpMessageConverter() {
|
||||
SpringEncoder encoder = this.context.getInstance("foo", SpringEncoder.class);
|
||||
assertThat(encoder, is(notNullValue()));
|
||||
assertThat(encoder).isNotNull();
|
||||
RequestTemplate request = new RequestTemplate();
|
||||
|
||||
encoder.encode("hi", MyType.class, request);
|
||||
|
||||
Collection<String> contentTypeHeader = request.headers().get("Content-Type");
|
||||
assertThat("missing content type header", contentTypeHeader, is(notNullValue()));
|
||||
assertThat("missing content type header", contentTypeHeader.isEmpty(), is(false));
|
||||
assertThat(contentTypeHeader).as("missing content type header").isNotNull();
|
||||
assertThat(contentTypeHeader.isEmpty()).as("missing content type header")
|
||||
.isFalse();
|
||||
|
||||
String header = contentTypeHeader.iterator().next();
|
||||
assertThat("content type header is wrong", header, is("application/mytype"));
|
||||
|
||||
assertThat("request charset is null", request.requestCharset(), is(notNullValue()));
|
||||
assertThat("request charset is wrong", request.requestCharset(), is(Charset.forName("UTF-8")));
|
||||
assertThat(header).as("content type header is wrong")
|
||||
.isEqualTo("application/mytype");
|
||||
|
||||
assertThat(request.requestCharset()).as("request charset is null").isNotNull();
|
||||
assertThat(request.requestCharset()).as("request charset is wrong")
|
||||
.isEqualTo(Charset.forName("UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBinaryData() {
|
||||
SpringEncoder encoder = this.context.getInstance("foo", SpringEncoder.class);
|
||||
assertThat(encoder, is(notNullValue()));
|
||||
assertThat(encoder).isNotNull();
|
||||
RequestTemplate request = new RequestTemplate();
|
||||
|
||||
encoder.encode("hi".getBytes(), null, request);
|
||||
|
||||
assertThat("Request Content-Type is not octet-stream",
|
||||
((List) request.headers().get(CONTENT_TYPE)).get(0),
|
||||
equalTo(APPLICATION_OCTET_STREAM_VALUE));
|
||||
assertThat(((List) request.headers().get(CONTENT_TYPE)).get(0))
|
||||
.as("Request Content-Type is not octet-stream")
|
||||
.isEqualTo(APPLICATION_OCTET_STREAM_VALUE);
|
||||
}
|
||||
|
||||
@Test(expected = EncodeException.class)
|
||||
public void testMultipartFile1() {
|
||||
SpringEncoder encoder = this.context.getInstance("foo", SpringEncoder.class);
|
||||
assertThat(encoder, is(notNullValue()));
|
||||
assertThat(encoder).isNotNull();
|
||||
RequestTemplate request = new RequestTemplate();
|
||||
|
||||
MultipartFile multipartFile = new MockMultipartFile("test_multipart_file", "hi".getBytes());
|
||||
MultipartFile multipartFile = new MockMultipartFile("test_multipart_file",
|
||||
"hi".getBytes());
|
||||
encoder.encode(multipartFile, MultipartFile.class, request);
|
||||
|
||||
assertThat("request charset is not null", request.requestCharset(), is(nullValue()));
|
||||
assertThat(request.requestCharset()).as("request charset is not null").isNull();
|
||||
}
|
||||
|
||||
// gh-105, gh-107
|
||||
@Test
|
||||
public void testMultipartFile2() {
|
||||
SpringEncoder encoder = this.context.getInstance("foo", SpringEncoder.class);
|
||||
assertThat(encoder, is(notNullValue()));
|
||||
assertThat(encoder).isNotNull();
|
||||
RequestTemplate request = new RequestTemplate();
|
||||
request.header(ACCEPT, MediaType.MULTIPART_FORM_DATA_VALUE);
|
||||
request.header(CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE);
|
||||
|
||||
MultipartFile multipartFile = new MockMultipartFile("test_multipart_file", "hi".getBytes());
|
||||
MultipartFile multipartFile = new MockMultipartFile("test_multipart_file",
|
||||
"hi".getBytes());
|
||||
encoder.encode(multipartFile, MultipartFile.class, request);
|
||||
|
||||
assertThat("Request Content-Type is not multipart/form-data",
|
||||
(String) ((List) request.headers().get(CONTENT_TYPE)).get(0),
|
||||
containsString("multipart/form-data; charset=UTF-8; boundary="));
|
||||
assertThat("There is more than one Content-Type request header",
|
||||
request.headers().get(CONTENT_TYPE).size(), equalTo(1));
|
||||
assertThat("Request Accept header is not multipart/form-data",
|
||||
((List) request.headers().get(ACCEPT)).get(0),
|
||||
equalTo(MULTIPART_FORM_DATA_VALUE));
|
||||
assertThat("Request Content-Length is not equal to 186",
|
||||
((List) request.headers().get(CONTENT_LENGTH)).get(0),
|
||||
equalTo("186"));
|
||||
assertThat("Body content cannot be decoded",
|
||||
new String(request.requestBody().asBytes()),
|
||||
containsString("hi"));
|
||||
assertThat((String) ((List) request.headers().get(CONTENT_TYPE)).get(0))
|
||||
.as("Request Content-Type is not multipart/form-data")
|
||||
.contains("multipart/form-data; charset=UTF-8; boundary=");
|
||||
assertThat(request.headers().get(CONTENT_TYPE).size())
|
||||
.as("There is more than one Content-Type request header").isEqualTo(1);
|
||||
assertThat(((List) request.headers().get(ACCEPT)).get(0))
|
||||
.as("Request Accept header is not multipart/form-data")
|
||||
.isEqualTo(MULTIPART_FORM_DATA_VALUE);
|
||||
assertThat(((List) request.headers().get(CONTENT_LENGTH)).get(0))
|
||||
.as("Request Content-Length is not equal to 186").isEqualTo("186");
|
||||
assertThat(new String(request.requestBody().asBytes()))
|
||||
.as("Body content cannot be decoded").contains("hi");
|
||||
}
|
||||
|
||||
class MediaTypeMatcher implements ArgumentMatcher<MediaType> {
|
||||
|
||||
private MediaType mediaType;
|
||||
protected interface TestClient {
|
||||
|
||||
public MediaTypeMatcher(String type, String subtype) {
|
||||
this.mediaType = new MediaType(type, subtype);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(MediaType argument) {
|
||||
return this.mediaType.equals(argument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("MediaTypeMatcher{");
|
||||
sb.append("mediaType=").append(this.mediaType);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
protected static class MyType {
|
||||
|
||||
private String value;
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected interface TestClient {
|
||||
|
||||
}
|
||||
|
||||
@@ -202,7 +179,7 @@ public class SpringEncoderTests {
|
||||
private static class MyHttpMessageConverter
|
||||
extends AbstractGenericHttpMessageConverter<Object> {
|
||||
|
||||
public MyHttpMessageConverter() {
|
||||
MyHttpMessageConverter() {
|
||||
super(new MediaType("application", "mytype"));
|
||||
}
|
||||
|
||||
@@ -240,7 +217,32 @@ public class SpringEncoderTests {
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MediaTypeMatcher implements ArgumentMatcher<MediaType> {
|
||||
|
||||
private MediaType mediaType;
|
||||
|
||||
MediaTypeMatcher(String type, String subtype) {
|
||||
this.mediaType = new MediaType(type, subtype);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(MediaType argument) {
|
||||
return this.mediaType.equals(argument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("MediaTypeMatcher{");
|
||||
sb.append("mediaType=").append(this.mediaType);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -53,10 +53,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
|
||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.springframework.web.util.UriUtils.encode;
|
||||
|
||||
@@ -66,6 +66,7 @@ import static org.springframework.web.util.UriUtils.encode;
|
||||
* @author Aram Peres
|
||||
*/
|
||||
public class SpringMvcContractTests {
|
||||
|
||||
private static final Class<?> EXECUTABLE_TYPE;
|
||||
|
||||
static {
|
||||
@@ -81,364 +82,11 @@ public class SpringMvcContractTests {
|
||||
|
||||
private SpringMvcContract contract;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
FormattingConversionServiceFactoryBean conversionServiceFactoryBean
|
||||
= new FormattingConversionServiceFactoryBean();
|
||||
conversionServiceFactoryBean.afterPropertiesSet();
|
||||
ConversionService conversionService = conversionServiceFactoryBean.getObject();
|
||||
|
||||
this.contract = new SpringMvcContract(Collections.emptyList(), conversionService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotationOnMethod_Simple() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/test/{id}", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Simple() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/test/{id}", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
|
||||
assertEquals("id", data.indexToName().get(0).iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_SimpleGetMapping() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("getMappingTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/test/{id}", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
|
||||
assertEquals("id", data.indexToName().get(0).iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Class_AnnotationsGetSpecificTest()
|
||||
throws Exception {
|
||||
Method method = TestTemplate_Class_Annotations.class
|
||||
.getDeclaredMethod("getSpecificTest", String.class, String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/prepend/{classId}/test/{testId}", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
|
||||
assertEquals("classId", data.indexToName().get(0).iterator().next());
|
||||
assertEquals("testId", data.indexToName().get(1).iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Class_AnnotationsGetAllTests() throws Exception {
|
||||
Method method = TestTemplate_Class_Annotations.class
|
||||
.getDeclaredMethod("getAllTests", String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/prepend/{classId}", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
|
||||
assertEquals("classId", data.indexToName().get(0).iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_ExtendedInterface() throws Exception {
|
||||
Method extendedMethod = TestTemplate_Extended.class.getMethod("getAllTests",
|
||||
String.class);
|
||||
MethodMetadata extendedData = this.contract.parseAndValidateMetadata(
|
||||
extendedMethod.getDeclaringClass(), extendedMethod);
|
||||
|
||||
Method method = TestTemplate_Class_Annotations.class
|
||||
.getDeclaredMethod("getAllTests", String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals(extendedData.template().url(), data.template().url());
|
||||
assertEquals(extendedData.template().method(), data.template().method());
|
||||
|
||||
assertEquals(data.indexToName().get(0).iterator().next(),
|
||||
data.indexToName().get(0).iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_SimplePost() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("postTest",
|
||||
TestObject.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/", data.template().url());
|
||||
assertEquals("POST", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_SimplePostMapping() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("postMappingTest",
|
||||
TestObject.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/", data.template().url());
|
||||
assertEquals("POST", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotationsOnMethod_Advanced() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest",
|
||||
String.class, String.class, Integer.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/advanced/test/{id}?amount=" + encode("{amount}", UTF_8),
|
||||
data.template().url());
|
||||
assertEquals("PUT", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotationsOnMethod_Advanced_UnknownAnnotation()
|
||||
throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest",
|
||||
String.class, String.class, Integer.class);
|
||||
this.contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
// Don't throw an exception and this passes
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Advanced() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest",
|
||||
String.class, String.class, Integer.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/advanced/test/{id}?amount=" + encode("{amount}", UTF_8),
|
||||
data.template().url());
|
||||
assertEquals("PUT", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
|
||||
assertEquals("Authorization", data.indexToName().get(0).iterator().next());
|
||||
assertEquals("id", data.indexToName().get(1).iterator().next());
|
||||
assertEquals("amount", data.indexToName().get(2).iterator().next());
|
||||
assertNotNull(data.indexToExpander().get(2));
|
||||
|
||||
assertEquals("{Authorization}",
|
||||
data.template().headers().get("Authorization").iterator().next());
|
||||
assertEquals("{amount}",
|
||||
data.template().queries().get("amount").iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Aliased() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest2",
|
||||
String.class, Integer.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/advanced/test2?amount=" + encode("{amount}", UTF_8),
|
||||
data.template().url());
|
||||
assertEquals("PUT", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
|
||||
assertEquals("Authorization", data.indexToName().get(0).iterator().next());
|
||||
assertEquals("amount", data.indexToName().get(1).iterator().next());
|
||||
|
||||
assertEquals("{Authorization}",
|
||||
data.template().headers().get("Authorization").iterator().next());
|
||||
assertEquals("{amount}",
|
||||
data.template().queries().get("amount").iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_DateTimeFormatParam() throws Exception {
|
||||
Method method = TestTemplate_DateTimeFormatParameter.class.getDeclaredMethod(
|
||||
"getTest", LocalDateTime.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
Param.Expander expander = data.indexToExpander().get(0);
|
||||
assertNotNull(expander);
|
||||
|
||||
LocalDateTime input = LocalDateTime.of(2001, 10, 12, 23, 56, 3);
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
|
||||
TestTemplate_DateTimeFormatParameter.CUSTOM_PATTERN);
|
||||
|
||||
String expected = formatter.format(input);
|
||||
|
||||
assertEquals(expected, expander.expand(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_NumberFormatParam() throws Exception {
|
||||
Method method = TestTemplate_NumberFormatParameter.class.getDeclaredMethod(
|
||||
"getTest", BigDecimal.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
Param.Expander expander = data.indexToExpander().get(0);
|
||||
assertNotNull(expander);
|
||||
|
||||
NumberStyleFormatter formatter = new NumberStyleFormatter(
|
||||
TestTemplate_NumberFormatParameter.CUSTOM_PATTERN);
|
||||
|
||||
BigDecimal input = BigDecimal.valueOf(1220.345);
|
||||
|
||||
String expected = formatter.print(input, Locale.getDefault());
|
||||
String actual = expander.expand(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Advanced2() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest");
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/advanced", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Advanced3() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest");
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_ListParams() throws Exception {
|
||||
Method method = TestTemplate_ListParams.class.getDeclaredMethod("getTest",
|
||||
List.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/test?id=" + encode("{id}", UTF_8),
|
||||
data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals("[{id}]", data.template().queries().get("id").toString());
|
||||
assertNotNull(data.indexToExpander().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_ListParamsWithoutName() throws Exception {
|
||||
Method method = TestTemplate_ListParamsWithoutName.class.getDeclaredMethod("getTest",
|
||||
List.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/test?id=" + encode("{id}", UTF_8), data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals("[{id}]", data.template().queries().get("id").toString());
|
||||
assertNotNull(data.indexToExpander().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_MapParams() throws Exception {
|
||||
Method method = TestTemplate_MapParams.class.getDeclaredMethod("getTest",
|
||||
Map.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/test", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertNotNull(data.queryMapIndex());
|
||||
assertEquals(0, data.queryMapIndex().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessHeaders() throws Exception {
|
||||
Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/test/{id}", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals("bar", data.template().headers().get("X-Foo").iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessHeadersWithoutValues() throws Exception {
|
||||
Method method = TestTemplate_HeadersWithoutValues.class.getDeclaredMethod("getTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/test/{id}", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertTrue(data.template().headers().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Fallback() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTestFallback",
|
||||
String.class, String.class, Integer.class);
|
||||
|
||||
assumeTrue("does not have java 8 parameter names", hasJava8ParameterNames(method));
|
||||
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/advanced/testfallback/{id}?amount=" + encode("{amount}", UTF_8), data
|
||||
.template().url());
|
||||
assertEquals("PUT", data.template().method());
|
||||
assertEquals(MediaType.APPLICATION_JSON_VALUE,
|
||||
data.template().headers().get("Accept").iterator().next());
|
||||
|
||||
assertEquals("Authorization", data.indexToName().get(0).iterator().next());
|
||||
assertEquals("id", data.indexToName().get(1).iterator().next());
|
||||
assertEquals("amount", data.indexToName().get(2).iterator().next());
|
||||
|
||||
assertEquals("{Authorization}",
|
||||
data.template().headers().get("Authorization").iterator().next());
|
||||
assertEquals("{amount}",
|
||||
data.template().queries().get("amount").iterator().next());
|
||||
}
|
||||
|
||||
/**
|
||||
* For abstract (e.g. interface) methods, only Java 8 Parameter names (compiler arg
|
||||
* -parameters) can supply parameter names; bytecode-based strategies use local
|
||||
* variable declarations, of which there are none for abstract methods.
|
||||
* @param m
|
||||
* @param m method
|
||||
* @return whether a parameter name was found
|
||||
* @throws IllegalArgumentException if method has no parameters
|
||||
*/
|
||||
@@ -461,6 +109,362 @@ public class SpringMvcContractTests {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
FormattingConversionServiceFactoryBean conversionServiceFactoryBean = new FormattingConversionServiceFactoryBean();
|
||||
conversionServiceFactoryBean.afterPropertiesSet();
|
||||
ConversionService conversionService = conversionServiceFactoryBean.getObject();
|
||||
|
||||
this.contract = new SpringMvcContract(Collections.emptyList(), conversionService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotationOnMethod_Simple() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Simple() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_SimpleGetMapping() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("getMappingTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Class_AnnotationsGetSpecificTest()
|
||||
throws Exception {
|
||||
Method method = TestTemplate_Class_Annotations.class
|
||||
.getDeclaredMethod("getSpecificTest", String.class, String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/prepend/{classId}/test/{testId}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("classId");
|
||||
assertThat(data.indexToName().get(1).iterator().next()).isEqualTo("testId");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Class_AnnotationsGetAllTests() throws Exception {
|
||||
Method method = TestTemplate_Class_Annotations.class
|
||||
.getDeclaredMethod("getAllTests", String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/prepend/{classId}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("classId");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_ExtendedInterface() throws Exception {
|
||||
Method extendedMethod = TestTemplate_Extended.class.getMethod("getAllTests",
|
||||
String.class);
|
||||
MethodMetadata extendedData = this.contract.parseAndValidateMetadata(
|
||||
extendedMethod.getDeclaringClass(), extendedMethod);
|
||||
|
||||
Method method = TestTemplate_Class_Annotations.class
|
||||
.getDeclaredMethod("getAllTests", String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo(extendedData.template().url());
|
||||
assertThat(data.template().method()).isEqualTo(extendedData.template().method());
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next())
|
||||
.isEqualTo(data.indexToName().get(0).iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_SimplePost() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("postTest",
|
||||
TestObject.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/");
|
||||
assertThat(data.template().method()).isEqualTo("POST");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_SimplePostMapping() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("postMappingTest",
|
||||
TestObject.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/");
|
||||
assertThat(data.template().method()).isEqualTo("POST");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotationsOnMethod_Advanced() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest",
|
||||
String.class, String.class, Integer.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url())
|
||||
.isEqualTo("/advanced/test/{id}?amount=" + encode("{amount}", UTF_8));
|
||||
assertThat(data.template().method()).isEqualTo("PUT");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotationsOnMethod_Advanced_UnknownAnnotation()
|
||||
throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest",
|
||||
String.class, String.class, Integer.class);
|
||||
this.contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
// Don't throw an exception and this passes
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Advanced() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest",
|
||||
String.class, String.class, Integer.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url())
|
||||
.isEqualTo("/advanced/test/{id}?amount=" + encode("{amount}", UTF_8));
|
||||
assertThat(data.template().method()).isEqualTo("PUT");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next())
|
||||
.isEqualTo("Authorization");
|
||||
assertThat(data.indexToName().get(1).iterator().next()).isEqualTo("id");
|
||||
assertThat(data.indexToName().get(2).iterator().next()).isEqualTo("amount");
|
||||
assertThat(data.indexToExpander().get(2)).isNotNull();
|
||||
|
||||
assertThat(data.template().headers().get("Authorization").iterator().next())
|
||||
.isEqualTo("{Authorization}");
|
||||
assertThat(data.template().queries().get("amount").iterator().next())
|
||||
.isEqualTo("{amount}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Aliased() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest2",
|
||||
String.class, Integer.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url())
|
||||
.isEqualTo("/advanced/test2?amount=" + encode("{amount}", UTF_8));
|
||||
assertThat(data.template().method()).isEqualTo("PUT");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next())
|
||||
.isEqualTo("Authorization");
|
||||
assertThat(data.indexToName().get(1).iterator().next()).isEqualTo("amount");
|
||||
|
||||
assertThat(data.template().headers().get("Authorization").iterator().next())
|
||||
.isEqualTo("{Authorization}");
|
||||
assertThat(data.template().queries().get("amount").iterator().next())
|
||||
.isEqualTo("{amount}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_DateTimeFormatParam() throws Exception {
|
||||
Method method = TestTemplate_DateTimeFormatParameter.class
|
||||
.getDeclaredMethod("getTest", LocalDateTime.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
Param.Expander expander = data.indexToExpander().get(0);
|
||||
assertThat(expander).isNotNull();
|
||||
|
||||
LocalDateTime input = LocalDateTime.of(2001, 10, 12, 23, 56, 3);
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter
|
||||
.ofPattern(TestTemplate_DateTimeFormatParameter.CUSTOM_PATTERN);
|
||||
|
||||
String expected = formatter.format(input);
|
||||
|
||||
assertThat(expander.expand(input)).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_NumberFormatParam() throws Exception {
|
||||
Method method = TestTemplate_NumberFormatParameter.class
|
||||
.getDeclaredMethod("getTest", BigDecimal.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
Param.Expander expander = data.indexToExpander().get(0);
|
||||
assertThat(expander).isNotNull();
|
||||
|
||||
NumberStyleFormatter formatter = new NumberStyleFormatter(
|
||||
TestTemplate_NumberFormatParameter.CUSTOM_PATTERN);
|
||||
|
||||
BigDecimal input = BigDecimal.valueOf(1220.345);
|
||||
|
||||
String expected = formatter.print(input, Locale.getDefault());
|
||||
String actual = expander.expand(input);
|
||||
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Advanced2() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest");
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/advanced");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Advanced3() throws Exception {
|
||||
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest");
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_ListParams() throws Exception {
|
||||
Method method = TestTemplate_ListParams.class.getDeclaredMethod("getTest",
|
||||
List.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test?id=" + encode("{id}", UTF_8));
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().queries().get("id").toString()).isEqualTo("[{id}]");
|
||||
assertThat(data.indexToExpander().get(0)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_ListParamsWithoutName() throws Exception {
|
||||
Method method = TestTemplate_ListParamsWithoutName.class
|
||||
.getDeclaredMethod("getTest", List.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test?id=" + encode("{id}", UTF_8));
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().queries().get("id").toString()).isEqualTo("[{id}]");
|
||||
assertThat(data.indexToExpander().get(0)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_MapParams() throws Exception {
|
||||
Method method = TestTemplate_MapParams.class.getDeclaredMethod("getTest",
|
||||
Map.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.queryMapIndex()).isNotNull();
|
||||
assertThat(data.queryMapIndex().intValue()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessHeaders() throws Exception {
|
||||
Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest",
|
||||
String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("X-Foo").iterator().next())
|
||||
.isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessHeadersWithoutValues() throws Exception {
|
||||
Method method = TestTemplate_HeadersWithoutValues.class
|
||||
.getDeclaredMethod("getTest", String.class);
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessAnnotations_Fallback() throws Exception {
|
||||
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTestFallback",
|
||||
String.class, String.class, Integer.class);
|
||||
|
||||
assumeTrue("does not have java 8 parameter names",
|
||||
hasJava8ParameterNames(method));
|
||||
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo(
|
||||
"/advanced/testfallback/{id}?amount=" + encode("{amount}", UTF_8));
|
||||
assertThat(data.template().method()).isEqualTo("PUT");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next())
|
||||
.isEqualTo("Authorization");
|
||||
assertThat(data.indexToName().get(1).iterator().next()).isEqualTo("id");
|
||||
assertThat(data.indexToName().get(2).iterator().next()).isEqualTo("amount");
|
||||
|
||||
assertThat(data.template().headers().get("Authorization").iterator().next())
|
||||
.isEqualTo("{Authorization}");
|
||||
assertThat(data.template().queries().get("amount").iterator().next())
|
||||
.isEqualTo("{amount}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessHeaderMap() throws Exception {
|
||||
Method method = TestTemplate_HeaderMap.class.getDeclaredMethod("headerMap",
|
||||
@@ -468,11 +472,11 @@ public class SpringMvcContractTests {
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/headerMap", data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals(0, data.headerMapIndex().intValue());
|
||||
assertThat(data.template().url()).isEqualTo("/headerMap");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.headerMapIndex().intValue()).isEqualTo(0);
|
||||
Map<String, Collection<String>> headers = data.template().headers();
|
||||
assertEquals("{aHeader}", headers.get("aHeader").iterator().next());
|
||||
assertThat(headers.get("aHeader").iterator().next()).isEqualTo("{aHeader}");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
@@ -489,12 +493,12 @@ public class SpringMvcContractTests {
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/queryMap?aParam=" + encode("{aParam}", UTF_8),
|
||||
data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals(0, data.queryMapIndex().intValue());
|
||||
assertThat(data.template().url())
|
||||
.isEqualTo("/queryMap?aParam=" + encode("{aParam}", UTF_8));
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.queryMapIndex().intValue()).isEqualTo(0);
|
||||
Map<String, Collection<String>> params = data.template().queries();
|
||||
assertEquals("{aParam}", params.get("aParam").iterator().next());
|
||||
assertThat(params.get("aParam").iterator().next()).isEqualTo("{aParam}");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -504,12 +508,12 @@ public class SpringMvcContractTests {
|
||||
MethodMetadata data = this.contract
|
||||
.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertEquals("/queryMapObject?aParam=" + encode("{aParam}", UTF_8),
|
||||
data.template().url());
|
||||
assertEquals("GET", data.template().method());
|
||||
assertEquals(0, data.queryMapIndex().intValue());
|
||||
assertThat(data.template().url())
|
||||
.isEqualTo("/queryMapObject?aParam=" + encode("{aParam}", UTF_8));
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.queryMapIndex().intValue()).isEqualTo(0);
|
||||
Map<String, Collection<String>> params = data.template().queries();
|
||||
assertEquals("{aParam}", params.get("aParam").iterator().next());
|
||||
assertThat(params.get("aParam").iterator().next()).isEqualTo("{aParam}");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
@@ -520,6 +524,7 @@ public class SpringMvcContractTests {
|
||||
}
|
||||
|
||||
public interface TestTemplate_Simple {
|
||||
|
||||
@RequestMapping(value = "/test/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
ResponseEntity<TestObject> getTest(@PathVariable("id") String id);
|
||||
|
||||
@@ -534,16 +539,19 @@ public class SpringMvcContractTests {
|
||||
|
||||
@PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
TestObject postMappingTest(@RequestBody TestObject object);
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping("/prepend/{classId}")
|
||||
public interface TestTemplate_Class_Annotations {
|
||||
|
||||
@RequestMapping(value = "/test/{testId}", method = RequestMethod.GET)
|
||||
TestObject getSpecificTest(@PathVariable("classId") String classId,
|
||||
@PathVariable("testId") String testId);
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
TestObject getAllTests(@PathVariable("classId") String classId);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_Extended extends TestTemplate_Class_Annotations {
|
||||
@@ -551,57 +559,68 @@ public class SpringMvcContractTests {
|
||||
}
|
||||
|
||||
public interface TestTemplate_Headers {
|
||||
|
||||
@RequestMapping(value = "/test/{id}", method = RequestMethod.GET, headers = "X-Foo=bar")
|
||||
ResponseEntity<TestObject> getTest(@PathVariable("id") String id);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_HeadersWithoutValues {
|
||||
@RequestMapping(value = "/test/{id}", method = RequestMethod.GET, headers = { "X-Foo", "!X-Bar", "X-Baz!=fooBar" })
|
||||
|
||||
@RequestMapping(value = "/test/{id}", method = RequestMethod.GET, headers = {
|
||||
"X-Foo", "!X-Bar", "X-Baz!=fooBar" })
|
||||
ResponseEntity<TestObject> getTest(@PathVariable("id") String id);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_ListParams {
|
||||
|
||||
@RequestMapping(value = "/test", method = RequestMethod.GET)
|
||||
ResponseEntity<TestObject> getTest(@RequestParam("id") List<String> id);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_ListParamsWithoutName {
|
||||
|
||||
@RequestMapping(value = "/test", method = RequestMethod.GET)
|
||||
ResponseEntity<TestObject> getTest(@RequestParam List<String> id);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_MapParams {
|
||||
|
||||
@RequestMapping(value = "/test", method = RequestMethod.GET)
|
||||
ResponseEntity<TestObject> getTest(@RequestParam Map<String, String> params);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_HeaderMap {
|
||||
|
||||
@RequestMapping(path = "/headerMap")
|
||||
String headerMap(
|
||||
@RequestHeader MultiValueMap<String, String> headerMap,
|
||||
String headerMap(@RequestHeader MultiValueMap<String, String> headerMap,
|
||||
@RequestHeader(name = "aHeader") String aHeader);
|
||||
|
||||
@RequestMapping(path = "/headerMapMoreThanOnce")
|
||||
String headerMapMoreThanOnce(
|
||||
@RequestHeader MultiValueMap<String, String> headerMap1,
|
||||
@RequestHeader MultiValueMap<String, String> headerMap2);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_QueryMap {
|
||||
|
||||
@RequestMapping(path = "/queryMap")
|
||||
String queryMap(
|
||||
@RequestParam MultiValueMap<String, String> queryMap,
|
||||
String queryMap(@RequestParam MultiValueMap<String, String> queryMap,
|
||||
@RequestParam(name = "aParam") String aParam);
|
||||
|
||||
@RequestMapping(path = "/queryMapMoreThanOnce")
|
||||
String queryMapMoreThanOnce(
|
||||
@RequestParam MultiValueMap<String, String> queryMap1,
|
||||
String queryMapMoreThanOnce(@RequestParam MultiValueMap<String, String> queryMap1,
|
||||
@RequestParam MultiValueMap<String, String> queryMap2);
|
||||
|
||||
@RequestMapping(path = "/queryMapObject")
|
||||
String queryMapObject(
|
||||
@SpringQueryMap TestObject queryMap,
|
||||
String queryMapObject(@SpringQueryMap TestObject queryMap,
|
||||
@RequestParam(name = "aParam") String aParam);
|
||||
|
||||
}
|
||||
|
||||
@JsonAutoDetect
|
||||
@@ -612,7 +631,7 @@ public class SpringMvcContractTests {
|
||||
@RequestMapping(path = "/test/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
ResponseEntity<TestObject> getTest(@RequestHeader("Authorization") String auth,
|
||||
@PathVariable("id") String id, @RequestParam("amount") Integer amount);
|
||||
|
||||
|
||||
@RequestMapping(path = "/test2", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
ResponseEntity<TestObject> getTest2(
|
||||
@RequestHeader(name = "Authorization") String auth,
|
||||
@@ -625,6 +644,7 @@ public class SpringMvcContractTests {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
TestObject getTest();
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_DateTimeFormatParameter {
|
||||
@@ -632,8 +652,9 @@ public class SpringMvcContractTests {
|
||||
String CUSTOM_PATTERN = "dd-MM-yyyy HH:mm";
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
String getTest(@RequestParam(name = "localDateTime")
|
||||
@DateTimeFormat(pattern = CUSTOM_PATTERN) LocalDateTime localDateTime);
|
||||
String getTest(
|
||||
@RequestParam(name = "localDateTime") @DateTimeFormat(pattern = CUSTOM_PATTERN) LocalDateTime localDateTime);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_NumberFormatParameter {
|
||||
@@ -641,14 +662,16 @@ public class SpringMvcContractTests {
|
||||
String CUSTOM_PATTERN = "$###,###.###";
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
String getTest(@RequestParam("amount")
|
||||
@NumberFormat(pattern = CUSTOM_PATTERN) BigDecimal amount);
|
||||
String getTest(
|
||||
@RequestParam("amount") @NumberFormat(pattern = CUSTOM_PATTERN) BigDecimal amount);
|
||||
|
||||
}
|
||||
|
||||
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
|
||||
@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
|
||||
public class TestObject {
|
||||
|
||||
public String something;
|
||||
|
||||
public Double number;
|
||||
|
||||
public TestObject() {
|
||||
@@ -691,10 +714,11 @@ public class SpringMvcContractTests {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("TestObject{")
|
||||
.append("something='").append(something).append("', ")
|
||||
.append("number=").append(number)
|
||||
.append("}").toString();
|
||||
return new StringBuilder("TestObject{").append("something='")
|
||||
.append(this.something).append("', ").append("number=")
|
||||
.append(this.number).append("}").toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,7 +12,6 @@
|
||||
* 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.openfeign.test;
|
||||
@@ -57,7 +56,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -67,9 +65,8 @@ import static org.mockito.Mockito.mockingDetails;
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(properties =
|
||||
{"feign.okhttp.enabled: false",
|
||||
"ribbon.eureka.enabled = false"})
|
||||
@SpringBootTest(properties = { "feign.okhttp.enabled: false",
|
||||
"ribbon.eureka.enabled = false" })
|
||||
@DirtiesContext
|
||||
public class ApacheHttpClientConfigurationTests {
|
||||
|
||||
@@ -84,49 +81,65 @@ public class ApacheHttpClientConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testFactories() {
|
||||
assertThat(connectionManagerFactory).isInstanceOf(ApacheHttpClientConnectionManagerFactory.class);
|
||||
assertThat(connectionManagerFactory).isInstanceOf(ApacheHttpClientConfigurationTestApp.MyApacheHttpClientConnectionManagerFactory.class);
|
||||
assertThat(httpClientFactory).isInstanceOf(ApacheHttpClientFactory.class);
|
||||
assertThat(httpClientFactory).isInstanceOf(ApacheHttpClientConfigurationTestApp.MyApacheHttpClientFactory.class);
|
||||
assertThat(this.connectionManagerFactory)
|
||||
.isInstanceOf(ApacheHttpClientConnectionManagerFactory.class);
|
||||
assertThat(this.connectionManagerFactory).isInstanceOf(
|
||||
ApacheHttpClientConfigurationTestApp.MyApacheHttpClientConnectionManagerFactory.class);
|
||||
assertThat(this.httpClientFactory).isInstanceOf(ApacheHttpClientFactory.class);
|
||||
assertThat(this.httpClientFactory).isInstanceOf(
|
||||
ApacheHttpClientConfigurationTestApp.MyApacheHttpClientFactory.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpClientWithFeign() {
|
||||
Client delegate = feignClient.getDelegate();
|
||||
assertTrue(ApacheHttpClient.class.isInstance(delegate));
|
||||
ApacheHttpClient apacheHttpClient = (ApacheHttpClient)delegate;
|
||||
Client delegate = this.feignClient.getDelegate();
|
||||
assertThat(ApacheHttpClient.class.isInstance(delegate)).isTrue();
|
||||
ApacheHttpClient apacheHttpClient = (ApacheHttpClient) delegate;
|
||||
HttpClient httpClient = getField(apacheHttpClient, "client");
|
||||
MockingDetails httpClientDetails = mockingDetails(httpClient);
|
||||
assertTrue(httpClientDetails.isMock());
|
||||
assertThat(httpClientDetails.isMock()).isTrue();
|
||||
}
|
||||
|
||||
protected <T> T getField(Object target, String name) {
|
||||
Field field = ReflectionUtils.findField(target.getClass(), name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
Object value = ReflectionUtils.getField(field, target);
|
||||
return (T)value;
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@EnableFeignClients(clients = {ApacheHttpClientConfigurationTestApp.FooClient.class})
|
||||
@EnableFeignClients(clients = {
|
||||
ApacheHttpClientConfigurationTestApp.FooClient.class })
|
||||
static class ApacheHttpClientConfigurationTestApp {
|
||||
|
||||
static class MyApacheHttpClientConnectionManagerFactory extends DefaultApacheHttpClientConnectionManagerFactory {
|
||||
@FeignClient(name = "foo", serviceId = "foo")
|
||||
interface FooClient {
|
||||
|
||||
}
|
||||
|
||||
static class MyApacheHttpClientConnectionManagerFactory
|
||||
extends DefaultApacheHttpClientConnectionManagerFactory {
|
||||
|
||||
@Override
|
||||
public HttpClientConnectionManager newConnectionManager(boolean disableSslValidation, int maxTotalConnections, int maxConnectionsPerRoute, long timeToLive, TimeUnit timeUnit, RegistryBuilder registry) {
|
||||
public HttpClientConnectionManager newConnectionManager(
|
||||
boolean disableSslValidation, int maxTotalConnections,
|
||||
int maxConnectionsPerRoute, long timeToLive, TimeUnit timeUnit,
|
||||
RegistryBuilder registry) {
|
||||
return mock(PoolingHttpClientConnectionManager.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MyApacheHttpClientFactory extends DefaultApacheHttpClientFactory {
|
||||
public MyApacheHttpClientFactory(HttpClientBuilder builder) {
|
||||
|
||||
MyApacheHttpClientFactory(HttpClientBuilder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClientBuilder createBuilder() {
|
||||
CloseableHttpClient client = mock(CloseableHttpClient.class);
|
||||
CloseableHttpClient client = mock(CloseableHttpClient.class);
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
StatusLine statusLine = mock(StatusLine.class);
|
||||
doReturn(200).when(statusLine).getStatusCode();
|
||||
@@ -134,21 +147,25 @@ public class ApacheHttpClientConfigurationTests {
|
||||
Header[] headers = new BasicHeader[0];
|
||||
doReturn(headers).when(response).getAllHeaders();
|
||||
try {
|
||||
Mockito.doReturn(response).when(client).execute(any(HttpUriRequest.class));
|
||||
} catch (IOException e) {
|
||||
Mockito.doReturn(response).when(client)
|
||||
.execute(any(HttpUriRequest.class));
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
HttpClientBuilder builder = mock(HttpClientBuilder.class);
|
||||
Mockito.doReturn(client).when(builder).build();
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class MyConfig {
|
||||
|
||||
@Bean
|
||||
public ApacheHttpClientFactory apacheHttpClientFactory(HttpClientBuilder builder) {
|
||||
public ApacheHttpClientFactory apacheHttpClientFactory(
|
||||
HttpClientBuilder builder) {
|
||||
return new MyApacheHttpClientFactory(builder);
|
||||
}
|
||||
|
||||
@@ -159,9 +176,6 @@ public class ApacheHttpClientConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name="foo", serviceId = "foo")
|
||||
interface FooClient {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,7 +12,6 @@
|
||||
* 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.openfeign.test;
|
||||
@@ -23,11 +22,10 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
||||
|
||||
@Configuration
|
||||
public class NoSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests()
|
||||
.anyRequest().permitAll()
|
||||
.and()
|
||||
.csrf().disable();
|
||||
http.authorizeRequests().anyRequest().permitAll().and().csrf().disable();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,7 +12,6 @@
|
||||
* 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.openfeign.test;
|
||||
@@ -20,9 +19,13 @@ package org.springframework.cloud.openfeign.test;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import feign.Client;
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockingDetails;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@@ -39,21 +42,18 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockingDetails;
|
||||
|
||||
import feign.Client;
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(properties = {"feign.okhttp.enabled: true",
|
||||
"spring.cloud.httpclientfactories.ok.enabled: true", "ribbon.eureka.enabled = false", "ribbon.okhttp.enabled: true",
|
||||
"feign.okhttp.enabled: true", "ribbon.httpclient.enabled: false", "feign.httpclient.enabled: false"})
|
||||
@SpringBootTest(properties = { "feign.okhttp.enabled: true",
|
||||
"spring.cloud.httpclientfactories.ok.enabled: true",
|
||||
"ribbon.eureka.enabled = false", "ribbon.okhttp.enabled: true",
|
||||
"feign.okhttp.enabled: true", "ribbon.httpclient.enabled: false",
|
||||
"feign.httpclient.enabled: false" })
|
||||
@DirtiesContext
|
||||
public class OkHttpClientConfigurationTests {
|
||||
|
||||
@@ -68,46 +68,41 @@ public class OkHttpClientConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testFactories() {
|
||||
assertThat(connectionPoolFactory).isInstanceOf(OkHttpClientConnectionPoolFactory.class);
|
||||
assertThat(connectionPoolFactory).isInstanceOf(TestConfig.MyOkHttpClientConnectionPoolFactory.class);
|
||||
assertThat(okHttpClientFactory).isInstanceOf(OkHttpClientFactory.class);
|
||||
assertThat(okHttpClientFactory).isInstanceOf(TestConfig.MyOkHttpClientFactory.class);
|
||||
assertThat(this.connectionPoolFactory)
|
||||
.isInstanceOf(OkHttpClientConnectionPoolFactory.class);
|
||||
assertThat(this.connectionPoolFactory)
|
||||
.isInstanceOf(TestConfig.MyOkHttpClientConnectionPoolFactory.class);
|
||||
assertThat(this.okHttpClientFactory).isInstanceOf(OkHttpClientFactory.class);
|
||||
assertThat(this.okHttpClientFactory)
|
||||
.isInstanceOf(TestConfig.MyOkHttpClientFactory.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpClientWithFeign() {
|
||||
Client delegate = feignClient.getDelegate();
|
||||
assertTrue(feign.okhttp.OkHttpClient.class.isInstance(delegate));
|
||||
feign.okhttp.OkHttpClient okHttpClient = (feign.okhttp.OkHttpClient)delegate;
|
||||
Client delegate = this.feignClient.getDelegate();
|
||||
assertThat(feign.okhttp.OkHttpClient.class.isInstance(delegate)).isTrue();
|
||||
feign.okhttp.OkHttpClient okHttpClient = (feign.okhttp.OkHttpClient) delegate;
|
||||
OkHttpClient httpClient = getField(okHttpClient, "delegate");
|
||||
MockingDetails httpClientDetails = mockingDetails(httpClient);
|
||||
assertTrue(httpClientDetails.isMock());
|
||||
assertThat(httpClientDetails.isMock()).isTrue();
|
||||
}
|
||||
|
||||
protected <T> T getField(Object target, String name) {
|
||||
Field field = ReflectionUtils.findField(target.getClass(), name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
Object value = ReflectionUtils.getField(field, target);
|
||||
return (T)value;
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
@FeignClient(name = "foo", serviceId = "foo")
|
||||
interface FooClient {
|
||||
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
static class TestConfig {
|
||||
|
||||
static class MyOkHttpClientConnectionPoolFactory extends DefaultOkHttpClientConnectionPoolFactory {
|
||||
@Override
|
||||
public ConnectionPool create(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {
|
||||
return new ConnectionPool();
|
||||
}
|
||||
}
|
||||
|
||||
static class MyOkHttpClientFactory extends DefaultOkHttpClientFactory {
|
||||
public MyOkHttpClientFactory(OkHttpClient.Builder builder) {
|
||||
super(builder);
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OkHttpClientConnectionPoolFactory connectionPoolFactory() {
|
||||
return new MyOkHttpClientConnectionPoolFactory();
|
||||
@@ -120,10 +115,28 @@ public class OkHttpClientConfigurationTests {
|
||||
|
||||
@Bean
|
||||
public OkHttpClient client() {
|
||||
return mock(OkHttpClient.class);
|
||||
}
|
||||
return mock(OkHttpClient.class);
|
||||
}
|
||||
|
||||
static class MyOkHttpClientConnectionPoolFactory
|
||||
extends DefaultOkHttpClientConnectionPoolFactory {
|
||||
|
||||
@Override
|
||||
public ConnectionPool create(int maxIdleConnections, long keepAliveDuration,
|
||||
TimeUnit timeUnit) {
|
||||
return new ConnectionPool();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MyOkHttpClientFactory extends DefaultOkHttpClientFactory {
|
||||
|
||||
MyOkHttpClientFactory(OkHttpClient.Builder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name="foo", serviceId = "foo")
|
||||
interface FooClient {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -34,17 +34,18 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Configuration
|
||||
@Import({NoopDiscoveryClientAutoConfiguration.class})
|
||||
@Import({ NoopDiscoveryClientAutoConfiguration.class })
|
||||
@AutoConfigureBefore(SecurityAutoConfiguration.class)
|
||||
public class TestAutoConfiguration {
|
||||
|
||||
public static final String USER = "user";
|
||||
|
||||
public static final String PASSWORD = "{noop}password";
|
||||
|
||||
@Configuration
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
protected static class TestSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
protected static class TestSecurityConfiguration
|
||||
extends WebSecurityConfigurerAdapter {
|
||||
|
||||
TestSecurityConfiguration() {
|
||||
super(true);
|
||||
@@ -53,18 +54,18 @@ public class TestAutoConfiguration {
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() {
|
||||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
|
||||
manager.createUser(User.withUsername(USER).password(PASSWORD).roles("USER").build());
|
||||
manager.createUser(
|
||||
User.withUsername(USER).password(PASSWORD).roles("USER").build());
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// super.configure(http);
|
||||
http.antMatcher("/proxy-username")
|
||||
.httpBasic()
|
||||
.and()
|
||||
.authorizeRequests().antMatchers("/**").permitAll();
|
||||
http.antMatcher("/proxy-username").httpBasic().and().authorizeRequests()
|
||||
.antMatchers("/**").permitAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* * 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.
|
||||
* 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.openfeign.testclients;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
@@ -26,7 +25,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
*/
|
||||
@FeignClient(name = "localapp")
|
||||
public interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
String getHello();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,24 +12,26 @@
|
||||
* 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.openfeign.valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import feign.Logger;
|
||||
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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
@@ -39,20 +41,15 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
|
||||
import feign.Logger;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Jakub Narloch
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = FeignClientNotPrimaryTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
|
||||
@SpringBootTest(classes = FeignClientNotPrimaryTests.Application.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"spring.application.name=feignclientnotprimarytest",
|
||||
"logging.level.org.springframework.cloud.openfeign.valid=DEBUG",
|
||||
"feign.httpclient.enabled=false", "feign.okhttp.enabled=false" })
|
||||
@@ -60,8 +57,11 @@ import static org.junit.Assert.assertNull;
|
||||
public class FeignClientNotPrimaryTests {
|
||||
|
||||
public static final String HELLO_WORLD_1 = "hello world 1";
|
||||
|
||||
public static final String OI_TERRA_2 = "oi terra 2";
|
||||
|
||||
public static final String MYHEADER1 = "myheader1";
|
||||
|
||||
public static final String MYHEADER2 = "myheader2";
|
||||
|
||||
@Value("${local.server.port}")
|
||||
@@ -73,8 +73,26 @@ public class FeignClientNotPrimaryTests {
|
||||
@Autowired
|
||||
private List<TestClient> testClients;
|
||||
|
||||
@Test
|
||||
public void testClientType() {
|
||||
assertThat(this.testClient).as("testClient was of wrong type")
|
||||
.isInstanceOf(PrimaryTestClient.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientCount() {
|
||||
assertThat(this.testClients).as("testClients was wrong").hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = this.testClient.getHello();
|
||||
assertThat(hello).as("hello was null").isNull();
|
||||
}
|
||||
|
||||
@FeignClient(name = "localapp", primary = false)
|
||||
protected interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, path = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
@@ -83,8 +101,8 @@ public class FeignClientNotPrimaryTests {
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@EnableFeignClients(clients = { TestClient.class} ,
|
||||
defaultConfiguration = TestDefaultFeignConfig.class)
|
||||
@EnableFeignClients(clients = {
|
||||
TestClient.class }, defaultConfiguration = TestDefaultFeignConfig.class)
|
||||
@RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class)
|
||||
protected static class Application {
|
||||
|
||||
@@ -101,53 +119,44 @@ public class FeignClientNotPrimaryTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientType() {
|
||||
assertThat(this.testClient).as("testClient was of wrong type").isInstanceOf(PrimaryTestClient.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientCount() {
|
||||
assertThat(this.testClients).as("testClients was wrong").hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = this.testClient.getHello();
|
||||
assertNull("hello was null", hello);
|
||||
}
|
||||
|
||||
protected static class PrimaryTestClient implements TestClient {
|
||||
|
||||
@Override
|
||||
public Hello getHello() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
|
||||
private String message;
|
||||
|
||||
public Hello() {}
|
||||
public Hello() {
|
||||
}
|
||||
|
||||
public Hello(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class TestDefaultFeignConfig {
|
||||
|
||||
@Bean
|
||||
Logger.Level feignLoggerLevel() {
|
||||
return Logger.Level.FULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Load balancer with fixed server list for "local" pointing to localhost
|
||||
@@ -163,4 +172,5 @@ public class FeignClientNotPrimaryTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -17,20 +17,21 @@
|
||||
package org.springframework.cloud.openfeign.valid;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -41,67 +42,72 @@ public class FeignClientValidationTests {
|
||||
public void validNotLoadBalanced() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
GoodUrlConfiguration.class);
|
||||
assertNotNull(context.getBean(GoodUrlConfiguration.Client.class));
|
||||
assertThat(context.getBean(GoodUrlConfiguration.Client.class)).isNotNull();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({FeignAutoConfiguration.class, HttpClientConfiguration.class})
|
||||
@EnableFeignClients(clients = GoodUrlConfiguration.Client.class)
|
||||
protected static class GoodUrlConfiguration {
|
||||
|
||||
@FeignClient(name="example", url="http://example.com")
|
||||
interface Client {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
@Deprecated
|
||||
String get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validPlaceholder() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
PlaceholderUrlConfiguration.class);
|
||||
assertNotNull(context.getBean(PlaceholderUrlConfiguration.Client.class));
|
||||
assertThat(context.getBean(PlaceholderUrlConfiguration.Client.class)).isNotNull();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({FeignAutoConfiguration.class, HttpClientConfiguration.class})
|
||||
@EnableFeignClients(clients = PlaceholderUrlConfiguration.Client.class)
|
||||
protected static class PlaceholderUrlConfiguration {
|
||||
|
||||
@FeignClient(name="example", url="${feignClient.url:http://example.com}")
|
||||
interface Client {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
@Deprecated
|
||||
String get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validLoadBalanced() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
LoadBalancerAutoConfiguration.class,
|
||||
RibbonAutoConfiguration.class,
|
||||
LoadBalancerAutoConfiguration.class, RibbonAutoConfiguration.class,
|
||||
FeignRibbonClientAutoConfiguration.class,
|
||||
GoodServiceIdConfiguration.class);
|
||||
assertNotNull(context.getBean(GoodServiceIdConfiguration.Client.class));
|
||||
assertThat(context.getBean(GoodServiceIdConfiguration.Client.class)).isNotNull();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({FeignAutoConfiguration.class, HttpClientConfiguration.class})
|
||||
@Import({ FeignAutoConfiguration.class, HttpClientConfiguration.class })
|
||||
@EnableFeignClients(clients = GoodUrlConfiguration.Client.class)
|
||||
protected static class GoodUrlConfiguration {
|
||||
|
||||
@FeignClient(name = "example", url = "http://example.com")
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
@Deprecated
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ FeignAutoConfiguration.class, HttpClientConfiguration.class })
|
||||
@EnableFeignClients(clients = PlaceholderUrlConfiguration.Client.class)
|
||||
protected static class PlaceholderUrlConfiguration {
|
||||
|
||||
@FeignClient(name = "example", url = "${feignClient.url:http://example.com}")
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
@Deprecated
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ FeignAutoConfiguration.class, HttpClientConfiguration.class })
|
||||
@EnableFeignClients(clients = GoodServiceIdConfiguration.Client.class)
|
||||
protected static class GoodServiceIdConfiguration {
|
||||
|
||||
@FeignClient("foo")
|
||||
interface Client {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
@Deprecated
|
||||
String get();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -18,19 +18,23 @@ package org.springframework.cloud.openfeign.valid;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import feign.Client;
|
||||
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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -46,18 +50,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import feign.Client;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -81,25 +74,63 @@ public class FeignHttpClientTests {
|
||||
@Autowired
|
||||
private UserClient userClient;
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = this.testClient.getHello();
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match")
|
||||
.isEqualTo(new Hello("hello world 1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch() {
|
||||
ResponseEntity<Void> response = this.testClient.patchHello(new Hello("foo"));
|
||||
assertThat(response).isNotNull();
|
||||
String header = response.getHeaders().getFirst("X-Hello");
|
||||
assertThat(header).isEqualTo("hello world patch");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignClientType() throws IllegalAccessException {
|
||||
assertThat(this.feignClient).isInstanceOf(LoadBalancerFeignClient.class);
|
||||
LoadBalancerFeignClient client = (LoadBalancerFeignClient) this.feignClient;
|
||||
Client delegate = client.getDelegate();
|
||||
assertThat(delegate).isInstanceOf(feign.httpclient.ApacheHttpClient.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignInheritanceSupport() {
|
||||
assertThat(this.userClient).as("UserClient was null").isNotNull();
|
||||
final User user = this.userClient.getUser(1);
|
||||
assertThat(user).as("Returned user was null").isNotNull();
|
||||
assertThat(new User("John Smith")).as("Users were different").isEqualTo(user);
|
||||
}
|
||||
|
||||
@FeignClient("localapp")
|
||||
protected interface TestClient extends BaseTestClient {
|
||||
|
||||
}
|
||||
|
||||
protected interface BaseTestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
Hello getHello();
|
||||
|
||||
@RequestMapping(method = RequestMethod.PATCH, value = "/hellop", consumes = "application/json")
|
||||
ResponseEntity<Void> patchHello(Hello hello);
|
||||
|
||||
}
|
||||
|
||||
protected interface UserService {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/users/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
User getUser(@PathVariable("id") long id);
|
||||
|
||||
}
|
||||
|
||||
@FeignClient("localapp1")
|
||||
protected interface UserClient extends UserService {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -108,8 +139,7 @@ public class FeignHttpClientTests {
|
||||
@EnableFeignClients(clients = { TestClient.class, UserClient.class })
|
||||
@RibbonClients({
|
||||
@RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class),
|
||||
@RibbonClient(name = "localapp1", configuration = LocalRibbonClientConfiguration.class)
|
||||
})
|
||||
@RibbonClient(name = "localapp1", configuration = LocalRibbonClientConfiguration.class) })
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
protected static class Application implements UserService {
|
||||
|
||||
@@ -120,12 +150,14 @@ public class FeignHttpClientTests {
|
||||
|
||||
@RequestMapping(method = RequestMethod.PATCH, value = "/hellop")
|
||||
public ResponseEntity<Void> patchHello(@RequestBody Hello hello,
|
||||
@RequestHeader("Content-Length") int contentLength) {
|
||||
@RequestHeader("Content-Length") int contentLength) {
|
||||
if (contentLength <= 0) {
|
||||
throw new IllegalArgumentException("Invalid Content-Length "+ contentLength);
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Content-Length " + contentLength);
|
||||
}
|
||||
if (!hello.getMessage().equals("foo")) {
|
||||
throw new IllegalArgumentException("Invalid Hello: " + hello.getMessage());
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Hello: " + hello.getMessage());
|
||||
}
|
||||
return ResponseEntity.ok().header("X-Hello", "hello world patch").build();
|
||||
}
|
||||
@@ -137,48 +169,19 @@ public class FeignHttpClientTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = this.testClient.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch() {
|
||||
ResponseEntity<Void> response = this.testClient.patchHello(new Hello("foo"));
|
||||
assertThat(response, is(notNullValue()));
|
||||
String header = response.getHeaders().getFirst("X-Hello");
|
||||
assertThat(header, equalTo("hello world patch"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignClientType() throws IllegalAccessException {
|
||||
assertThat(this.feignClient, is(instanceOf(LoadBalancerFeignClient.class)));
|
||||
LoadBalancerFeignClient client = (LoadBalancerFeignClient) this.feignClient;
|
||||
Client delegate = client.getDelegate();
|
||||
assertThat(delegate, is(instanceOf(feign.httpclient.ApacheHttpClient.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignInheritanceSupport() {
|
||||
assertNotNull("UserClient was null", this.userClient);
|
||||
final User user = this.userClient.getUser(1);
|
||||
assertNotNull("Returned user was null", user);
|
||||
assertEquals("Users were different", user, new User("John Smith"));
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
|
||||
private String message;
|
||||
|
||||
public Hello() {}
|
||||
public Hello() {
|
||||
}
|
||||
|
||||
public Hello(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
@@ -187,29 +190,36 @@ public class FeignHttpClientTests {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Hello that = (Hello) o;
|
||||
return Objects.equals(message, that.message);
|
||||
return Objects.equals(this.message, that.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(message);
|
||||
return Objects.hash(this.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class User {
|
||||
|
||||
private String name;
|
||||
|
||||
public User() {}
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
@@ -218,16 +228,21 @@ public class FeignHttpClientTests {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
User that = (User) o;
|
||||
return Objects.equals(name, that.name);
|
||||
return Objects.equals(this.name, that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
return Objects.hash(this.name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Load balancer with fixed server list for "local" pointing to localhost
|
||||
@@ -243,4 +258,5 @@ public class FeignHttpClientTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -12,24 +12,29 @@
|
||||
* 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.openfeign.valid;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import feign.Client;
|
||||
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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -44,20 +49,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import feign.Client;
|
||||
|
||||
import java.util.Objects;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -82,25 +74,63 @@ public class FeignOkHttpTests {
|
||||
@Autowired
|
||||
private UserClient userClient;
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = this.testClient.getHello();
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match")
|
||||
.isEqualTo(new Hello("hello world 1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch() {
|
||||
ResponseEntity<Void> response = this.testClient.patchHello(new Hello("foo"));
|
||||
assertThat(response).isNotNull();
|
||||
String header = response.getHeaders().getFirst("X-Hello");
|
||||
assertThat(header).isEqualTo("hello world patch");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignClientType() throws IllegalAccessException {
|
||||
assertThat(this.feignClient).isInstanceOf(LoadBalancerFeignClient.class);
|
||||
LoadBalancerFeignClient client = (LoadBalancerFeignClient) this.feignClient;
|
||||
Client delegate = client.getDelegate();
|
||||
assertThat(delegate).isInstanceOf(feign.okhttp.OkHttpClient.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignInheritanceSupport() {
|
||||
assertThat(this.userClient).as("UserClient was null").isNotNull();
|
||||
final User user = this.userClient.getUser(1);
|
||||
assertThat(user).as("Returned user was null").isNotNull();
|
||||
assertThat(new User("John Smith")).as("Users were different").isEqualTo(user);
|
||||
}
|
||||
|
||||
@FeignClient("localapp")
|
||||
protected interface TestClient extends BaseTestClient {
|
||||
|
||||
}
|
||||
|
||||
protected interface BaseTestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
Hello getHello();
|
||||
|
||||
@RequestMapping(method = RequestMethod.PATCH, value = "/hellop", consumes = "application/json")
|
||||
ResponseEntity<Void> patchHello(Hello hello);
|
||||
|
||||
}
|
||||
|
||||
protected interface UserService {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/users/{id}")
|
||||
User getUser(@PathVariable("id") long id);
|
||||
|
||||
}
|
||||
|
||||
@FeignClient("localapp1")
|
||||
protected interface UserClient extends UserService {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -109,8 +139,7 @@ public class FeignOkHttpTests {
|
||||
@EnableFeignClients(clients = { TestClient.class, UserClient.class })
|
||||
@RibbonClients({
|
||||
@RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class),
|
||||
@RibbonClient(name = "localapp1", configuration = LocalRibbonClientConfiguration.class)
|
||||
})
|
||||
@RibbonClient(name = "localapp1", configuration = LocalRibbonClientConfiguration.class) })
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
protected static class Application implements UserService {
|
||||
|
||||
@@ -123,10 +152,12 @@ public class FeignOkHttpTests {
|
||||
public ResponseEntity<Void> patchHello(@RequestBody Hello hello,
|
||||
@RequestHeader("Content-Length") int contentLength) {
|
||||
if (contentLength <= 0) {
|
||||
throw new IllegalArgumentException("Invalid Content-Length "+ contentLength);
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Content-Length " + contentLength);
|
||||
}
|
||||
if (!hello.getMessage().equals("foo")) {
|
||||
throw new IllegalArgumentException("Invalid Hello: " + hello.getMessage());
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Hello: " + hello.getMessage());
|
||||
}
|
||||
return ResponseEntity.ok().header("X-Hello", "hello world patch").build();
|
||||
}
|
||||
@@ -138,38 +169,8 @@ public class FeignOkHttpTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = this.testClient.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch() {
|
||||
ResponseEntity<Void> response = this.testClient.patchHello(new Hello("foo"));
|
||||
assertThat(response, is(notNullValue()));
|
||||
String header = response.getHeaders().getFirst("X-Hello");
|
||||
assertThat(header, equalTo("hello world patch"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignClientType() throws IllegalAccessException {
|
||||
assertThat(this.feignClient, is(instanceOf(LoadBalancerFeignClient.class)));
|
||||
LoadBalancerFeignClient client = (LoadBalancerFeignClient) this.feignClient;
|
||||
Client delegate = client.getDelegate();
|
||||
assertThat(delegate, is(instanceOf(feign.okhttp.OkHttpClient.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeignInheritanceSupport() {
|
||||
assertNotNull("UserClient was null", this.userClient);
|
||||
final User user = this.userClient.getUser(1);
|
||||
assertNotNull("Returned user was null", user);
|
||||
assertEquals("Users were different", user, new User("John Smith"));
|
||||
}
|
||||
|
||||
public static class Hello {
|
||||
|
||||
private String message;
|
||||
|
||||
public Hello() {
|
||||
@@ -180,7 +181,7 @@ public class FeignOkHttpTests {
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
@@ -189,19 +190,25 @@ public class FeignOkHttpTests {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Hello that = (Hello) o;
|
||||
return Objects.equals(message, that.message);
|
||||
return Objects.equals(this.message, that.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(message);
|
||||
return Objects.hash(this.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class User {
|
||||
|
||||
private String name;
|
||||
|
||||
public User() {
|
||||
@@ -212,7 +219,7 @@ public class FeignOkHttpTests {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
@@ -221,16 +228,21 @@ public class FeignOkHttpTests {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
User that = (User) o;
|
||||
return Objects.equals(name, that.name);
|
||||
return Objects.equals(this.name, that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
return Objects.hash(this.name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Load balancer with fixed server list for "local" pointing to localhost
|
||||
@@ -246,4 +258,5 @@ public class FeignOkHttpTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* * 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.
|
||||
* 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.openfeign.valid.scanning;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
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.context.SpringBootTest;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration;
|
||||
import org.springframework.cloud.openfeign.testclients.TestClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -37,17 +39,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = FeignClientEnvVarTests.Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, value = {
|
||||
@SpringBootTest(classes = FeignClientEnvVarTests.Application.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"spring.application.name=feignclienttest", "feign.httpclient.enabled=false",
|
||||
"basepackage=org.springframework.cloud.openfeign.testclients" })
|
||||
@DirtiesContext
|
||||
@@ -59,22 +58,23 @@ public class FeignClientEnvVarTests {
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
String hello = this.testClient.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", "hello world 1", hello);
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match").isEqualTo("hello world 1");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@EnableFeignClients(basePackages = {"${basepackage}"})
|
||||
@EnableFeignClients(basePackages = { "${basepackage}" })
|
||||
@RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class)
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
protected static class Application {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public String getHello() {
|
||||
return "hello world 1";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Load balancer with fixed server list for "local" pointing to localhost
|
||||
@@ -90,4 +90,5 @@ public class FeignClientEnvVarTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -26,7 +26,6 @@ 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.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
@@ -41,14 +40,14 @@ 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.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = FeignClientScanningTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
|
||||
@SpringBootTest(classes = FeignClientScanningTests.Application.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"spring.application.name=feignclienttest", "feign.httpclient.enabled=false" })
|
||||
@DirtiesContext
|
||||
public class FeignClientScanningTests {
|
||||
@@ -66,16 +65,34 @@ public class FeignClientScanningTests {
|
||||
@SuppressWarnings("unused")
|
||||
private Client feignClient;
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
String hello = this.testClient.getHello();
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match").isEqualTo("hello world 1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleTypeByKey() {
|
||||
String hello = this.testClientByKey.getHello();
|
||||
assertThat(hello).as("hello was null").isNotNull();
|
||||
assertThat(hello).as("first hello didn't match").isEqualTo("hello world 1");
|
||||
}
|
||||
|
||||
@FeignClient("localapp123")
|
||||
protected interface TestClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
String getHello();
|
||||
|
||||
}
|
||||
|
||||
@FeignClient("${feignClient.localappName}")
|
||||
protected interface TestClientByKey {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
String getHello();
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -85,6 +102,7 @@ public class FeignClientScanningTests {
|
||||
@RibbonClients(defaultConfiguration = LocalRibbonClientConfiguration.class)
|
||||
@Import(NoSecurityConfiguration.class)
|
||||
protected static class Application {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public String getHello() {
|
||||
return "hello world 1";
|
||||
@@ -92,20 +110,6 @@ public class FeignClientScanningTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
String hello = this.testClient.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", "hello world 1", hello);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleTypeByKey() {
|
||||
String hello = this.testClientByKey.getHello();
|
||||
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 {
|
||||
@@ -119,4 +123,5 @@ public class FeignClientScanningTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
# This configuration used by test class FeignClientUsingPropertiesTests
|
||||
|
||||
logging.level.org.springframework.cloud.openfeign=debug
|
||||
|
||||
feign.client.default-to-properties=true
|
||||
feign.client.default-config=default
|
||||
|
||||
feign.client.config.default.connectTimeout=5000
|
||||
feign.client.config.default.readTimeout=5000
|
||||
feign.client.config.default.loggerLevel=full
|
||||
feign.client.config.default.errorDecoder=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.DefaultErrorDecoder
|
||||
feign.client.config.default.retryer=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.NoRetryer
|
||||
feign.client.config.default.decode404=true
|
||||
|
||||
feign.client.config.foo.requestInterceptors[0]=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.FooRequestInterceptor
|
||||
feign.client.config.foo.requestInterceptors[1]=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.BarRequestInterceptor
|
||||
|
||||
feign.client.config.bar.connectTimeout=1000
|
||||
feign.client.config.bar.readTimeout=1000
|
||||
|
||||
feign.client.config.form.encoder=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.FormEncoder
|
||||
feign.client.config.form.encoder=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.FormEncoder
|
||||
|
||||
Reference in New Issue
Block a user