001 002package io.vrap.rmf.base.client.http; 003 004import static io.vrap.rmf.base.client.http.HttpStatusCode.INTERNAL_SERVER_ERROR_500; 005import static io.vrap.rmf.base.client.http.HttpStatusCode.SERVICE_UNAVAILABLE_503; 006import static java.util.Arrays.asList; 007 008import java.util.List; 009import java.util.concurrent.ExecutorService; 010import java.util.concurrent.ScheduledExecutorService; 011 012import io.vrap.rmf.base.client.ApiHttpException; 013 014import dev.failsafe.spi.Scheduler; 015 016/** 017 * Middleware for retrying of a requests upon configured response status codes and/or exceptions 018 */ 019public interface RetryRequestMiddleware extends Middleware { 020 int DEFAULT_MAX_DELAY = 60000; 021 int DEFAULT_INITIAL_DELAY = 200; 022 List<Integer> DEFAULT_RETRY_STATUS_CODES = asList(INTERNAL_SERVER_ERROR_500, SERVICE_UNAVAILABLE_503); 023 024 public static RetryRequestMiddleware of(final int maxRetries) { 025 return new RetryMiddleware(maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, DEFAULT_RETRY_STATUS_CODES, 026 null); 027 } 028 029 public static RetryRequestMiddleware of(final int maxRetries, final List<Integer> statusCodes) { 030 return new RetryMiddleware(maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, statusCodes, null); 031 } 032 033 public static RetryRequestMiddleware of(final int maxRetries, final List<Integer> statusCodes, 034 final List<Class<? extends Throwable>> failures) { 035 return new RetryMiddleware(maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, statusCodes, failures); 036 } 037 038 public static RetryRequestMiddleware of(final int maxRetries, final long delay, final long maxDelay) { 039 return new RetryMiddleware(maxRetries, delay, maxDelay, DEFAULT_RETRY_STATUS_CODES, null); 040 } 041 042 public static RetryRequestMiddleware of(final int maxRetries, final long delay, final long maxDelay, 043 final List<Integer> statusCodes) { 044 return new RetryMiddleware(maxRetries, delay, maxDelay, statusCodes, null); 045 } 046 047 public static RetryRequestMiddleware of(final int maxRetries, final long delay, final long maxDelay, 048 final List<Integer> statusCodes, final List<Class<? extends Throwable>> failures) { 049 return new RetryMiddleware(maxRetries, delay, maxDelay, 050 handleFailures(failures).andThen(handleStatusCodes(statusCodes))); 051 } 052 053 public static RetryRequestMiddleware of(final int maxRetries, final long delay, final long maxDelay, 054 final FailsafeRetryPolicyBuilderOptions fn) { 055 return new RetryMiddleware(maxRetries, delay, maxDelay, fn); 056 } 057 058 public static RetryRequestMiddleware of(final Scheduler scheduler, final int maxRetries) { 059 return new RetryMiddleware(scheduler, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, 060 DEFAULT_RETRY_STATUS_CODES, null); 061 } 062 063 public static RetryRequestMiddleware of(final Scheduler scheduler, final int maxRetries, 064 final List<Integer> statusCodes) { 065 return new RetryMiddleware(scheduler, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, statusCodes, null); 066 } 067 068 public static RetryRequestMiddleware of(final Scheduler scheduler, final int maxRetries, 069 final List<Integer> statusCodes, final List<Class<? extends Throwable>> failures) { 070 return new RetryMiddleware(scheduler, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, statusCodes, 071 failures); 072 } 073 074 public static RetryRequestMiddleware of(final Scheduler scheduler, final int maxRetries, final long delay, 075 final long maxDelay) { 076 return new RetryMiddleware(scheduler, maxRetries, delay, maxDelay, DEFAULT_RETRY_STATUS_CODES, null); 077 } 078 079 public static RetryRequestMiddleware of(final Scheduler scheduler, final int maxRetries, final long delay, 080 final long maxDelay, final List<Integer> statusCodes) { 081 return new RetryMiddleware(scheduler, maxRetries, delay, maxDelay, statusCodes, null); 082 } 083 084 public static RetryRequestMiddleware of(final Scheduler scheduler, final int maxRetries, final long delay, 085 final long maxDelay, final List<Integer> statusCodes, final List<Class<? extends Throwable>> failures) { 086 return new RetryMiddleware(scheduler, maxRetries, delay, maxDelay, 087 handleFailures(failures).andThen(handleStatusCodes(statusCodes))); 088 } 089 090 public static RetryRequestMiddleware of(final Scheduler scheduler, final int maxRetries, final long delay, 091 final long maxDelay, final FailsafeRetryPolicyBuilderOptions fn) { 092 return new RetryMiddleware(scheduler, maxRetries, delay, maxDelay, fn); 093 } 094 095 public static RetryRequestMiddleware of(final ScheduledExecutorService executorService, final int maxRetries) { 096 return new RetryMiddleware(executorService, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, 097 DEFAULT_RETRY_STATUS_CODES, null); 098 } 099 100 public static RetryRequestMiddleware of(final ScheduledExecutorService executorService, final int maxRetries, 101 final List<Integer> statusCodes) { 102 return new RetryMiddleware(executorService, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, statusCodes, 103 null); 104 } 105 106 public static RetryRequestMiddleware of(final ScheduledExecutorService executorService, final int maxRetries, 107 final List<Integer> statusCodes, final List<Class<? extends Throwable>> failures) { 108 return new RetryMiddleware(executorService, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, statusCodes, 109 failures); 110 } 111 112 public static RetryRequestMiddleware of(final ScheduledExecutorService executorService, final int maxRetries, 113 final long delay, final long maxDelay) { 114 return new RetryMiddleware(executorService, maxRetries, delay, maxDelay, DEFAULT_RETRY_STATUS_CODES, null); 115 } 116 117 public static RetryRequestMiddleware of(final ScheduledExecutorService executorService, final int maxRetries, 118 final long delay, final long maxDelay, final List<Integer> statusCodes) { 119 return new RetryMiddleware(executorService, maxRetries, delay, maxDelay, statusCodes, null); 120 } 121 122 public static RetryRequestMiddleware of(final ScheduledExecutorService executorService, final int maxRetries, 123 final long delay, final long maxDelay, final List<Integer> statusCodes, 124 final List<Class<? extends Throwable>> failures) { 125 return new RetryMiddleware(executorService, maxRetries, delay, maxDelay, 126 handleFailures(failures).andThen(handleStatusCodes(statusCodes))); 127 } 128 129 public static RetryRequestMiddleware of(final ScheduledExecutorService executorService, final int maxRetries, 130 final long delay, final long maxDelay, final FailsafeRetryPolicyBuilderOptions fn) { 131 return new RetryMiddleware(executorService, maxRetries, delay, maxDelay, fn); 132 } 133 134 public static RetryRequestMiddleware of(final ExecutorService executorService, final int maxRetries) { 135 return new RetryMiddleware(executorService, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, 136 DEFAULT_RETRY_STATUS_CODES, null); 137 } 138 139 public static RetryRequestMiddleware of(final ExecutorService executorService, final int maxRetries, 140 final List<Integer> statusCodes) { 141 return new RetryMiddleware(executorService, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, statusCodes, 142 null); 143 } 144 145 public static RetryRequestMiddleware of(final ExecutorService executorService, final int maxRetries, 146 final List<Integer> statusCodes, final List<Class<? extends Throwable>> failures) { 147 return new RetryMiddleware(executorService, maxRetries, DEFAULT_INITIAL_DELAY, DEFAULT_MAX_DELAY, statusCodes, 148 failures); 149 } 150 151 public static RetryRequestMiddleware of(final ExecutorService executorService, final int maxRetries, 152 final long delay, final long maxDelay) { 153 return new RetryMiddleware(executorService, maxRetries, delay, maxDelay, DEFAULT_RETRY_STATUS_CODES, null); 154 } 155 156 public static RetryRequestMiddleware of(final ExecutorService executorService, final int maxRetries, 157 final long delay, final long maxDelay, final List<Integer> statusCodes) { 158 return new RetryMiddleware(executorService, maxRetries, delay, maxDelay, statusCodes, null); 159 } 160 161 public static RetryRequestMiddleware of(final ExecutorService executorService, final int maxRetries, 162 final long delay, final long maxDelay, final List<Integer> statusCodes, 163 final List<Class<? extends Throwable>> failures) { 164 return new RetryMiddleware(executorService, maxRetries, delay, maxDelay, 165 handleFailures(failures).andThen(handleStatusCodes(statusCodes))); 166 } 167 168 public static RetryRequestMiddleware of(final ExecutorService executorService, final int maxRetries, 169 final long delay, final long maxDelay, final FailsafeRetryPolicyBuilderOptions fn) { 170 return new RetryMiddleware(executorService, maxRetries, delay, maxDelay, fn); 171 } 172 173 public static FailsafeRetryPolicyBuilderOptions handleFailures(final List<Class<? extends Throwable>> failures) { 174 return builder -> { 175 if (failures != null) { 176 builder.handle(failures); 177 } 178 return builder; 179 }; 180 } 181 182 public static FailsafeRetryPolicyBuilderOptions handleStatusCodes(final List<Integer> statusCodes) { 183 return builder -> builder.handleIf((response, throwable) -> { 184 if (throwable instanceof ApiHttpException) { 185 return statusCodes.contains(((ApiHttpException) throwable).getStatusCode()); 186 } 187 return statusCodes.contains(response.getStatusCode()); 188 }); 189 } 190}