Skip to content

Commit 9aae5f7

Browse files
committed
FIX: interceptors disapearing on BaseBuilder#clone
1 parent 4a438b9 commit 9aae5f7

File tree

3 files changed

+81
-29
lines changed

3 files changed

+81
-29
lines changed

core/src/main/java/feign/BaseBuilder.java

+44-29
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@
3232
import java.util.stream.Collectors;
3333

3434
public abstract class BaseBuilder<B extends BaseBuilder<B, T>, T> implements Cloneable {
35-
36-
private final B thisB;
37-
3835
protected final List<RequestInterceptor> requestInterceptors = new ArrayList<>();
3936
protected final List<ResponseInterceptor> responseInterceptors = new ArrayList<>();
4037
protected Logger.Level logLevel = Logger.Level.NONE;
@@ -56,37 +53,42 @@ public abstract class BaseBuilder<B extends BaseBuilder<B, T>, T> implements Clo
5653

5754
public BaseBuilder() {
5855
super();
59-
thisB = (B) this;
6056
}
6157

58+
@SuppressWarnings("unchecked")
6259
public B logLevel(Logger.Level logLevel) {
6360
this.logLevel = logLevel;
64-
return thisB;
61+
return (B) this;
6562
}
6663

64+
@SuppressWarnings("unchecked")
6765
public B contract(Contract contract) {
6866
this.contract = contract;
69-
return thisB;
67+
return (B) this;
7068
}
7169

70+
@SuppressWarnings("unchecked")
7271
public B retryer(Retryer retryer) {
7372
this.retryer = retryer;
74-
return thisB;
73+
return (B) this;
7574
}
7675

76+
@SuppressWarnings("unchecked")
7777
public B logger(Logger logger) {
7878
this.logger = logger;
79-
return thisB;
79+
return (B) this;
8080
}
8181

82+
@SuppressWarnings("unchecked")
8283
public B encoder(Encoder encoder) {
8384
this.encoder = encoder;
84-
return thisB;
85+
return (B) this;
8586
}
8687

88+
@SuppressWarnings("unchecked")
8789
public B decoder(Decoder decoder) {
8890
this.decoder = decoder;
89-
return thisB;
91+
return (B) this;
9092
}
9193

9294
/**
@@ -99,25 +101,29 @@ public B decoder(Decoder decoder) {
99101
*
100102
* @since 9.6
101103
*/
104+
@SuppressWarnings("unchecked")
102105
public B doNotCloseAfterDecode() {
103106
this.closeAfterDecode = false;
104-
return thisB;
107+
return (B) this;
105108
}
106109

110+
@SuppressWarnings("unchecked")
107111
public B decodeVoid() {
108112
this.decodeVoid = true;
109-
return thisB;
113+
return (B) this;
110114
}
111115

116+
@SuppressWarnings("unchecked")
112117
public B queryMapEncoder(QueryMapEncoder queryMapEncoder) {
113118
this.queryMapEncoder = queryMapEncoder;
114-
return thisB;
119+
return (B) this;
115120
}
116121

117122
/** Allows to map the response before passing it to the decoder. */
123+
@SuppressWarnings("unchecked")
118124
public B mapAndDecode(ResponseMapper mapper, Decoder decoder) {
119125
this.decoder = new ResponseMappingDecoder(mapper, decoder);
120-
return thisB;
126+
return (B) this;
121127
}
122128

123129
/**
@@ -135,9 +141,10 @@ public B mapAndDecode(ResponseMapper mapper, Decoder decoder) {
135141
*
136142
* @since 11.9
137143
*/
144+
@SuppressWarnings("unchecked")
138145
public B dismiss404() {
139146
this.dismiss404 = true;
140-
return thisB;
147+
return (B) this;
141148
}
142149

143150
/**
@@ -157,81 +164,91 @@ public B dismiss404() {
157164
* @deprecated use {@link #dismiss404()} instead.
158165
*/
159166
@Deprecated
167+
@SuppressWarnings("unchecked")
160168
public B decode404() {
161169
this.dismiss404 = true;
162-
return thisB;
170+
return (B) this;
163171
}
164172

173+
@SuppressWarnings("unchecked")
165174
public B errorDecoder(ErrorDecoder errorDecoder) {
166175
this.errorDecoder = errorDecoder;
167-
return thisB;
176+
return (B) this;
168177
}
169178

179+
@SuppressWarnings("unchecked")
170180
public B options(Options options) {
171181
this.options = options;
172-
return thisB;
182+
return (B) this;
173183
}
174184

175185
/** Adds a single request interceptor to the builder. */
186+
@SuppressWarnings("unchecked")
176187
public B requestInterceptor(RequestInterceptor requestInterceptor) {
177188
this.requestInterceptors.add(requestInterceptor);
178-
return thisB;
189+
return (B) this;
179190
}
180191

181192
/**
182193
* Sets the full set of request interceptors for the builder, overwriting any previous
183194
* interceptors.
184195
*/
196+
@SuppressWarnings("unchecked")
185197
public B requestInterceptors(Iterable<RequestInterceptor> requestInterceptors) {
186198
this.requestInterceptors.clear();
187199
for (RequestInterceptor requestInterceptor : requestInterceptors) {
188200
this.requestInterceptors.add(requestInterceptor);
189201
}
190-
return thisB;
202+
return (B) this;
191203
}
192204

193205
/**
194206
* Sets the full set of request interceptors for the builder, overwriting any previous
195207
* interceptors.
196208
*/
209+
@SuppressWarnings("unchecked")
197210
public B responseInterceptors(Iterable<ResponseInterceptor> responseInterceptors) {
198211
this.responseInterceptors.clear();
199212
for (ResponseInterceptor responseInterceptor : responseInterceptors) {
200213
this.responseInterceptors.add(responseInterceptor);
201214
}
202-
return thisB;
215+
return (B) this;
203216
}
204217

205218
/** Adds a single response interceptor to the builder. */
219+
@SuppressWarnings("unchecked")
206220
public B responseInterceptor(ResponseInterceptor responseInterceptor) {
207221
this.responseInterceptors.add(responseInterceptor);
208-
return thisB;
222+
return (B) this;
209223
}
210224

211225
/** Allows you to override how reflective dispatch works inside of Feign. */
226+
@SuppressWarnings("unchecked")
212227
public B invocationHandlerFactory(InvocationHandlerFactory invocationHandlerFactory) {
213228
this.invocationHandlerFactory = invocationHandlerFactory;
214-
return thisB;
229+
return (B) this;
215230
}
216231

232+
@SuppressWarnings("unchecked")
217233
public B exceptionPropagationPolicy(ExceptionPropagationPolicy propagationPolicy) {
218234
this.propagationPolicy = propagationPolicy;
219-
return thisB;
235+
return (B) this;
220236
}
221237

238+
@SuppressWarnings("unchecked")
222239
public B addCapability(Capability capability) {
223240
this.capabilities.add(capability);
224-
return thisB;
241+
return (B) this;
225242
}
226243

227244
@SuppressWarnings("unchecked")
228245
B enrich() {
229246
if (capabilities.isEmpty()) {
230-
return thisB;
247+
return (B) this;
231248
}
232249

233250
try {
234-
B clone = (B) thisB.clone();
251+
B clone = (B) this.clone();
235252

236253
getFieldsToEnrich()
237254
.forEach(
@@ -274,8 +291,6 @@ List<Field> getFieldsToEnrich() {
274291
.filter(field -> !field.isSynthetic())
275292
// and capabilities itself
276293
.filter(field -> !Objects.equals(field.getName(), "capabilities"))
277-
// and thisB helper field
278-
.filter(field -> !Objects.equals(field.getName(), "thisB"))
279294
// skip primitive types
280295
.filter(field -> !field.getType().isPrimitive())
281296
// skip enumerations

core/src/test/java/feign/BaseBuilderTest.java

+23
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,27 @@ void checkEnrichTouchesAllBuilderFields()
6767
.responseInterceptor((ic, c) -> c.next(ic)),
6868
12);
6969
}
70+
71+
@Test
72+
void checkCloneDontLooseInterceptors() {
73+
Feign.Builder originalBuilder = Feign.builder().addCapability(new Capability() {});
74+
75+
// There is no any interceptors
76+
assertThat(originalBuilder.requestInterceptors).isNotNull().isEmpty();
77+
78+
Feign.Builder enrichedBuilder = originalBuilder.enrich();
79+
Feign.Builder enrichedBuilderWithInterceptor = enrichedBuilder.requestInterceptor((req) -> {});
80+
81+
// Original builder should have no interceptor
82+
assertThat(originalBuilder.requestInterceptors).isNotNull().isEmpty();
83+
84+
// enrichedBuilder should have an interceptor
85+
assertThat(enrichedBuilder.requestInterceptors).isNotNull().isNotEmpty().hasSize(1);
86+
87+
// enrichedBuilderWithInterceptor should have an interceptor
88+
assertThat(enrichedBuilderWithInterceptor.requestInterceptors)
89+
.isNotNull()
90+
.isNotEmpty()
91+
.hasSize(1);
92+
}
7093
}

oauth2/src/test/resources/test.env

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
AWS_DOMAIN=feign
2+
AWS_REGION=us-west-2
3+
AWS_CLIENT_ID=25fhico3bdqmssemu6ur5op98m
4+
AWS_CLIENT_SECRET=jpc3av0it1j32us3ijcf066u3cqg9euoo0pc920b6jqg9i0h1ki
5+
AWS_TENANT=us-west-2_WbMEZgSZt
6+
AWS_ISSUER_URI=https://cognito-idp.us-west-2.amazonaws.com/us-west-2_WbMEZgSZt
7+
AWS_JWK_SET_URI=https://cognito-idp.us-west-2.amazonaws.com/us-west-2_WbMEZgSZt/.well-known/jwks.json
8+
9+
AUTH0_CLIENT_ID=oleVJYeNgas7mJrRzmg5LQNR4aTpxDln
10+
AUTH0_CLIENT_SECRET=bZxSqpuH4m41PYjD5STHsTzOSgAMRWS5alc6JPz3zZLBFxggwgvgfc3qkdFzjUEN
11+
AUTH0_TENANT=hosuaby
12+
AUTH0_AUDIENCE=https://hosuaby.auth0.com/api/v2/
13+
AUTH0_ISSUER_URI=https://hosuaby.auth0.com/
14+
AUTH0_JWK_SET_URI=https://hosuaby.auth0.com/.well-known/jwks.json

0 commit comments

Comments
 (0)