SLING-4280 - Enable dumping of remote server logs in case of test failures

- Commons Testing - Added a new class TestInfoPassingClient which passes Sling test related headers (MDC keys starting with X-Sling) to outgoing request. Also used by HttpTestBase
 - Junit Core - Exposed a TestLogServlet to capture server side logs for test being executed
 - Testing Tools - Added RemoteLogDumper rule which connects to remote server and obtains the server logs and then dump them to system err stream upon failure. Also added a TestDescriptionInterceptor
 - integration-test - Modified the dependency to use logback as it supports MDC

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1651751 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/commons/testing/integration/HttpTestBase.java b/src/main/java/org/apache/sling/commons/testing/integration/HttpTestBase.java
index 51ab614..d0ab076 100644
--- a/src/main/java/org/apache/sling/commons/testing/integration/HttpTestBase.java
+++ b/src/main/java/org/apache/sling/commons/testing/integration/HttpTestBase.java
@@ -109,7 +109,7 @@
         public TestNode(String parentPath, Map<String, String> properties) throws IOException {
             super(testClient, parentPath, properties);
         }
-    };
+    }
 
     public static String removeEndingSlash(String str) {
         if(str != null && str.endsWith("/")) {
@@ -153,7 +153,7 @@
         }
 
         // setup HTTP client, with authentication (using default Jackrabbit credentials)
-        httpClient = new HttpClient();
+        httpClient = new TestInfoPassingClient();
         httpClient.getParams().setAuthenticationPreemptive(true);
         Credentials defaultcreds = getDefaultCredentials();
         httpClient.getState().setCredentials(new AuthScope(url.getHost(), url.getPort(), AuthScope.ANY_REALM), defaultcreds);
diff --git a/src/main/java/org/apache/sling/commons/testing/integration/TestInfoPassingClient.java b/src/main/java/org/apache/sling/commons/testing/integration/TestInfoPassingClient.java
new file mode 100644
index 0000000..314e33b
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/testing/integration/TestInfoPassingClient.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.commons.testing.integration;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.commons.httpclient.HostConfiguration;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpState;
+import org.slf4j.MDC;
+
+/**
+ * HttpClient extension which also passes test related headers as part
+ * of outgoing HTTP request
+ */
+public class TestInfoPassingClient extends HttpClient {
+    //Defined in org.apache.sling.testing.tools.junit.TestLogRule
+    private static final String SLING_HEADER_PREFIX = "X-Sling-";
+
+    @Override
+    public int executeMethod(HostConfiguration hostconfig, HttpMethod method,
+                             HttpState state) throws IOException {
+        addSlingHeaders(method);
+        return super.executeMethod(hostconfig, method, state);
+    }
+
+    /**
+     * Adds all MDC key-value pairs as HTTP header where the key starts
+     * with 'X-Sling-'
+     */
+    private static void addSlingHeaders(HttpMethod m){
+        Map<?,?> mdc = MDC.getCopyOfContextMap();
+        if (mdc != null) {
+            for (Map.Entry<?, ?> e : mdc.entrySet()) {
+                Object key = e.getKey();
+                if (key instanceof String
+                        && ((String)key).startsWith(SLING_HEADER_PREFIX)
+                        && e.getValue() instanceof String) {
+                    m.addRequestHeader((String) key, (String) e.getValue());
+                }
+            }
+        }
+    }
+}