Skip to content

Commit 3042e52

Browse files
edudarvelo
andauthored
Advanced parametrized type resolution for AsyncFeign (#1623)
* Advanced parametrized type resolution for AsyncFeign * Formatting fix Co-authored-by: Marvin Froeder <velo@users.noreply.github.com>
1 parent fdc7bc2 commit 3042e52

File tree

2 files changed

+112
-5
lines changed

2 files changed

+112
-5
lines changed

core/src/main/java/feign/MethodInfo.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@ class MethodInfo {
3333
MethodInfo(Class<?> targetType, Method method) {
3434
this.configKey = Feign.configKey(targetType, method);
3535

36-
final Type type = method.getGenericReturnType();
36+
final Type type = Types.resolve(targetType, targetType, method.getGenericReturnType());
3737

38-
if (method.getReturnType() != CompletableFuture.class) {
39-
this.asyncReturnType = false;
40-
this.underlyingReturnType = type;
41-
} else {
38+
if (type instanceof ParameterizedType
39+
&& Types.getRawType(type).isAssignableFrom(CompletableFuture.class)) {
4240
this.asyncReturnType = true;
4341
this.underlyingReturnType = ((ParameterizedType) type).getActualTypeArguments()[0];
42+
} else {
43+
this.asyncReturnType = false;
44+
this.underlyingReturnType = type;
4445
}
4546
}
4647

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright 2012-2022 The Feign Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
package feign;
15+
16+
import java.lang.reflect.ParameterizedType;
17+
import java.lang.reflect.Type;
18+
import java.util.List;
19+
import java.util.concurrent.CompletableFuture;
20+
import org.junit.Test;
21+
import org.junit.experimental.runners.Enclosed;
22+
import org.junit.runner.RunWith;
23+
import static org.junit.Assert.*;
24+
25+
@RunWith(Enclosed.class)
26+
public class MethodInfoTest {
27+
28+
public static class AsyncClientTest {
29+
public interface AsyncClient {
30+
CompletableFuture<String> log();
31+
}
32+
33+
@Test
34+
public void testCompletableFutureOfString() throws Exception {
35+
MethodInfo mi = new MethodInfo(AsyncClient.class, AsyncClient.class.getMethod("log"));
36+
assertEquals("AsyncClient#log()", mi.configKey());
37+
assertTrue(mi.isAsyncReturnType());
38+
assertEquals(String.class, mi.underlyingReturnType());
39+
}
40+
}
41+
42+
public static class GenericAsyncClientTest {
43+
public interface GenericAsyncClient<T> {
44+
T log();
45+
}
46+
47+
public interface AsyncClient extends GenericAsyncClient<CompletableFuture<String>> {
48+
}
49+
50+
@Test
51+
public void testGenericCompletableFutureOfString() throws Exception {
52+
MethodInfo mi = new MethodInfo(AsyncClient.class, AsyncClient.class.getMethod("log"));
53+
assertEquals("AsyncClient#log()", mi.configKey());
54+
assertTrue(mi.isAsyncReturnType());
55+
assertEquals(String.class, mi.underlyingReturnType());
56+
}
57+
}
58+
59+
public static class SyncClientTest {
60+
public interface SyncClient {
61+
String log();
62+
}
63+
64+
@Test
65+
public void testString() throws Exception {
66+
MethodInfo mi = new MethodInfo(SyncClient.class, SyncClient.class.getMethod("log"));
67+
assertEquals("SyncClient#log()", mi.configKey());
68+
assertFalse(mi.isAsyncReturnType());
69+
assertEquals(String.class, mi.underlyingReturnType());
70+
}
71+
}
72+
73+
public static class GenericSyncClientTest {
74+
public interface GenericSyncClient<T> {
75+
T log();
76+
}
77+
78+
public interface SyncClient extends GenericSyncClient<List<String>> {
79+
}
80+
81+
public static class ListOfStrings implements ParameterizedType {
82+
@Override
83+
public Type[] getActualTypeArguments() {
84+
return new Type[] {String.class};
85+
}
86+
87+
@Override
88+
public Type getRawType() {
89+
return List.class;
90+
}
91+
92+
@Override
93+
public Type getOwnerType() {
94+
return null;
95+
}
96+
}
97+
98+
@Test
99+
public void testListOfStrings() throws Exception {
100+
MethodInfo mi = new MethodInfo(SyncClient.class, SyncClient.class.getMethod("log"));
101+
assertEquals("SyncClient#log()", mi.configKey());
102+
assertFalse(mi.isAsyncReturnType());
103+
assertTrue(Types.equals(new ListOfStrings(), mi.underlyingReturnType()));
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)