001package org.hl7.fhir.r4.utils.client.network; 002 003import java.io.IOException; 004 005import okhttp3.Interceptor; 006import okhttp3.Request; 007import okhttp3.Response; 008 009/** 010 * An {@link Interceptor} for {@link okhttp3.OkHttpClient} that controls the 011 * number of times we retry a to execute a given request, before reporting a 012 * 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 037 // the server, we must close it first 038 if (response != null) { 039// System.out.println("Previous " + chain.request().method() + " attempt returned HTTP<" + (response.code()) 040// + "> from url -> " + chain.request().url() + "."); 041 response.close(); 042 } 043 // System.out.println(chain.request().method() + " attempt <" + (retryCounter + 044 // 1) + "> to url -> " + chain.request().url()); 045 response = chain.proceed(request); 046 } catch (IOException e) { 047 try { 048 // Include a small break in between requests. 049 Thread.sleep(RETRY_TIME); 050 } catch (InterruptedException e1) { 051 System.out.println(chain.request().method() + " to url -> " + chain.request().url() + " interrupted on try <" 052 + retryCounter + ">"); 053 } 054 } finally { 055 retryCounter++; 056 } 057 } while ((response == null || !response.isSuccessful()) && (retryCounter <= maxRetry + 1)); 058 059 /* 060 * if something has gone wrong, and we are unable to complete the request, we 061 * still need to initialize the return response so we don't get a null pointer 062 * exception. 063 */ 064 return response != null ? response : chain.proceed(request); 065 } 066 067}