Skip to content
This repository was archived by the owner on Dec 20, 2025. It is now read-only.

Commit 4e1a797

Browse files
feat(retrofit2): add ErrorHandlingExecutorCallAdapterFactory to the retrofit2 client (#1225)
* feat(retrofit2): add ErrorHandlingExecutorCallAdapterFactory to the retrofit2 client * test(retrofit2): add test coverage for ErrorHandlingExecutorCallAdapterFactory * test(retrofit2): add few more asserts in one of the tests
1 parent 8ea1b21 commit 4e1a797

3 files changed

Lines changed: 57 additions & 3 deletions

File tree

kork-retrofit2/kork-retrofit2.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ apply from: "$rootDir/gradle/kotlin-test.gradle"
44
dependencies {
55
api(platform(project(":spinnaker-dependencies")))
66
implementation project(":kork-web")
7+
implementation project(":kork-retrofit")
78
implementation "com.squareup.retrofit2:retrofit"
89
implementation "com.squareup.retrofit2:converter-jackson"
910
implementation "com.squareup.okhttp3:logging-interceptor"
1011
implementation "io.zipkin.brave:brave-instrumentation-okhttp3"
1112

12-
testImplementation project(":kork-retrofit")
1313
testImplementation "org.springframework.boot:spring-boot-starter-test"
1414
testRuntimeOnly "cglib:cglib-nodep"
1515
testRuntimeOnly "org.objenesis:objenesis"

kork-retrofit2/src/main/java/com/netflix/spinnaker/kork/retrofit/Retrofit2ServiceFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public <T> T create(
5757
.baseUrl(Objects.requireNonNull(HttpUrl.parse(serviceEndpoint.getBaseUrl())))
5858
.client(okHttpClient)
5959
.addConverterFactory(JacksonConverterFactory.create(objectMapper))
60+
.addCallAdapterFactory(ErrorHandlingExecutorCallAdapterFactory.getInstance())
6061
.build()
6162
.create(type);
6263
}

kork-retrofit2/src/test/java/com/netflix/spinnaker/kork/retrofit/Retrofit2ServiceFactoryTest.java

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
2525
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
2626
import static org.junit.jupiter.api.Assertions.assertEquals;
27+
import static org.junit.jupiter.api.Assertions.assertThrows;
2728

2829
import com.fasterxml.jackson.databind.ObjectMapper;
2930
import com.github.tomakehurst.wiremock.WireMockServer;
@@ -36,6 +37,9 @@
3637
import com.netflix.spinnaker.config.okhttp3.OkHttpClientProvider;
3738
import com.netflix.spinnaker.kork.client.ServiceClientFactory;
3839
import com.netflix.spinnaker.kork.client.ServiceClientProvider;
40+
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerConversionException;
41+
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerHttpException;
42+
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerServerException;
3943
import com.netflix.spinnaker.okhttp.OkHttpClientConfigurationProperties;
4044
import java.util.List;
4145
import java.util.Map;
@@ -108,15 +112,16 @@ void testRetrofit2ClientWithResponse() {
108112
.willReturn(
109113
aResponse()
110114
.withHeader("Content-Type", "application/json")
111-
.withBody("{\"message\": \"success\", \"code\": 200}")));
115+
.withBody("{\"message\": \"success\"}")));
112116

113117
ServiceEndpoint serviceEndpoint =
114118
new DefaultServiceEndpoint("retrofit2service", "http://localhost:" + port);
115119
Retrofit2TestService retrofit2TestService =
116120
serviceClientProvider.getService(Retrofit2TestService.class, serviceEndpoint);
117121
Response<Map<String, String>> response =
118122
Retrofit2SyncCall.executeCall(retrofit2TestService.getSomething());
119-
123+
assertEquals(response.code(), 200);
124+
assertEquals(response.headers().get("Content-Type"), "application/json");
120125
assertEquals(response.body().get("message"), "success");
121126
}
122127

@@ -150,6 +155,54 @@ void testRetrofit2Client_withInterceptor() {
150155
.withHeader("Authorization", equalTo("Bearer my-token")));
151156
}
152157

158+
@Test
159+
void testRetrofit2Client_withHttpException() {
160+
stubFor(
161+
get(urlEqualTo("/test"))
162+
.willReturn(
163+
aResponse()
164+
.withHeader("Content-Type", "application/json")
165+
.withStatus(400)
166+
.withBody("{\"message\": \"error\"}")));
167+
168+
ServiceEndpoint serviceEndpoint =
169+
new DefaultServiceEndpoint("retrofit2service", "http://localhost:" + port);
170+
171+
Retrofit2TestService retrofit2TestService =
172+
serviceClientProvider.getService(Retrofit2TestService.class, serviceEndpoint);
173+
174+
SpinnakerHttpException exception =
175+
assertThrows(
176+
SpinnakerHttpException.class,
177+
() -> Retrofit2SyncCall.executeCall(retrofit2TestService.getSomething()));
178+
assertEquals(exception.getResponseCode(), 400);
179+
assertEquals(
180+
exception.getMessage(),
181+
"Status: 400, Method: GET, URL: http://localhost:" + port + "/test, Message: error");
182+
}
183+
184+
@Test
185+
void testRetrofit2Client_withConversionException() {
186+
stubFor(
187+
get(urlEqualTo("/test"))
188+
.willReturn(
189+
aResponse()
190+
.withHeader("Content-Type", "application/json")
191+
.withBody("{\"message\": \"incorrect json}")));
192+
193+
ServiceEndpoint serviceEndpoint =
194+
new DefaultServiceEndpoint("retrofit2service", "http://localhost:" + port);
195+
196+
Retrofit2TestService retrofit2TestService =
197+
serviceClientProvider.getService(Retrofit2TestService.class, serviceEndpoint);
198+
199+
SpinnakerServerException exception =
200+
assertThrows(
201+
SpinnakerConversionException.class,
202+
() -> Retrofit2SyncCall.executeCall(retrofit2TestService.getSomething()));
203+
assertEquals(exception.getMessage(), "Failed to process response body");
204+
}
205+
153206
@Configuration
154207
public static class Retrofit2TestConfig {
155208

0 commit comments

Comments
 (0)