SLING-9053 implementing retries
diff --git a/src/main/java/org/apache/sling/testing/clients/AbstractSlingClient.java b/src/main/java/org/apache/sling/testing/clients/AbstractSlingClient.java
index 2d3f70d..1087158 100644
--- a/src/main/java/org/apache/sling/testing/clients/AbstractSlingClient.java
+++ b/src/main/java/org/apache/sling/testing/clients/AbstractSlingClient.java
@@ -33,7 +33,6 @@
 import java.lang.reflect.Constructor;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -454,6 +453,12 @@
         return doStreamRequest(request, headers, expectedStatus);
     }
 
+    private boolean isServiceUnavailable(SlingHttpResponse response) {
+        StatusLine statusLine = response.getStatusLine();
+        return statusLine != null && statusLine.getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE;
+    }
+
+
     /**
      * <p>Execute an HTTP request and consumes the entity in the response. The content is cached and can be retrieved using
      * {@code response.getContent()}.
@@ -468,10 +473,33 @@
      * @throws ClientException if the request could not be executed
      */
     public  SlingHttpResponse doRequest(HttpUriRequest request, List<Header> headers, int... expectedStatus) throws ClientException {
-        SlingHttpResponse response = doStreamRequest(request, headers, expectedStatus);
+        int maxRetries = Constants.HTTP_RETRIES;
+        boolean needRetry = false;
+        SlingHttpResponse response = null;
+        do {
+            try {
+                if (needRetry) {
+                    // add some pacing
+                    Thread.sleep(Constants.HTTP_RETRIES_DELAY);
+                }
+                response = doStreamRequest(request, headers, expectedStatus);
+                needRetry = maxRetries > 0 && isServiceUnavailable(response);
+                // Consume entity and cache the content so the connection is closed
+                response.getContent();
+            } catch (ClientException | RuntimeException ex ) {
+                needRetry = ex.getMessage().contains("Could not read content from response")
+                        || ex.getMessage().contains("Instead 503 was returned!");
 
-        // Consume entity and cache the content so the connection is closed
-        response.getContent();
+                if (needRetry) {
+                    log.warn("Retry needed due to " + ex.getMessage());
+                }
+                if (maxRetries == 0) {
+                    throw ex;
+                }
+            } catch (InterruptedException ex) {
+                throw new ClientException("Interrupted while pacing request", ex);
+            }
+       } while (needRetry && maxRetries-- > 0);
 
         return response;
     }
diff --git a/src/main/java/org/apache/sling/testing/clients/Constants.java b/src/main/java/org/apache/sling/testing/clients/Constants.java
index 3e7ce66..d7dd8e5 100644
--- a/src/main/java/org/apache/sling/testing/clients/Constants.java
+++ b/src/main/java/org/apache/sling/testing/clients/Constants.java
@@ -28,11 +28,21 @@
 
     // Custom delay for requests
     private static long delay;
+
+    // Custom number of retries for failing requests
+    private static int retries;
+
+    // Custom delay between retries in millisec
+    private static long retriesDelay;
     static {
         try {
             Constants.delay = Long.getLong(Constants.CONFIG_PROP_PREFIX + "http.delay", 0);
+            Constants.retries = Integer.getInteger(Constants.CONFIG_PROP_PREFIX + "http.retries", 0);
+            Constants.retriesDelay = Long.getLong(Constants.CONFIG_PROP_PREFIX + "http.retriesDelay", 1000);
         } catch (NumberFormatException e) {
             Constants.delay = 0;
+            Constants.retries = 5;
+            Constants.retriesDelay = 1000;
         }
     }
 
@@ -43,6 +53,18 @@
     public static final long HTTP_DELAY = delay;
 
     /**
+     * Custom number of retries after an HTTP request failed due to 503 or any broken connection issues.
+     * Used by {@link org.apache.sling.testing.clients.AbstractSlingClient}
+     */
+    public static final int HTTP_RETRIES = retries;
+
+    /**
+     * Custom delay in milliseconds between each retries, default to 1000 milliseconds.
+     * Used by {@link org.apache.sling.testing.clients.AbstractSlingClient}
+     */
+    public static final long HTTP_RETRIES_DELAY = retriesDelay;
+
+    /**
      * Handle to OSGI console
      */
     public static final String OSGI_CONSOLE = "/system/console";
diff --git a/src/main/java/org/apache/sling/testing/clients/package-info.java b/src/main/java/org/apache/sling/testing/clients/package-info.java
index c3e99df..df6de91 100644
--- a/src/main/java/org/apache/sling/testing/clients/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("1.5.0")
+@Version("1.6.0")
 package org.apache.sling.testing.clients;
 
 import org.osgi.annotation.versioning.Version;