001package org.hl7.fhir.r5.utils.client.network; 002 003import okhttp3.Interceptor; 004import okhttp3.Request; 005import okhttp3.Response; 006import javax.annotation.Nonnull; 007 008import java.io.IOException; 009 010/** 011 * An {@link Interceptor} for {@link okhttp3.OkHttpClient} that controls the number of times we retry a to execute a 012 * given request, before reporting a failure. This includes unsuccessful return codes and timeouts. 013 */ 014public class RetryInterceptor implements Interceptor { 015 016 // Delay between retying failed requests, in millis 017 private final long RETRY_TIME = 2000; 018 019 // Maximum number of times to retry the request before failing 020 private final int maxRetry; 021 022 // Internal counter for tracking the number of times we've tried this request 023 private int retryCounter = 0; 024 025 public RetryInterceptor(int maxRetry) { 026 this.maxRetry = maxRetry; 027 } 028 029 @Override 030 public Response intercept(Interceptor.Chain chain) throws IOException { 031 Request request = chain.request(); 032 Response response = null; 033 034 do { 035 try { 036 // If we are retrying a failed request that failed due to a bad response from the server, we must close it first 037 if (response != null) { 038// System.out.println("Previous " + chain.request().method() + " attempt returned HTTP<" + (response.code()) 039// + "> from url -> " + chain.request().url() + "."); 040 response.close(); 041 } 042 // System.out.println(chain.request().method() + " attempt <" + (retryCounter + 1) + "> to url -> " + chain.request().url()); 043 response = chain.proceed(request); 044 } catch (IOException e) { 045 try { 046 // Include a small break in between requests. 047 Thread.sleep(RETRY_TIME); 048 } catch (InterruptedException e1) { 049 System.out.println(chain.request().method() + " to url -> " + chain.request().url() + " interrupted on try <" + retryCounter + ">"); 050 } 051 } finally { 052 retryCounter++; 053 } 054 } while ((response == null || !response.isSuccessful()) && (retryCounter <= maxRetry + 1)); 055 056 /* 057 * if something has gone wrong, and we are unable to complete the request, we still need to initialize the return 058 * response so we don't get a null pointer exception. 059 */ 060 return response != null ? response : chain.proceed(request); 061 } 062 063}