Skip to content

Commit d585597

Browse files
author
Thanh Nguyen
committed
More tests for async flow.
1 parent b6a4525 commit d585597

File tree

2 files changed

+193
-1
lines changed

2 files changed

+193
-1
lines changed

spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientOverrideDefaultsTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ interface FooAsyncClient {
224224

225225
}
226226

227-
@FeignClient(name = "barAsync", url = "https://barAsync",
227+
@FeignClient(name = "barAsync", url = "https://barAsync", decode404 = true,
228228
configuration = BarAsyncConfiguration.class, asynchronous = true)
229229
interface BarAsyncClient {
230230

spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientUsingPropertiesTests.java

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.List;
2929
import java.util.Map;
3030
import java.util.Objects;
31+
import java.util.concurrent.CompletionException;
3132
import java.util.concurrent.TimeUnit;
3233
import java.util.stream.Collectors;
3334
import java.util.stream.Stream;
@@ -76,6 +77,7 @@
7677
* @author Eko Kurniawan Khannedy
7778
* @author Olga Maciaszek-Sharma
7879
* @author Ilia Ilinykh
80+
* @author Nguyen Ky Thanh
7981
*/
8082
@SuppressWarnings("FieldMayBeFinal")
8183
@RunWith(SpringJUnit4ClassRunner.class)
@@ -142,62 +144,124 @@ public FooClient fooClient() {
142144
"http://localhost:" + port);
143145
}
144146

147+
public FooAsyncClient fooAsyncClient() {
148+
fooFactoryBean.setApplicationContext(applicationContext);
149+
return (FooAsyncClient) fooFactoryBean.asyncFeign(context)
150+
.target(FooAsyncClient.class, "http://localhost:" + port);
151+
}
152+
145153
public BarClient barClient() {
146154
barFactoryBean.setApplicationContext(applicationContext);
147155
return barFactoryBean.feign(context).target(BarClient.class,
148156
"http://localhost:" + port);
149157
}
150158

159+
public BarAsyncClient barAsyncClient() {
160+
barFactoryBean.setApplicationContext(applicationContext);
161+
return (BarAsyncClient) barFactoryBean.asyncFeign(context)
162+
.target(BarAsyncClient.class, "http://localhost:" + port);
163+
}
164+
151165
public UnwrapClient unwrapClient() {
152166
unwrapFactoryBean.setApplicationContext(applicationContext);
153167
return unwrapFactoryBean.feign(context).target(UnwrapClient.class,
154168
"http://localhost:" + port);
155169
}
156170

171+
public UnwrapAsyncClient unwrapAsyncClient() {
172+
unwrapFactoryBean.setApplicationContext(applicationContext);
173+
return (UnwrapAsyncClient) unwrapFactoryBean.asyncFeign(context)
174+
.target(UnwrapAsyncClient.class, "http://localhost:" + port);
175+
}
176+
157177
public FormClient formClient() {
158178
formFactoryBean.setApplicationContext(applicationContext);
159179
return formFactoryBean.feign(context).target(FormClient.class,
160180
"http://localhost:" + port);
161181
}
162182

183+
public FormAsyncClient formAsyncClient() {
184+
formFactoryBean.setApplicationContext(applicationContext);
185+
return (FormAsyncClient) formFactoryBean.asyncFeign(context)
186+
.target(FormAsyncClient.class, "http://localhost:" + port);
187+
}
188+
163189
@Test
164190
public void testFoo() {
165191
String response = fooClient().foo();
166192
assertThat(response).isEqualTo("OK");
167193
}
168194

195+
@Test
196+
public void testFooAsync() {
197+
String response = fooAsyncClient().foo();
198+
assertThat(response).isEqualTo("OK");
199+
}
200+
169201
@Test(expected = RetryableException.class)
170202
public void testBar() {
171203
barClient().bar();
172204
fail("it should timeout");
173205
}
174206

207+
@Test(expected = CompletionException.class)
208+
public void testBarAsync() {
209+
barAsyncClient().bar();
210+
fail("it should timeout");
211+
}
212+
175213
@Test(expected = SocketTimeoutException.class)
176214
public void testUnwrap() throws Exception {
177215
unwrapClient().unwrap();
178216
fail("it should timeout");
179217
}
180218

219+
@Test(expected = CompletionException.class)
220+
public void testUnwrapAsync() throws Exception {
221+
unwrapAsyncClient().unwrap();
222+
fail("it should timeout");
223+
}
224+
181225
@Test
182226
public void testForm() {
183227
Map<String, String> request = Collections.singletonMap("form", "Data");
184228
String response = formClient().form(request);
185229
assertThat(response).isEqualTo("Data");
186230
}
187231

232+
@Test
233+
public void testAsyncForm() {
234+
Map<String, String> request = Collections.singletonMap("form", "Data");
235+
String response = formAsyncClient().form(request);
236+
assertThat(response).isEqualTo("Data");
237+
}
238+
188239
@Test
189240
public void testSingleValue() {
190241
List<String> response = singleValueClient().singleValue();
191242
assertThat(response).isEqualTo(Arrays.asList("header", "parameter"));
192243
}
193244

245+
@Test
246+
public void testSingleValueAsync() {
247+
List<String> response = singleValueAsyncClient().singleValue();
248+
assertThat(response).isEqualTo(Arrays.asList("header", "parameter"));
249+
}
250+
194251
@Test
195252
public void testMultipleValue() {
196253
List<String> response = multipleValueClient().multipleValue();
197254
assertThat(response).isEqualTo(
198255
Arrays.asList("header1", "header2", "parameter1", "parameter2"));
199256
}
200257

258+
@Test
259+
public void testMultipleValueAsync() {
260+
List<String> response = multipleValueAsyncClient().multipleValue();
261+
assertThat(response).isEqualTo(
262+
Arrays.asList("header1", "header2", "parameter1", "parameter2"));
263+
}
264+
201265
public SingleValueClient singleValueClient() {
202266
this.defaultHeadersAndQuerySingleParamsFeignClientFactoryBean
203267
.setApplicationContext(this.applicationContext);
@@ -206,6 +270,14 @@ public SingleValueClient singleValueClient() {
206270
.target(SingleValueClient.class, "http://localhost:" + this.port);
207271
}
208272

273+
public SingleValueAsyncClient singleValueAsyncClient() {
274+
this.defaultHeadersAndQuerySingleParamsFeignClientFactoryBean
275+
.setApplicationContext(this.applicationContext);
276+
return (SingleValueAsyncClient) this.defaultHeadersAndQuerySingleParamsFeignClientFactoryBean
277+
.asyncFeign(this.context)
278+
.target(SingleValueAsyncClient.class, "http://localhost:" + this.port);
279+
}
280+
209281
public MultipleValueClient multipleValueClient() {
210282
this.defaultHeadersAndQueryMultipleParamsFeignClientFactoryBean
211283
.setApplicationContext(this.applicationContext);
@@ -214,6 +286,14 @@ public MultipleValueClient multipleValueClient() {
214286
.target(MultipleValueClient.class, "http://localhost:" + this.port);
215287
}
216288

289+
public MultipleValueAsyncClient multipleValueAsyncClient() {
290+
this.defaultHeadersAndQueryMultipleParamsFeignClientFactoryBean
291+
.setApplicationContext(this.applicationContext);
292+
return (MultipleValueAsyncClient) this.defaultHeadersAndQueryMultipleParamsFeignClientFactoryBean
293+
.asyncFeign(this.context)
294+
.target(MultipleValueAsyncClient.class, "http://localhost:" + this.port);
295+
}
296+
217297
@Test
218298
public void readTimeoutShouldWorkWhenConnectTimeoutNotSet() {
219299
FeignClientFactoryBean readTimeoutFactoryBean = new FeignClientFactoryBean();
@@ -230,6 +310,23 @@ public void readTimeoutShouldWorkWhenConnectTimeoutNotSet() {
230310
assertThat(options.connectTimeoutMillis()).isEqualTo(5000);
231311
}
232312

313+
@Test
314+
public void readTimeoutAsyncShouldWorkWhenConnectTimeoutNotSet() {
315+
FeignClientFactoryBean readTimeoutFactoryBean = new FeignClientFactoryBean();
316+
readTimeoutFactoryBean.setContextId("readTimeout");
317+
readTimeoutFactoryBean.setType(FeignClientFactoryBean.class);
318+
readTimeoutFactoryBean.setApplicationContext(applicationContext);
319+
320+
TimeoutAsyncClient client = (TimeoutAsyncClient) readTimeoutFactoryBean
321+
.asyncFeign(context)
322+
.target(TimeoutAsyncClient.class, "http://localhost:" + port);
323+
324+
Request.Options options = getAsyncRequestOptions((Proxy) client);
325+
326+
assertThat(options.readTimeoutMillis()).isEqualTo(1000);
327+
assertThat(options.connectTimeoutMillis()).isEqualTo(5000);
328+
}
329+
233330
@Test
234331
public void connectTimeoutShouldWorkWhenReadTimeoutNotSet() {
235332
FeignClientFactoryBean readTimeoutFactoryBean = new FeignClientFactoryBean();
@@ -246,6 +343,23 @@ public void connectTimeoutShouldWorkWhenReadTimeoutNotSet() {
246343
assertThat(options.readTimeoutMillis()).isEqualTo(5000);
247344
}
248345

346+
@Test
347+
public void connectTimeoutAsyncShouldWorkWhenReadTimeoutNotSet() {
348+
FeignClientFactoryBean readTimeoutFactoryBean = new FeignClientFactoryBean();
349+
readTimeoutFactoryBean.setContextId("connectTimeout");
350+
readTimeoutFactoryBean.setType(FeignClientFactoryBean.class);
351+
readTimeoutFactoryBean.setApplicationContext(applicationContext);
352+
353+
TimeoutAsyncClient client = (TimeoutAsyncClient) readTimeoutFactoryBean
354+
.asyncFeign(context)
355+
.target(TimeoutAsyncClient.class, "http://localhost:" + port);
356+
357+
Request.Options options = getAsyncRequestOptions((Proxy) client);
358+
359+
assertThat(options.connectTimeoutMillis()).isEqualTo(1000);
360+
assertThat(options.readTimeoutMillis()).isEqualTo(5000);
361+
}
362+
249363
@Test
250364
public void shouldSetFollowRedirects() {
251365
FeignClientFactoryBean testFactoryBean = new FeignClientFactoryBean();
@@ -261,6 +375,22 @@ public void shouldSetFollowRedirects() {
261375
assertThat(options.isFollowRedirects()).isFalse();
262376
}
263377

378+
@Test
379+
public void shouldSetFollowRedirectsAsync() {
380+
FeignClientFactoryBean testFactoryBean = new FeignClientFactoryBean();
381+
testFactoryBean.setContextId("test");
382+
testFactoryBean.setType(FeignClientFactoryBean.class);
383+
testFactoryBean.setApplicationContext(applicationContext);
384+
385+
TimeoutAsyncClient client = (TimeoutAsyncClient) testFactoryBean
386+
.asyncFeign(context)
387+
.target(TimeoutAsyncClient.class, "http://localhost:" + port);
388+
389+
Request.Options options = getAsyncRequestOptions((Proxy) client);
390+
391+
assertThat(options.isFollowRedirects()).isFalse();
392+
}
393+
264394
private Request.Options getRequestOptions(Proxy client) {
265395
Object invocationHandler = ReflectionTestUtils.getField(client, "h");
266396
Map<Method, InvocationHandlerFactory.MethodHandler> dispatch = (Map<Method, InvocationHandlerFactory.MethodHandler>) ReflectionTestUtils
@@ -270,27 +400,60 @@ private Request.Options getRequestOptions(Proxy client) {
270400
"options");
271401
}
272402

403+
private Request.Options getAsyncRequestOptions(Proxy client) {
404+
Object asyncInvocationHandler = ReflectionTestUtils.getField(client, "h");
405+
Object instance = ReflectionTestUtils.getField(asyncInvocationHandler,
406+
"instance");
407+
Object invocationHandler = ReflectionTestUtils.getField(instance, "h");
408+
Map<Method, InvocationHandlerFactory.MethodHandler> dispatch = (Map<Method, InvocationHandlerFactory.MethodHandler>) ReflectionTestUtils
409+
.getField(Objects.requireNonNull(invocationHandler), "dispatch");
410+
Method key = new ArrayList<>(dispatch.keySet()).get(0);
411+
return (Request.Options) ReflectionTestUtils.getField(dispatch.get(key),
412+
"options");
413+
}
414+
273415
protected interface FooClient {
274416

275417
@GetMapping(path = "/foo")
276418
String foo();
277419

278420
}
279421

422+
protected interface FooAsyncClient {
423+
424+
@GetMapping(path = "/foo")
425+
String foo();
426+
427+
}
428+
280429
protected interface BarClient {
281430

282431
@GetMapping(path = "/bar")
283432
String bar();
284433

285434
}
286435

436+
protected interface BarAsyncClient {
437+
438+
@GetMapping(path = "/bar")
439+
String bar();
440+
441+
}
442+
287443
protected interface UnwrapClient {
288444

289445
@GetMapping(path = "/bar") // intentionally /bar
290446
String unwrap() throws IOException;
291447

292448
}
293449

450+
protected interface UnwrapAsyncClient {
451+
452+
@GetMapping(path = "/bar") // intentionally /bar
453+
String unwrap() throws IOException;
454+
455+
}
456+
294457
protected interface FormClient {
295458

296459
@RequestMapping(value = "/form", method = RequestMethod.POST,
@@ -299,27 +462,56 @@ protected interface FormClient {
299462

300463
}
301464

465+
protected interface FormAsyncClient {
466+
467+
@RequestMapping(value = "/form", method = RequestMethod.POST,
468+
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
469+
String form(Map<String, String> form);
470+
471+
}
472+
302473
protected interface SingleValueClient {
303474

304475
@GetMapping(path = "/singleValue")
305476
List<String> singleValue();
306477

307478
}
308479

480+
protected interface SingleValueAsyncClient {
481+
482+
@GetMapping(path = "/singleValue")
483+
List<String> singleValue();
484+
485+
}
486+
309487
protected interface MultipleValueClient {
310488

311489
@GetMapping(path = "/multipleValue")
312490
List<String> multipleValue();
313491

314492
}
315493

494+
protected interface MultipleValueAsyncClient {
495+
496+
@GetMapping(path = "/multipleValue")
497+
List<String> multipleValue();
498+
499+
}
500+
316501
protected interface TimeoutClient {
317502

318503
@GetMapping("/timeouts")
319504
String timeouts();
320505

321506
}
322507

508+
protected interface TimeoutAsyncClient {
509+
510+
@GetMapping("/timeouts")
511+
String timeouts();
512+
513+
}
514+
323515
@Configuration(proxyBeanMethods = false)
324516
@EnableAutoConfiguration
325517
@RestController

0 commit comments

Comments
 (0)