Skip to content

Commit

Permalink
feat(retrofit2): add ErrorHandlingExecutorCallAdapterFactory to the r…
Browse files Browse the repository at this point in the history
…etrofit2 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
  • Loading branch information
kirangodishala authored Feb 7, 2025
1 parent 8ea1b21 commit 4e1a797
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
2 changes: 1 addition & 1 deletion kork-retrofit2/kork-retrofit2.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ apply from: "$rootDir/gradle/kotlin-test.gradle"
dependencies {
api(platform(project(":spinnaker-dependencies")))
implementation project(":kork-web")
implementation project(":kork-retrofit")
implementation "com.squareup.retrofit2:retrofit"
implementation "com.squareup.retrofit2:converter-jackson"
implementation "com.squareup.okhttp3:logging-interceptor"
implementation "io.zipkin.brave:brave-instrumentation-okhttp3"

testImplementation project(":kork-retrofit")
testImplementation "org.springframework.boot:spring-boot-starter-test"
testRuntimeOnly "cglib:cglib-nodep"
testRuntimeOnly "org.objenesis:objenesis"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public <T> T create(
.baseUrl(Objects.requireNonNull(HttpUrl.parse(serviceEndpoint.getBaseUrl())))
.client(okHttpClient)
.addConverterFactory(JacksonConverterFactory.create(objectMapper))
.addCallAdapterFactory(ErrorHandlingExecutorCallAdapterFactory.getInstance())
.build()
.create(type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.WireMockServer;
Expand All @@ -36,6 +37,9 @@
import com.netflix.spinnaker.config.okhttp3.OkHttpClientProvider;
import com.netflix.spinnaker.kork.client.ServiceClientFactory;
import com.netflix.spinnaker.kork.client.ServiceClientProvider;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerConversionException;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerHttpException;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerServerException;
import com.netflix.spinnaker.okhttp.OkHttpClientConfigurationProperties;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -108,15 +112,16 @@ void testRetrofit2ClientWithResponse() {
.willReturn(
aResponse()
.withHeader("Content-Type", "application/json")
.withBody("{\"message\": \"success\", \"code\": 200}")));
.withBody("{\"message\": \"success\"}")));

ServiceEndpoint serviceEndpoint =
new DefaultServiceEndpoint("retrofit2service", "http://localhost:" + port);
Retrofit2TestService retrofit2TestService =
serviceClientProvider.getService(Retrofit2TestService.class, serviceEndpoint);
Response<Map<String, String>> response =
Retrofit2SyncCall.executeCall(retrofit2TestService.getSomething());

assertEquals(response.code(), 200);
assertEquals(response.headers().get("Content-Type"), "application/json");
assertEquals(response.body().get("message"), "success");
}

Expand Down Expand Up @@ -150,6 +155,54 @@ void testRetrofit2Client_withInterceptor() {
.withHeader("Authorization", equalTo("Bearer my-token")));
}

@Test
void testRetrofit2Client_withHttpException() {
stubFor(
get(urlEqualTo("/test"))
.willReturn(
aResponse()
.withHeader("Content-Type", "application/json")
.withStatus(400)
.withBody("{\"message\": \"error\"}")));

ServiceEndpoint serviceEndpoint =
new DefaultServiceEndpoint("retrofit2service", "http://localhost:" + port);

Retrofit2TestService retrofit2TestService =
serviceClientProvider.getService(Retrofit2TestService.class, serviceEndpoint);

SpinnakerHttpException exception =
assertThrows(
SpinnakerHttpException.class,
() -> Retrofit2SyncCall.executeCall(retrofit2TestService.getSomething()));
assertEquals(exception.getResponseCode(), 400);
assertEquals(
exception.getMessage(),
"Status: 400, Method: GET, URL: http://localhost:" + port + "/test, Message: error");
}

@Test
void testRetrofit2Client_withConversionException() {
stubFor(
get(urlEqualTo("/test"))
.willReturn(
aResponse()
.withHeader("Content-Type", "application/json")
.withBody("{\"message\": \"incorrect json}")));

ServiceEndpoint serviceEndpoint =
new DefaultServiceEndpoint("retrofit2service", "http://localhost:" + port);

Retrofit2TestService retrofit2TestService =
serviceClientProvider.getService(Retrofit2TestService.class, serviceEndpoint);

SpinnakerServerException exception =
assertThrows(
SpinnakerConversionException.class,
() -> Retrofit2SyncCall.executeCall(retrofit2TestService.getSomething()));
assertEquals(exception.getMessage(), "Failed to process response body");
}

@Configuration
public static class Retrofit2TestConfig {

Expand Down

0 comments on commit 4e1a797

Please sign in to comment.