Skip to content

Commit

Permalink
feat(exceptions): Add SpinnakerRetrofitErrorHandler and replace Retro…
Browse files Browse the repository at this point in the history
…fitError catch blocks (#1034)

* add SpinnakerRetrofitErrorHandler and replace RetrofitError catch blocks

* use native SpinnakerException setRetryable method instead of using IntegrationException

* remove explicit retry configuration from exception handling as it's covered by SpinnakerRetrofitErrorHandler

* use SpinnakerHttpException instead of NotFoundException

* chore(spotless): apply spotless fixes

---------

Co-authored-by: abe garcia <abraham_garcia-ortiz1@homedepot.com>
Co-authored-by: David Byron <dbyron@salesforce.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Mar 30, 2023
1 parent 0cc5ab8 commit 59dd50a
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 30 deletions.
1 change: 1 addition & 0 deletions fiat-api/fiat-api.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies {
implementation "io.spinnaker.kork:kork-security"
implementation "io.spinnaker.kork:kork-telemetry"
implementation "io.spinnaker.kork:kork-web"
implementation "io.spinnaker.kork:kork-retrofit"
implementation "com.squareup.retrofit:retrofit"
implementation "com.squareup.retrofit:converter-jackson"
implementation "com.jakewharton.retrofit:retrofit1-okhttp3-client"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.netflix.spinnaker.config.DefaultServiceEndpoint;
import com.netflix.spinnaker.config.ErrorConfiguration;
import com.netflix.spinnaker.config.okhttp3.OkHttpClientProvider;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerRetrofitErrorHandler;
import com.netflix.spinnaker.kork.web.exceptions.ExceptionMessageDecorator;
import com.netflix.spinnaker.okhttp.SpinnakerRequestInterceptor;
import com.netflix.spinnaker.retrofit.Slf4jRetrofitLogger;
Expand Down Expand Up @@ -81,6 +82,7 @@ public FiatService fiatService(
.setRequestInterceptor(interceptor)
.setClient(new Ok3Client(okHttpClient))
.setConverter(new JacksonConverter(objectMapper))
.setErrorHandler(SpinnakerRetrofitErrorHandler.getInstance())
.setLogLevel(retrofitLogLevel)
.setLog(new Slf4jRetrofitLogger(FiatService.class))
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import com.netflix.spinnaker.fiat.model.resources.Account;
import com.netflix.spinnaker.fiat.model.resources.Authorizable;
import com.netflix.spinnaker.fiat.model.resources.ResourceType;
import com.netflix.spinnaker.kork.exceptions.IntegrationException;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerHttpException;
import com.netflix.spinnaker.kork.telemetry.caffeine.CaffeineStatsCounter;
import com.netflix.spinnaker.security.AccessControlled;
import com.netflix.spinnaker.security.AuthenticatedRequest;
Expand Down Expand Up @@ -55,7 +55,6 @@
import org.springframework.stereotype.Component;
import org.springframework.util.backoff.BackOffExecution;
import org.springframework.util.backoff.ExponentialBackOff;
import retrofit.RetrofitError;

@Component
@Slf4j
Expand Down Expand Up @@ -188,19 +187,11 @@ public boolean canCreate(String resourceType, Object resource) {
try {
fiatService.canCreate(username, resourceType, resource);
return true;
} catch (RetrofitError re) {
boolean shouldRetry = true;
if (re.getKind() == RetrofitError.Kind.HTTP) {
switch (HttpStatus.valueOf(re.getResponse().getStatus())) {
case NOT_FOUND:
return false;
case BAD_REQUEST:
shouldRetry = false;
}
} catch (SpinnakerHttpException e) {
if (e.getResponseCode() == HttpStatus.NOT_FOUND.value()) {
return false;
}
IntegrationException ie = new IntegrationException(re);
ie.setRetryable(shouldRetry);
throw ie;
throw e;
}
});
})
Expand Down
1 change: 1 addition & 0 deletions fiat-github/fiat-github.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ dependencies {
implementation "com.squareup.retrofit:converter-jackson"
implementation "com.jakewharton.retrofit:retrofit1-okhttp3-client"
implementation "io.spinnaker.kork:kork-web"
implementation "io.spinnaker.kork:kork-retrofit"
implementation "javax.validation:validation-api"
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.netflix.spinnaker.config.okhttp3.OkHttpClientProvider;
import com.netflix.spinnaker.fiat.roles.github.GitHubProperties;
import com.netflix.spinnaker.fiat.roles.github.client.GitHubClient;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerRetrofitErrorHandler;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
Expand Down Expand Up @@ -44,6 +45,7 @@ public GitHubClient gitHubClient(OkHttpClientProvider clientProvider) {
clientProvider.getClient(
new DefaultServiceEndpoint("github", gitHubProperties.getBaseUrl()))))
.setConverter(new JacksonConverter())
.setErrorHandler(SpinnakerRetrofitErrorHandler.getInstance())
.setLogLevel(retrofitLogLevel)
.setLog(new Slf4jRetrofitLogger(GitHubClient.class))
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import com.netflix.spinnaker.fiat.roles.github.client.GitHubClient;
import com.netflix.spinnaker.fiat.roles.github.model.Member;
import com.netflix.spinnaker.fiat.roles.github.model.Team;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerHttpException;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerNetworkException;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
Expand All @@ -38,10 +40,10 @@
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import retrofit.RetrofitError;
import retrofit.client.Header;

@Slf4j
@Component
Expand Down Expand Up @@ -268,8 +270,10 @@ private List<Team> getTeamsInOrgPaginated(String organization, int page) {
try {
log.debug("Requesting page " + page + " of teams.");
teams = gitHubClient.getOrgTeams(organization, page, gitHubProperties.paginationValue);
} catch (RetrofitError e) {
if (e.getResponse().getStatus() != 404) {
} catch (SpinnakerNetworkException e) {
log.error(String.format("Could not find the server %s", gitHubProperties.getBaseUrl()), e);
} catch (SpinnakerHttpException e) {
if (e.getResponseCode() != HttpStatus.NOT_FOUND.value()) {
handleNon404s(e);
throw e;
} else {
Expand All @@ -285,8 +289,10 @@ private List<Member> getMembersInOrgPaginated(String organization, int page) {
try {
log.debug("Requesting page " + page + " of members.");
members = gitHubClient.getOrgMembers(organization, page, gitHubProperties.paginationValue);
} catch (RetrofitError e) {
if (e.getResponse().getStatus() != 404) {
} catch (SpinnakerNetworkException e) {
log.error(String.format("Could not find the server %s", gitHubProperties.getBaseUrl()), e);
} catch (SpinnakerHttpException e) {
if (e.getResponseCode() != HttpStatus.NOT_FOUND.value()) {
handleNon404s(e);
throw e;
} else {
Expand All @@ -304,8 +310,10 @@ private List<Member> getMembersInTeamPaginated(String organization, String teamS
members =
gitHubClient.getMembersOfTeam(
organization, teamSlug, page, gitHubProperties.paginationValue);
} catch (RetrofitError e) {
if (e.getResponse().getStatus() != 404) {
} catch (SpinnakerNetworkException e) {
log.error(String.format("Could not find the server %s", gitHubProperties.getBaseUrl()), e);
} catch (SpinnakerHttpException e) {
if (e.getResponseCode() != HttpStatus.NOT_FOUND.value()) {
handleNon404s(e);
throw e;
} else {
Expand All @@ -325,17 +333,16 @@ private boolean isMemberOfTeam(Team t, String username) {
return false;
}

private void handleNon404s(RetrofitError e) {
private void handleNon404s(SpinnakerHttpException e) {
String msg = "";
if (e.getKind() == RetrofitError.Kind.NETWORK) {
msg = String.format("Could not find the server %s", gitHubProperties.getBaseUrl());
} else if (e.getResponse().getStatus() == 401) {
if (e.getResponseCode() == HttpStatus.UNAUTHORIZED.value()) {
msg = "HTTP 401 Unauthorized.";
} else if (e.getResponse().getStatus() == 403) {
} else if (e.getResponseCode() == HttpStatus.FORBIDDEN.value()) {
HttpHeaders headers = e.getHeaders();
val rateHeaders =
e.getResponse().getHeaders().stream()
.filter(header -> RATE_LIMITING_HEADERS.contains(header.getName()))
.map(Header::toString)
RATE_LIMITING_HEADERS.stream()
.filter(headers::containsKey)
.map(headers::getFirst)
.collect(Collectors.toList());

msg = "HTTP 403 Forbidden. Rate limit info: " + StringUtils.join(rateHeaders, ", ");
Expand Down
1 change: 1 addition & 0 deletions fiat-web/fiat-web.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
implementation "io.spinnaker.kork:kork-config"
implementation "io.spinnaker.kork:kork-plugins"
implementation "io.spinnaker.kork:kork-web"
implementation "io.spinnaker.kork:kork-retrofit"
implementation "io.swagger:swagger-annotations"
implementation "net.logstash.logback:logstash-logback-encoder"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.netflix.spinnaker.config.okhttp3.OkHttpClientProvider;
import com.netflix.spinnaker.fiat.providers.ProviderHealthTracker;
import com.netflix.spinnaker.fiat.providers.internal.*;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerRetrofitErrorHandler;
import com.netflix.spinnaker.retrofit.Slf4jRetrofitLogger;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -68,6 +69,7 @@ Front50Api front50Api() {
new Ok3Client(
clientProvider.getClient(new DefaultServiceEndpoint("front50", front50Endpoint))))
.setConverter(new JacksonConverter(objectMapper))
.setErrorHandler(SpinnakerRetrofitErrorHandler.getInstance())
.setLogLevel(retrofitLogLevel)
.setLog(new Slf4jRetrofitLogger(Front50Api.class))
.build()
Expand Down Expand Up @@ -102,6 +104,7 @@ ClouddriverApi clouddriverApi() {
clientProvider.getClient(
new DefaultServiceEndpoint("clouddriver", clouddriverEndpoint))))
.setConverter(new JacksonConverter(objectMapper))
.setErrorHandler(SpinnakerRetrofitErrorHandler.getInstance())
.setLogLevel(retrofitLogLevel)
.setLog(new Slf4jRetrofitLogger(ClouddriverApi.class))
.build()
Expand Down Expand Up @@ -157,6 +160,7 @@ IgorApi igorApi(@Value("${services.igor.base-url}") String igorEndpoint) {
new Ok3Client(
clientProvider.getClient(new DefaultServiceEndpoint("igor", igorEndpoint))))
.setConverter(new JacksonConverter(objectMapper))
.setErrorHandler(SpinnakerRetrofitErrorHandler.getInstance())
.setLogLevel(retrofitLogLevel)
.setLog(new Slf4jRetrofitLogger(IgorApi.class))
.build()
Expand Down

0 comments on commit 59dd50a

Please sign in to comment.