Add support for configurations in Felix .config format

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1600865 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 6617f3f..137fcd3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -157,5 +157,11 @@
             <version>4.1</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+            <scope>test</scope>
+        </dependency>
       </dependencies>
 </project>
diff --git a/src/test/java/org/apache/sling/crankstart/launcher/CrankstartBootstrapTest.java b/src/test/java/org/apache/sling/crankstart/launcher/CrankstartBootstrapTest.java
index 9c91184..c0d7f0d 100644
--- a/src/test/java/org/apache/sling/crankstart/launcher/CrankstartBootstrapTest.java
+++ b/src/test/java/org/apache/sling/crankstart/launcher/CrankstartBootstrapTest.java
@@ -3,6 +3,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.File;
@@ -13,11 +14,18 @@
 import java.net.ServerSocket;
 import java.util.Random;
 
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
 import org.apache.sling.commons.testing.junit.Retry;
 import org.apache.sling.commons.testing.junit.RetryRule;
 import org.junit.AfterClass;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
@@ -28,7 +36,7 @@
 public class CrankstartBootstrapTest {
     
     private static final int port = getAvailablePort();
-    private static final HttpClient client = new HttpClient();
+    private static DefaultHttpClient client;
     private static Thread crankstartThread;
     private static String baseUrl = "http://localhost:" + port;
     public static final String TEST_RESOURCE = "/launcher-test.crank.txt";
@@ -55,6 +63,18 @@
         return result;
     }
     
+    @Before
+    public void setupHttpClient() {
+        client = new DefaultHttpClient(); 
+    }
+    
+    private void setAdminCredentials() {
+        client.getCredentialsProvider().setCredentials(
+                AuthScope.ANY, 
+                new UsernamePasswordCredentials("admin", "admin"));
+        client.addRequestInterceptor(new PreemptiveAuthInterceptor(), 0);
+    }
+    
     @BeforeClass
     public static void testExtensionPropertyBeforeTests() {
         assertNull(TEST_SYSTEM_PROPERTY + " should not be set before tests", System.getProperty(TEST_SYSTEM_PROPERTY));
@@ -62,7 +82,8 @@
     
     @BeforeClass
     public static void setup() {
-        final GetMethod get = new GetMethod(baseUrl);
+        client = new DefaultHttpClient(); 
+        final HttpUriRequest get = new HttpGet(baseUrl);
         System.setProperty("http.port", String.valueOf(port));
         System.setProperty("osgi.storage.path", getOsgiStoragePath());
         
@@ -71,7 +92,7 @@
         final Reader input = new InputStreamReader(is);
         
         try {
-            client.executeMethod(get);
+            client.execute(get);
             fail("Expecting connection to " + port + " to fail before starting HTTP service");
         } catch(IOException expected) {
         }
@@ -101,20 +122,36 @@
         crankstartThread.join();
     }
     
+    private void closeConnection(HttpResponse r) throws IOException {
+        if(r != null && r.getEntity() != null) {
+            EntityUtils.consume(r.getEntity());
+        }
+    }
+    
     @Test
     @Retry(timeoutMsec=10000, intervalMsec=250)
     public void testHttpRoot() throws Exception {
-        final GetMethod get = new GetMethod(baseUrl);
-        client.executeMethod(get);
-        assertEquals("Expecting page not found at " + get.getURI(), 404, get.getStatusCode());
+        final HttpUriRequest get = new HttpGet(baseUrl);
+        HttpResponse response = null;
+        try {
+            response = client.execute(get);
+            assertEquals("Expecting page not found at " + get.getURI(), 404, response.getStatusLine().getStatusCode());
+        } finally {
+            closeConnection(response);
+        }
     }
     
     @Test
     @Retry(timeoutMsec=10000, intervalMsec=250)
     public void testSingleConfigServlet() throws Exception {
-        final GetMethod get = new GetMethod(baseUrl + "/single");
-        client.executeMethod(get);
-        assertEquals("Expecting success for " + get.getURI(), 200, get.getStatusCode());
+        final HttpUriRequest get = new HttpGet(baseUrl + "/single");
+        HttpResponse response = null;
+        try {
+            response = client.execute(get);
+            assertEquals("Expecting success for " + get.getURI(), 200, response.getStatusLine().getStatusCode());
+        } finally {
+            closeConnection(response);
+        }
     }
     
     @Test
@@ -122,9 +159,14 @@
     public void testConfigFactoryServlet() throws Exception {
         final String [] paths = { "/foo", "/bar/test" };
         for(String path : paths) {
-            final GetMethod get = new GetMethod(baseUrl + path);
-            client.executeMethod(get);
-            assertEquals("Expecting success for " + get.getURI(), 200, get.getStatusCode());
+            final HttpUriRequest get = new HttpGet(baseUrl + path);
+            HttpResponse response = null;
+            try {
+                response = client.execute(get);
+                assertEquals("Expecting success for " + get.getURI(), 200, response.getStatusLine().getStatusCode());
+            } finally {
+                closeConnection(response);
+            }
         }
     }
     
@@ -139,9 +181,42 @@
     @Retry(timeoutMsec=10000, intervalMsec=250)
     public void testJUnitServlet() throws Exception {
         final String path = "/system/sling/junit";
-        final GetMethod get = new GetMethod(baseUrl + path);
-        client.executeMethod(get);
-        assertEquals("Expecting JUnit servlet to be installed via sling extension command, at " + get.getURI(), 200, get.getStatusCode());
+        final HttpUriRequest get = new HttpGet(baseUrl + path);
+        HttpResponse response = null;
+        try {
+            response = client.execute(get);
+            assertEquals("Expecting JUnit servlet to be installed via sling extension command, at " + get.getURI(), 200, response.getStatusLine().getStatusCode());
+        } finally {
+            closeConnection(response);
+        }
+    }
+    
+    @Test
+    @Retry(timeoutMsec=10000, intervalMsec=250)
+    public void testFelixFormatConfig() throws Exception {
+        setAdminCredentials();
+        final String path = "/system/console/config/configuration-status-20140606-1347+0200.txt";
+        final HttpUriRequest get = new HttpGet(baseUrl + path);
+        HttpResponse response = null;
+        try {
+            response = client.execute(get);
+            assertEquals("Expecting config dump to be available at " + get.getURI(), 200, response.getStatusLine().getStatusCode());
+            assertNotNull("Expecting response entity", response.getEntity());
+            String encoding = "UTF-8";
+            if(response.getEntity().getContentEncoding() != null) {
+                encoding = response.getEntity().getContentEncoding().getValue();
+            }
+            final String content = IOUtils.toString(response.getEntity().getContent(), encoding);
+            final String [] expected = new String[] {
+                    "array = [foo, bar.from.launcher.test]",
+                    "service.ranking.launcher.test = 54321"
+            };
+            for(String exp : expected) {
+                assertTrue("Expecting config content to contain " + exp, content.contains(exp));
+            }
+        } finally {
+            closeConnection(response);
+        }
     }
     
     private static String getOsgiStoragePath() {
@@ -154,4 +229,4 @@
         tmpFolder.deleteOnExit();
         return tmpFolder.getAbsolutePath();
     }
-}
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/crankstart/launcher/PreemptiveAuthInterceptor.java b/src/test/java/org/apache/sling/crankstart/launcher/PreemptiveAuthInterceptor.java
new file mode 100644
index 0000000..5e82a54
--- /dev/null
+++ b/src/test/java/org/apache/sling/crankstart/launcher/PreemptiveAuthInterceptor.java
@@ -0,0 +1,41 @@
+package org.apache.sling.crankstart.launcher;
+
+import java.io.IOException;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.AuthState;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+
+/** It's not like httpclient 4.1 makes this simple... */
+class PreemptiveAuthInterceptor implements HttpRequestInterceptor {
+
+    public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
+
+        AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
+        CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
+        HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+
+        // If not auth scheme has been initialized yet
+        if (authState.getAuthScheme() == null) {
+            AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());
+
+            // Obtain credentials matching the target host
+            Credentials creds = credsProvider.getCredentials(authScope);
+
+            // If found, generate BasicScheme preemptively
+            if (creds != null) {
+                authState.setAuthScheme(new BasicScheme());
+                authState.setCredentials(creds);
+            }
+        }
+    }
+}
diff --git a/src/test/resources/launcher-test.crank.txt b/src/test/resources/launcher-test.crank.txt
index 8bc7b3b..6376370 100644
--- a/src/test/resources/launcher-test.crank.txt
+++ b/src/test/resources/launcher-test.crank.txt
@@ -57,6 +57,12 @@
   path=/bar/test
   message=Not used
   
+# Test Felix format configs
+config felix.format.test FORMAT:felix.config
+  mongouri="mongodb://localhost:27017"
+  service.ranking.launcher.test=I"54321"
+  array=["foo","bar.from.launcher.test"]
+  
 # Test an extension command provided by our test-services bundle
 test.system.property the.test.system.property was set by test-services bundle