You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ja...@apache.org on 2012/04/23 14:15:06 UTC

svn commit: r1329199 [4/5] - in /ace/trunk: ./ ace-authenticationprocessor-basicauth/src/main/java/org/apache/ace/authenticationprocessor/basicauth/ ace-client-automation/src/main/java/org/apache/ace/client/automation/ ace-client-repository-api/src/mai...

Modified: ace/trunk/ace-integrationtests/src/test/java/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-integrationtests/src/test/java/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-integrationtests/src/test/java/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java (original)
+++ ace/trunk/ace-integrationtests/src/test/java/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java Mon Apr 23 12:15:01 2012
@@ -18,17 +18,87 @@
  */
 package org.apache.ace.it.repositoryadmin;
 
-import org.apache.ace.client.repository.*;
+import static org.apache.ace.client.repository.RepositoryObject.PRIVATE_TOPIC_ROOT;
+import static org.apache.ace.client.repository.RepositoryObject.PUBLIC_TOPIC_ROOT;
+import static org.apache.ace.client.repository.stateful.StatefulTargetObject.KEY_ID;
+import static org.apache.ace.client.repository.stateful.StatefulTargetObject.KEY_REGISTRATION_STATE;
+import static org.apache.ace.client.repository.stateful.StatefulTargetObject.TOPIC_ADDED;
+import static org.apache.ace.client.repository.stateful.StatefulTargetObject.TOPIC_ALL;
+import static org.apache.ace.client.repository.stateful.StatefulTargetObject.TOPIC_REMOVED;
+import static org.apache.ace.client.repository.stateful.StatefulTargetObject.TOPIC_STATUS_CHANGED;
+import static org.apache.ace.client.repository.stateful.StatefulTargetObject.UNKNOWN_VERSION;
+import static org.apache.ace.it.Options.jetty;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.jar.Attributes;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import junit.framework.Assert;
+
+import org.apache.ace.client.repository.ObjectRepository;
+import org.apache.ace.client.repository.RepositoryAdmin;
+import org.apache.ace.client.repository.RepositoryAdminLoginContext;
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.RepositoryObject.WorkingState;
+import org.apache.ace.client.repository.SessionFactory;
 import org.apache.ace.client.repository.helper.ArtifactHelper;
 import org.apache.ace.client.repository.helper.ArtifactPreprocessor;
 import org.apache.ace.client.repository.helper.PropertyResolver;
 import org.apache.ace.client.repository.helper.bundle.BundleHelper;
-import org.apache.ace.client.repository.object.*;
-import org.apache.ace.client.repository.repository.*;
+import org.apache.ace.client.repository.object.Artifact2FeatureAssociation;
+import org.apache.ace.client.repository.object.ArtifactObject;
+import org.apache.ace.client.repository.object.DeploymentArtifact;
+import org.apache.ace.client.repository.object.DeploymentVersionObject;
+import org.apache.ace.client.repository.object.Distribution2TargetAssociation;
+import org.apache.ace.client.repository.object.DistributionObject;
+import org.apache.ace.client.repository.object.Feature2DistributionAssociation;
+import org.apache.ace.client.repository.object.FeatureObject;
+import org.apache.ace.client.repository.object.TargetObject;
+import org.apache.ace.client.repository.repository.Artifact2FeatureAssociationRepository;
+import org.apache.ace.client.repository.repository.ArtifactRepository;
+import org.apache.ace.client.repository.repository.DeploymentVersionRepository;
+import org.apache.ace.client.repository.repository.Distribution2TargetAssociationRepository;
+import org.apache.ace.client.repository.repository.DistributionRepository;
+import org.apache.ace.client.repository.repository.Feature2DistributionAssociationRepository;
+import org.apache.ace.client.repository.repository.FeatureRepository;
+import org.apache.ace.client.repository.repository.TargetRepository;
 import org.apache.ace.client.repository.stateful.StatefulTargetObject;
+import org.apache.ace.client.repository.stateful.StatefulTargetObject.ProvisioningState;
+import org.apache.ace.client.repository.stateful.StatefulTargetObject.RegistrationState;
+import org.apache.ace.client.repository.stateful.StatefulTargetObject.StoreState;
 import org.apache.ace.client.repository.stateful.StatefulTargetRepository;
 import org.apache.ace.http.listener.constants.HttpConstants;
 import org.apache.ace.it.IntegrationTestBase;
+import org.apache.ace.it.Options.Ace;
+import org.apache.ace.it.Options.Felix;
+import org.apache.ace.it.Options.Knopflerfish;
+import org.apache.ace.it.Options.Osgi;
 import org.apache.ace.log.AuditEvent;
 import org.apache.ace.log.LogEvent;
 import org.apache.ace.obr.storage.file.constants.OBRFileStoreConstants;
@@ -57,27 +127,6 @@ import org.osgi.service.http.HttpService
 import org.osgi.service.useradmin.User;
 import org.osgi.util.tracker.ServiceTracker;
 
-import java.io.*;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.jar.Attributes;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-
-import junit.framework.Assert;
-
-import static org.apache.ace.client.repository.RepositoryObject.PRIVATE_TOPIC_ROOT;
-import static org.apache.ace.client.repository.RepositoryObject.PUBLIC_TOPIC_ROOT;
-import static org.apache.ace.client.repository.RepositoryObject.WorkingState;
-import static org.apache.ace.client.repository.stateful.StatefulTargetObject.*;
-import static org.apache.ace.it.Options.*;
-import static org.ops4j.pax.exam.CoreOptions.*;
-
 @RunWith(JUnit4TestRunner.class)
 public class RepositoryAdminTest extends IntegrationTestBase implements EventHandler {
 
@@ -97,6 +146,8 @@ public class RepositoryAdminTest extends
                 Knopflerfish.useradmin(),
                 Knopflerfish.log(),
                 Ace.util(),
+                Ace.authenticationApi(),
+                Ace.connectionFactory(),
                 Ace.rangeApi(),
                 Ace.log(),
                 Ace.serverLogStore(),
@@ -120,7 +171,7 @@ public class RepositoryAdminTest extends
     protected void before() throws IOException {
         getService(SessionFactory.class).createSession("test-session-ID");
         configureFactory("org.apache.ace.server.log.store.factory",
-            "name", "auditlog");
+            "name", "auditlog", "authentication.enabled", "false");
     }
 
     protected Component[] getDependencies() {
@@ -352,8 +403,11 @@ public class RepositoryAdminTest extends
         }
 
         final RepositoryAdminLoginContext loginContext1 = m_repositoryAdmin.createLoginContext(user1);
-        loginContext1.addShopRepository(new URL(HOST + ENDPOINT), "apache", "store", true);
-        loginContext1.addTargetRepository(new URL(HOST + ENDPOINT), "apache", "target", true);
+        loginContext1
+            .add(loginContext1.createShopRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("store").setWriteable())
+            .add(loginContext1.createTargetRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("target").setWriteable());
         m_repositoryAdmin.login(loginContext1);
 
         assert !m_repositoryAdmin.isCurrent() : "When first logging in without checking out, the repository cannot be current.";
@@ -440,8 +494,11 @@ public class RepositoryAdminTest extends
         cleanUp();
 
         final RepositoryAdminLoginContext loginContext2 = m_repositoryAdmin.createLoginContext(user2);
-        loginContext2.addShopRepository(new URL(HOST + ENDPOINT), "apache", "store", true);
-        loginContext2.addTargetRepository(new URL(HOST + ENDPOINT), "apache", "target", true);
+        loginContext2
+            .add(loginContext2.createShopRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("store").setWriteable())
+            .add(loginContext2.createTargetRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("target").setWriteable());
 
         runAndWaitForEvent(new Callable<Object>() {
             public Object call() throws Exception {
@@ -550,9 +607,14 @@ public class RepositoryAdminTest extends
         addRepository("deploymentInstance", "apache", "deployment", true);
 
         RepositoryAdminLoginContext loginContext = m_repositoryAdmin.createLoginContext(user);
-        loginContext.addShopRepository(new URL(HOST + ENDPOINT), "apache", "store", true);
-        loginContext.addTargetRepository(new URL(HOST + ENDPOINT), "apache", "target", true);
-        loginContext.addDeploymentRepository(new URL(HOST + ENDPOINT), "apache", "deployment", true);
+        loginContext
+            .add(loginContext.createShopRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("store").setWriteable())
+            .add(loginContext.createTargetRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("target").setWriteable())
+            .add(loginContext.createDeploymentRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("deployment").setWriteable());
+
         m_repositoryAdmin.login(loginContext);
 
         runAndWaitForEvent(new Callable<Object>() {
@@ -635,9 +697,14 @@ public class RepositoryAdminTest extends
         addRepository("deploymentInstance", "apache", "deployment", true);
 
         RepositoryAdminLoginContext loginContext = m_repositoryAdmin.createLoginContext(user);
-        loginContext.addShopRepository(new URL(HOST + ENDPOINT), "apache", "store", true);
-        loginContext.addTargetRepository(new URL(HOST + ENDPOINT), "apache", "target", true);
-        loginContext.addDeploymentRepository(new URL(HOST + ENDPOINT), "apache", "deployment", true);
+        loginContext
+            .add(loginContext.createShopRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("store").setWriteable())
+            .add(loginContext.createTargetRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("target").setWriteable())
+            .add(loginContext.createDeploymentRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("deployment").setWriteable());
+
         m_repositoryAdmin.login(loginContext);
 
         /*
@@ -1545,9 +1612,8 @@ public class RepositoryAdminTest extends
             m_name = name;
         }
 
-        @SuppressWarnings("unchecked")
         public Dictionary getCredentials() {
-            return null;
+            return new Properties();
         }
 
         public boolean hasCredential(String arg0, Object arg1) {
@@ -1558,9 +1624,8 @@ public class RepositoryAdminTest extends
             return m_name;
         }
 
-        @SuppressWarnings("unchecked")
         public Dictionary getProperties() {
-            return null;
+            return new Properties();
         }
 
         public int getType() {
@@ -1579,8 +1644,12 @@ public class RepositoryAdminTest extends
         addRepository("targetInstance", "apache", "target", true);
 
         final RepositoryAdminLoginContext loginContext1 = m_repositoryAdmin.createLoginContext(user1);
-        loginContext1.addShopRepository(new URL(HOST + ENDPOINT), "apache", "store", true);
-        loginContext1.addTargetRepository(new URL(HOST + ENDPOINT), "apache", "target", true);
+        loginContext1
+            .add(loginContext1.createShopRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("store").setWriteable())
+            .add(loginContext1.createTargetRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("target").setWriteable());
+
         m_repositoryAdmin.login(loginContext1);
 
         FeatureObject g1 = createBasicFeatureObject("feature1");
@@ -1614,8 +1683,12 @@ public class RepositoryAdminTest extends
         addRepository("targetInstance", "apache", "target", true);
 
         final RepositoryAdminLoginContext loginContext1 = m_repositoryAdmin.createLoginContext(user1);
-        loginContext1.addShopRepository(new URL(HOST + ENDPOINT), "apache", "store", true);
-        loginContext1.addTargetRepository(new URL(HOST + ENDPOINT), "apache", "target", false);
+        loginContext1
+            .add(loginContext1.createShopRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("store").setWriteable())
+            .add(loginContext1.createTargetRepositoryContext()
+                .setLocation(new URL(HOST + ENDPOINT)).setCustomer("apache").setName("target"));
+
         m_repositoryAdmin.login(loginContext1);
 
         m_repositoryAdmin.checkout();
@@ -1654,43 +1727,6 @@ public class RepositoryAdminTest extends
         }
     }
 
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testRepostoryLoginDoubleRepository() throws Exception {
-        RepositoryAdminLoginContext context = m_repositoryAdmin.createLoginContext(new MockUser("user"));
-        context.addRepositories(new URL("http://localhost:" + TestConstants.PORT), "apache", "shop", true,
-            ArtifactRepository.class, Artifact2FeatureAssociationRepository.class, FeatureRepository.class);
-        context.addRepositories(new URL("http://localhost:" + TestConstants.PORT), "apache", "deployment", true,
-            FeatureRepository.class, Feature2DistributionAssociationRepository.class, DistributionRepository.class);
-        try {
-            m_repositoryAdmin.login(context);
-            assert false : "We tried to log in with two repositories that try to access the same repository service; this should not be allowed.";
-        }
-        catch (IllegalArgumentException iae) {
-            // expected
-        }
-    }
-
-    private static interface newRepository extends ObjectRepository<DistributionObject> {
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testRepostoryLoginRepositoryWithoutImplementation() throws Exception {
-        RepositoryAdminLoginContext context = m_repositoryAdmin.createLoginContext(new MockUser("user"));
-        context.addRepositories(new URL("http://localhost:" + TestConstants.PORT), "apache", "shop", true,
-            ArtifactRepository.class, Artifact2FeatureAssociationRepository.class, FeatureRepository.class);
-        context.addRepositories(new URL("http://localhost:" + TestConstants.PORT), "apache", "deployment", true,
-            FeatureRepository.class, Feature2DistributionAssociationRepository.class, newRepository.class);
-        try {
-            m_repositoryAdmin.login(context);
-            assert false : "We tried to log in with a repository for which no implementation is available; this should not be allowed.";
-        }
-        catch (IllegalArgumentException iae) {
-            // expected
-        }
-    }
-
     /**
      * Tests the template processing mechanism: given a custom processor, do the correct calls go out?
      */
@@ -1773,7 +1809,7 @@ public class RepositoryAdminTest extends
 
         String noTemplate = "<Attribute content=\"http://someURL\"/>";
         String noTemplateProcessed = "<Attribute content=\"http://someURL\"/>";
-        final File noTemplateFile = createFileWithContents("template", "xml", xmlHeader + noTemplate + xmlFooter);
+        final File noTemplateFile = createFileWithContents("template", ".xml", xmlHeader + noTemplate + xmlFooter);
 
         String simpleTemplate = "<Attribute content=\"http://$context.name\"/>";
         String simpleTemplateProcessed = "<Attribute content=\"http://mydistribution\"/>";
@@ -2019,8 +2055,8 @@ public class RepositoryAdminTest extends
 
     protected void startRepositoryService() throws IOException {
         // configure the (replication)repository servlets
-        setProperty("org.apache.ace.repository.servlet.RepositoryServlet", new Object[][] { { HttpConstants.ENDPOINT,
-            ENDPOINT } });
+        configure("org.apache.ace.repository.servlet.RepositoryServlet", HttpConstants.ENDPOINT,
+            ENDPOINT, "authentication.enabled", "false");
     }
 
     @After
@@ -2054,20 +2090,9 @@ public class RepositoryAdminTest extends
         tracker.close();
     }
 
-    private void addObr(String endpoint, String fileLocation) throws IOException, InterruptedException,
-        InvalidSyntaxException {
-        Properties propsServlet = new Properties();
-        propsServlet.put(HttpConstants.ENDPOINT, endpoint);
-        propsServlet.put("OBRInstance", "singleOBRServlet");
-        Properties propsStore = new Properties();
-        propsStore.put(OBRFileStoreConstants.FILE_LOCATION_KEY, fileLocation);
-        propsStore.put("OBRInstance", "singleOBRStore");
-
-        Configuration configServlet = m_configAdmin.getConfiguration("org.apache.ace.obr.servlet", null);
-        Configuration configStore = m_configAdmin.getConfiguration("org.apache.ace.obr.storage.file", null);
-
-        configServlet.update(propsServlet);
-        configStore.update(propsStore);
+    private void addObr(String endpoint, String fileLocation) throws IOException, InterruptedException {
+        configure("org.apache.ace.obr.servlet", "OBRInstance", "singleOBRServlet", "org.apache.ace.server.servlet.endpoint", endpoint, "authentication.enabled", "false");
+        configure("org.apache.ace.obr.storage.file", "OBRInstance", "singleOBRStore", OBRFileStoreConstants.FILE_LOCATION_KEY, fileLocation);
 
         // Wait for the endpoint to respond.
         // TODO below there is a similar url that does put a slash between port and endpoint, why?
@@ -2137,21 +2162,6 @@ public class RepositoryAdminTest extends
             tracker.close();
         }
     }
-
-    /* Configure properties for the specified service PID */
-    @SuppressWarnings("unchecked")
-    private void setProperty(String pid, Object[][] props) throws IOException {
-        Configuration configuration = m_configAdmin.getConfiguration(pid, null);
-        Dictionary dictionary = configuration.getProperties();
-        if (dictionary == null) {
-            dictionary = new Hashtable();
-        }
-        for (Object[] pair : props) {
-            dictionary.put(pair[0], pair[1]);
-        }
-        configuration.update(dictionary);
-    }
-
 }
 
 class MockArtifactHelper implements ArtifactHelper {

Modified: ace/trunk/ace-integrationtests/src/test/java/org/apache/ace/it/useradminconfigurator/ConfiguratorTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-integrationtests/src/test/java/org/apache/ace/it/useradminconfigurator/ConfiguratorTest.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-integrationtests/src/test/java/org/apache/ace/it/useradminconfigurator/ConfiguratorTest.java (original)
+++ ace/trunk/ace-integrationtests/src/test/java/org/apache/ace/it/useradminconfigurator/ConfiguratorTest.java Mon Apr 23 12:15:01 2012
@@ -18,7 +18,23 @@
  */
 package org.apache.ace.it.useradminconfigurator;
 
+import static org.apache.ace.it.Options.jetty;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
 import org.apache.ace.it.IntegrationTestBase;
+import org.apache.ace.it.Options.Ace;
+import org.apache.ace.it.Options.Felix;
+import org.apache.ace.it.Options.Knopflerfish;
+import org.apache.ace.it.Options.Osgi;
 import org.apache.ace.repository.Repository;
 import org.apache.ace.repository.impl.constants.RepositoryConstants;
 import org.apache.ace.test.constants.TestConstants;
@@ -32,21 +48,13 @@ import org.ops4j.pax.exam.options.Wrappe
 import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-
-import static org.apache.ace.it.Options.*;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.ops4j.pax.exam.CoreOptions.*;
-
 @RunWith(JUnit4TestRunner.class)
 public class ConfiguratorTest extends IntegrationTestBase {
 
     @Configuration
     public Option[] configuration() {
         return options(
-            systemProperty("org.osgi.service.http.port").value("" + TestConstants.PORT),    
+            systemProperty("org.osgi.service.http.port").value("" + TestConstants.PORT),
             provision(
                 wrappedBundle(maven("org.apache.ace", "org.apache.ace.util")).overwriteManifest(WrappedUrlProvisionOption.OverwriteMode.FULL), // we do this because we need access to some test classes that aren't exported
                 Osgi.compendium(),
@@ -56,6 +64,8 @@ public class ConfiguratorTest extends In
                 Felix.configAdmin(),
                 Knopflerfish.useradmin(),
                 Knopflerfish.log(),
+                Ace.authenticationApi(),
+                Ace.connectionFactory(),
                 Ace.rangeApi(),
                 Ace.scheduler(),
                 Ace.httplistener(),
@@ -87,12 +97,9 @@ public class ConfiguratorTest extends In
                 RepositoryConstants.REPOSITORY_NAME, "users",
                 RepositoryConstants.REPOSITORY_CUSTOMER, "apache",
                 RepositoryConstants.REPOSITORY_MASTER, "true");
-        configure("org.apache.ace.repository.servlet.RepositoryServlet",
-                "org.apache.ace.server.servlet.endpoint", "/repository");
         configure("org.apache.ace.configurator.useradmin.task.UpdateUserAdminTask",
                 "repositoryName", "users",
-                "repositoryCustomer", "apache",
-                "repositoryLocation", "http://localhost:" + TestConstants.PORT + "/repository");
+                "repositoryCustomer", "apache");
         configure("org.apache.ace.scheduler",
                 "org.apache.ace.configurator.useradmin.task.UpdateUserAdminTask", "1000");
     }

Modified: ace/trunk/ace-launcher/src/main/java/org/apache/ace/launcher/Main.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-launcher/src/main/java/org/apache/ace/launcher/Main.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-launcher/src/main/java/org/apache/ace/launcher/Main.java (original)
+++ ace/trunk/ace-launcher/src/main/java/org/apache/ace/launcher/Main.java Mon Apr 23 12:15:01 2012
@@ -75,6 +75,19 @@ public class Main {
             return "agents: configures multiple management agents: agent-id,identification,discovery[;agent-id,identification,discovery]*";
         }
     };
+    
+    private Argument m_auth = new KeyValueArgument() {
+        @Override
+        protected void handle(String key, String value) {
+            if ("auth".equals(key)) {
+                System.setProperty("auth", value);
+            }
+        }
+        
+        public String getDescription() {
+            return "auth: point to the properties file containing the authentication credentials for a certain subsystem: <dir/file/url>";
+        }
+    };
 
     private Argument m_help = new Argument() {
         public void handle(String argument) {
@@ -88,7 +101,7 @@ public class Main {
             return "help: prints this help message";
         }
     };
-    
+
     private Argument m_additionalBundles = new KeyValueArgument() {
         public void handle(String key, String value) {
             if ("bundle".equals(key)) {
@@ -113,6 +126,7 @@ public class Main {
     private FrameworkOption m_fwOptionHandler = new FrameworkOption();
     
     private final List<Argument> m_arguments = Arrays.asList(
+        m_auth,
         m_additionalBundles,
         m_identification,
         m_discovery,

Modified: ace/trunk/ace-log-servlet/pom.xml
URL: http://svn.apache.org/viewvc/ace/trunk/ace-log-servlet/pom.xml?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-log-servlet/pom.xml (original)
+++ ace/trunk/ace-log-servlet/pom.xml Mon Apr 23 12:15:01 2012
@@ -47,6 +47,7 @@
         </export.package>
         <import.package>
             !org.apache.ace.server.log.servlet,
+            org.apache.ace.authentication.api;resolution:=optional;version=${project.version},
             org.apache.ace.log;version=${project.version},
             org.apache.ace.range;version=${project.version},
             org.apache.ace.server.log.store;version=${project.version},
@@ -60,6 +61,10 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.ace</groupId>
+            <artifactId>org.apache.ace.authentication.api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ace</groupId>
             <artifactId>org.apache.ace.range.api</artifactId>
         </dependency>
         <dependency>

Modified: ace/trunk/ace-log-servlet/src/main/java/org/apache/ace/server/log/servlet/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-log-servlet/src/main/java/org/apache/ace/server/log/servlet/Activator.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-log-servlet/src/main/java/org/apache/ace/server/log/servlet/Activator.java (original)
+++ ace/trunk/ace-log-servlet/src/main/java/org/apache/ace/server/log/servlet/Activator.java Mon Apr 23 12:15:01 2012
@@ -25,6 +25,7 @@ import java.util.Properties;
 
 import javax.servlet.Servlet;
 
+import org.apache.ace.authentication.api.AuthenticationService;
 import org.apache.ace.server.log.store.LogStore;
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyActivatorBase;
@@ -36,7 +37,11 @@ import org.osgi.service.cm.ManagedServic
 import org.osgi.service.log.LogService;
 
 public class Activator extends DependencyActivatorBase implements ManagedServiceFactory {
-    private static final String LOG_NAME = "name";
+
+    private static final String KEY_LOG_NAME = "name";
+
+    /** A boolean denoting whether or not authentication is enabled. */
+    private static final String KEY_USE_AUTHENTICATION = "authentication.enabled";
 
     private final Map<String, Component> m_instances = new HashMap<String, Component>(); // String -> Service
     private DependencyManager m_manager;
@@ -69,16 +74,24 @@ public class Activator extends Dependenc
 
     @SuppressWarnings("unchecked")
     public void updated(String pid, Dictionary dict) throws ConfigurationException {
-        String name = (String) dict.get(LOG_NAME);
+        String name = (String) dict.get(KEY_LOG_NAME);
         if ((name == null) || "".equals(name)) {
-            throw new ConfigurationException(LOG_NAME, "Log name has to be specified.");
+            throw new ConfigurationException(KEY_LOG_NAME, "Log name has to be specified.");
+        }
+        
+        String useAuthString = (String) dict.get(KEY_USE_AUTHENTICATION);
+        if (useAuthString == null
+            || !("true".equalsIgnoreCase(useAuthString) || "false".equalsIgnoreCase(useAuthString))) {
+            throw new ConfigurationException(KEY_USE_AUTHENTICATION, "Missing or invalid value!");
         }
+        boolean useAuth = Boolean.parseBoolean(useAuthString);
 
         Component service = m_instances.get(pid);
         if (service == null) {
             service = m_manager.createComponent()
                 .setInterface(Servlet.class.getName(), dict)
-                .setImplementation(new LogServlet(name))
+                .setImplementation(new LogServlet(name, useAuth))
+                .add(createServiceDependency().setService(AuthenticationService.class).setRequired(useAuth))
                 .add(createServiceDependency().setService(LogService.class).setRequired(false))
                 .add(createServiceDependency().setService(LogStore.class, "(&("+Constants.OBJECTCLASS+"="+LogStore.class.getName()+")(name=" + name + "))").setRequired(true));
 

Modified: ace/trunk/ace-log-servlet/src/main/java/org/apache/ace/server/log/servlet/LogServlet.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-log-servlet/src/main/java/org/apache/ace/server/log/servlet/LogServlet.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-log-servlet/src/main/java/org/apache/ace/server/log/servlet/LogServlet.java (original)
+++ ace/trunk/ace-log-servlet/src/main/java/org/apache/ace/server/log/servlet/LogServlet.java Mon Apr 23 12:15:01 2012
@@ -18,23 +18,28 @@
  */
 package org.apache.ace.server.log.servlet;
 
+import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.servlet.ServletException;
 import javax.servlet.ServletInputStream;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.ace.authentication.api.AuthenticationService;
 import org.apache.ace.log.LogDescriptor;
 import org.apache.ace.log.LogEvent;
 import org.apache.ace.range.SortedRangeSet;
 import org.apache.ace.server.log.store.LogStore;
 import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.User;
 
 /**
  * This class acts as a servlet and handles the log protocol. This means a number of requests will be handled:
@@ -72,14 +77,18 @@ public class LogServlet extends HttpServ
     private static final String FILTER_KEY = "filter";
     private static final String LOGID_KEY = "logid";
     private static final String RANGE_KEY = "range";
-
-    private volatile LogService m_log; /* will be injected by dependencymanager */
-    private volatile LogStore m_store; /* will be injected by dependencymanager */
+    
+    // injected by Dependency Manager
+    private volatile LogService m_log;
+    private volatile LogStore m_store;
+    private volatile AuthenticationService m_authService;
 
     private final String m_name;
+    private final boolean m_useAuth;
 
-    public LogServlet(String name) {
+    public LogServlet(String name, boolean useAuth) {
         m_name = name;
+        m_useAuth = useAuth;
     }
 
     @Override
@@ -135,6 +144,37 @@ public class LogServlet extends HttpServ
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        if (!authenticate(req)) {
+            // Authentication failed; don't proceed with the original request...
+            resp.sendError(SC_UNAUTHORIZED);
+        } else {
+            // Authentication successful, proceed with original request...
+            super.service(req, resp);
+        }
+    }
+
+    /**
+     * Authenticates, if needed the user with the information from the given request.
+     * 
+     * @param request the request to obtain the credentials from, cannot be <code>null</code>.
+     * @return <code>true</code> if the authentication was successful, <code>false</code> otherwise.
+     */
+    private boolean authenticate(HttpServletRequest request) {
+        if (m_useAuth) {
+            User user = m_authService.authenticate(request);
+            if (user == null) {
+                m_log.log(LogService.LOG_INFO, "Authentication failure!");
+            }
+            return (user != null);
+        }
+        return true;
+    }
+
     // Handle a call to the query 'command'
     protected boolean handleQuery(String targetID, String logID, String filter, ServletOutputStream output) throws IOException {
         if ((targetID != null) && (logID != null)) {

Modified: ace/trunk/ace-log-servlet/src/test/java/org/apache/ace/server/log/servlet/LogServletTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-log-servlet/src/test/java/org/apache/ace/server/log/servlet/LogServletTest.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-log-servlet/src/test/java/org/apache/ace/server/log/servlet/LogServletTest.java (original)
+++ ace/trunk/ace-log-servlet/src/test/java/org/apache/ace/server/log/servlet/LogServletTest.java Mon Apr 23 12:15:01 2012
@@ -49,7 +49,7 @@ public class LogServletTest {
 
     @BeforeMethod(alwaysRun = true)
     protected void setUp() throws Exception {
-        m_logServlet = new LogServlet("test");
+        m_logServlet = new LogServlet("test", false /* useAuth */);
         TestUtils.configureObject(m_logServlet, LogService.class);
         m_mockStore = new MockLogStore();
         TestUtils.configureObject(m_logServlet, LogStore.class, m_mockStore);

Modified: ace/trunk/ace-log-task/pom.xml
URL: http://svn.apache.org/viewvc/ace/trunk/ace-log-task/pom.xml?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-log-task/pom.xml (original)
+++ ace/trunk/ace-log-task/pom.xml Mon Apr 23 12:15:01 2012
@@ -64,6 +64,10 @@
         </dependency>
         <dependency>
             <groupId>org.apache.ace</groupId>
+            <artifactId>org.apache.ace.connectionfactory</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ace</groupId>
             <artifactId>org.apache.ace.log</artifactId>
         </dependency>
         <dependency>

Modified: ace/trunk/ace-log-task/src/main/java/org/apache/ace/server/log/task/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-log-task/src/main/java/org/apache/ace/server/log/task/Activator.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-log-task/src/main/java/org/apache/ace/server/log/task/Activator.java (original)
+++ ace/trunk/ace-log-task/src/main/java/org/apache/ace/server/log/task/Activator.java Mon Apr 23 12:15:01 2012
@@ -23,6 +23,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 
+import org.apache.ace.connectionfactory.ConnectionFactory;
 import org.apache.ace.discovery.Discovery;
 import org.apache.ace.log.LogSync;
 import org.apache.ace.server.log.store.LogStore;
@@ -37,9 +38,11 @@ import org.osgi.service.log.LogService;
 
 public class Activator extends DependencyActivatorBase implements ManagedServiceFactory {
 
-    private static final String LOG_NAME = "name";
-    private DependencyManager m_manager;
+    private static final String KEY_LOG_NAME = "name";
+    
     private final Map<String, Component> m_instances = new HashMap<String, Component>();
+    
+    private volatile DependencyManager m_manager;
     private volatile LogService m_log;
 
     @Override
@@ -50,7 +53,8 @@ public class Activator extends Dependenc
         manager.add(createComponent()
             .setInterface(ManagedServiceFactory.class.getName(), props)
             .setImplementation(this)
-            .add(createServiceDependency().setService(LogService.class).setRequired(false)));
+            .add(createServiceDependency().setService(LogService.class).setRequired(false))
+            );
     }
 
     @Override
@@ -70,27 +74,43 @@ public class Activator extends Dependenc
 
     @SuppressWarnings("unchecked")
     public synchronized void updated(String pid, Dictionary dict) throws ConfigurationException {
-        String name = (String) dict.get(LOG_NAME);
+        String name = (String) dict.get(KEY_LOG_NAME);
         if ((name == null) || "".equals(name)) {
-            throw new ConfigurationException(LOG_NAME, "Log name has to be specified.");
+            throw new ConfigurationException(KEY_LOG_NAME, "Log name has to be specified.");
         }
 
-        Component service = m_instances.get(pid);
-        if (service == null) {
-            Properties props = new Properties();
-            props.put(LOG_NAME, name);
-            props.put("taskName", LogSyncTask.class.getName());
-            props.put("description", "Syncs log (name=" + name + ") with a server.");
-            service = m_manager.createComponent()
-                .setInterface(new String[] { Runnable.class.getName(), LogSync.class.getName() }, props)
-                .setImplementation(new LogSyncTask(name, name))
-                .add(createServiceDependency().setService(LogStore.class, "(&("+Constants.OBJECTCLASS+"="+LogStore.class.getName()+")(name=" + name + "))").setRequired(true))
-                .add(createServiceDependency().setService(Discovery.class).setRequired(true))
-                .add(createServiceDependency().setService(LogService.class).setRequired(false));
-            m_instances.put(pid, service);
-            m_manager.add(service);
-        } else {
-            m_log.log(LogService.LOG_INFO, "Ignoring configuration update because factory instance was already configured: " + name);
+        Component comp;
+        boolean created = false;
+
+        synchronized (m_instances) {
+            comp = m_instances.get(pid);
+            if (comp != null) {
+                m_log.log(LogService.LOG_INFO, "Ignoring configuration update because factory instance was already configured: " + name);
+            } else {
+                Properties props = new Properties();
+                props.put(KEY_LOG_NAME, name);
+                props.put("taskName", LogSyncTask.class.getName());
+                props.put("description", "Syncs log (name=" + name + ") with a server.");
+                
+                String filter = "(&(" + Constants.OBJECTCLASS + "=" + LogStore.class.getName() + ")(name=" + name + "))";
+
+                LogSyncTask service = new LogSyncTask(name, name);
+
+                comp = m_manager.createComponent()
+                                .setInterface(new String[] { Runnable.class.getName(), LogSync.class.getName() }, props)
+                                .setImplementation(service)
+                                .add(createServiceDependency().setService(ConnectionFactory.class).setRequired(true))
+                                .add(createServiceDependency().setService(LogStore.class, filter).setRequired(true))
+                                .add(createServiceDependency().setService(Discovery.class).setRequired(true))
+                                .add(createServiceDependency().setService(LogService.class).setRequired(false));
+                m_instances.put(pid, comp);
+
+                created = true;
+            }
+        }
+        
+        if (created && (comp != null)) {
+            m_manager.add(comp);
         }
     }
 }
\ No newline at end of file

Modified: ace/trunk/ace-log-task/src/main/java/org/apache/ace/server/log/task/LogSyncTask.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-log-task/src/main/java/org/apache/ace/server/log/task/LogSyncTask.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-log-task/src/main/java/org/apache/ace/server/log/task/LogSyncTask.java (original)
+++ ace/trunk/ace-log-task/src/main/java/org/apache/ace/server/log/task/LogSyncTask.java Mon Apr 23 12:15:01 2012
@@ -26,12 +26,14 @@ import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
+import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.ace.connectionfactory.ConnectionFactory;
 import org.apache.ace.discovery.Discovery;
 import org.apache.ace.log.LogDescriptor;
 import org.apache.ace.log.LogEvent;
@@ -46,7 +48,7 @@ public class LogSyncTask implements Runn
     private static final String COMMAND_SEND = "send";
     private static final String COMMAND_RECEIVE = "receive";
 
-    private static final String GWID_KEY = "gwid";
+    private static final String TARGETID_KEY = "gwid";
     private static final String FILTER_KEY = "filter";
     private static final String LOGID_KEY = "logid";
     private static final String RANGE_KEY = "range";
@@ -55,6 +57,8 @@ public class LogSyncTask implements Runn
     private volatile Discovery m_discovery;
     private volatile LogService m_log;
     private volatile LogStore m_logStore;
+    private volatile ConnectionFactory m_connectionFactory;
+    
     private final String m_endpoint;
     private final String m_name;
 
@@ -94,7 +98,7 @@ public class LogSyncTask implements Runn
     private boolean synchronize(boolean push, boolean pull) throws IOException {
         URL host = m_discovery.discover();
 
-        Connection queryConnection = new Connection(new URL(host, m_endpoint + "/" + COMMAND_QUERY));
+        URLConnection queryConnection = m_connectionFactory.createConnection(new URL(host, m_endpoint + "/" + COMMAND_QUERY));
         InputStream queryInput = queryConnection.getInputStream();
 
         List<LogDescriptor> localRanges = m_logStore.getDescriptors();
@@ -114,7 +118,9 @@ public class LogSyncTask implements Runn
         boolean result = false;
         OutputStream sendOutput = null;
         try {
-            Connection sendConnection = new Connection(new URL(host, m_endpoint + "/" + COMMAND_SEND));
+            URLConnection sendConnection = m_connectionFactory.createConnection(new URL(host, m_endpoint + "/" + COMMAND_SEND));
+            sendConnection.setDoOutput(true);
+            
             sendOutput = sendConnection.getOutputStream();
 
             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sendOutput));
@@ -124,7 +130,12 @@ public class LogSyncTask implements Runn
 
             sendOutput.flush();
             sendOutput.close();
-            sendConnection.close();
+
+            if (sendConnection instanceof HttpURLConnection) {
+                HttpURLConnection conn = (HttpURLConnection) sendConnection;
+                conn.getContent();
+                conn.disconnect();
+            }
         }
         catch (IOException e) {
             m_log.log(LogService.LOG_ERROR, "Unable to (fully) synchronize log with remote", e);
@@ -174,17 +185,24 @@ public class LogSyncTask implements Runn
         List<LogDescriptor> delta = calculateDelta(remoteRanges, localRanges);
         result = !delta.isEmpty();
         for (LogDescriptor l : delta) {
-            Connection receiveConnection;
             try {
                 /*
                  * The request currently contains a range. This is not yet supported by the servlet, but it will
                  * simply be ignored.
                  */
-                receiveConnection = new Connection(new URL(host, m_endpoint + "/" + COMMAND_RECEIVE + "?" + GWID_KEY +
-                    "=" + l.getTargetID() + "&" + LOGID_KEY + "=" + l.getLogID() + "&" + RANGE_KEY + "=" + l.getRangeSet().toRepresentation()));
+                URL url = new URL(host, m_endpoint + "/" + COMMAND_RECEIVE + "?" + TARGETID_KEY + "=" + l.getTargetID() + "&" + LOGID_KEY + "=" + l.getLogID() + "&" + RANGE_KEY + "=" + l.getRangeSet().toRepresentation());
+                
+                URLConnection receiveConnection = m_connectionFactory.createConnection(url);
                 InputStream receiveInput = receiveConnection.getInputStream();
+                
                 BufferedReader reader = new BufferedReader(new InputStreamReader(receiveInput));
                 readLogs(reader);
+                
+                if (receiveConnection instanceof HttpURLConnection) {
+                    HttpURLConnection conn = (HttpURLConnection) receiveConnection;
+                    conn.getContent();
+                    conn.disconnect();
+                }
             }
             catch (IOException e) {
                 m_log.log(LogService.LOG_ERROR, "Unable to connect to retrieve log events.", e);
@@ -279,50 +297,6 @@ public class LogSyncTask implements Runn
 
     }
 
-    // helper class that abstracts handling of a URLConnection somewhat.
-    private class Connection {
-        private URLConnection m_connection;
-
-        public Connection(URL url) throws IOException {
-            m_connection = url.openConnection();
-        }
-
-        /**
-         * Enables the retrieving of input using this connection and returns an inputstream
-         * to the connection.
-         *
-         * @return Inputstream to the connection.
-         * @throws java.io.IOException If I/O problems occur.
-         */
-        public InputStream getInputStream() throws IOException {
-            m_connection.setDoInput(true);
-            return m_connection.getInputStream();
-        }
-
-        /**
-         * Enables the sending of output using this connection and returns an outputstream
-         * to the connection.
-         *
-         * @return Outputstream to the connection.
-         * @throws java.io.IOException If I/O problems occur.
-         */
-        public OutputStream getOutputStream() throws IOException {
-            m_connection.setDoOutput(true);
-            return m_connection.getOutputStream();
-        }
-
-        /**
-         * Should be called when a <code>Connection</code> is used to do a POST (write to it's outputstream)
-         * without reading it's inputstream (the response). Calling this will make sure the POST request is sent.
-         *
-         * @throws java.io.IOException If I/O problems occur dealing with the connection.
-         */
-        public void close() throws IOException {
-            m_connection.getContent();
-        }
-
-    }
-
     public String getName() {
         return m_name;
     }

Modified: ace/trunk/ace-managementagent/pom.xml
URL: http://svn.apache.org/viewvc/ace/trunk/ace-managementagent/pom.xml?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-managementagent/pom.xml (original)
+++ ace/trunk/ace-managementagent/pom.xml Mon Apr 23 12:15:01 2012
@@ -161,6 +161,10 @@
             <groupId>org.apache.ace</groupId>
             <artifactId>org.apache.ace.deployment.task</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.ace</groupId>
+            <artifactId>org.apache.ace.connectionfactory</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

Modified: ace/trunk/ace-managementagent/src/main/java/org/apache/ace/managementagent/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-managementagent/src/main/java/org/apache/ace/managementagent/Activator.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-managementagent/src/main/java/org/apache/ace/managementagent/Activator.java (original)
+++ ace/trunk/ace-managementagent/src/main/java/org/apache/ace/managementagent/Activator.java Mon Apr 23 12:15:01 2012
@@ -1,5 +1,6 @@
 package org.apache.ace.managementagent;
 
+import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 import java.util.Dictionary;
@@ -14,11 +15,13 @@ import org.osgi.service.cm.Configuration
 
 public class Activator extends DependencyActivatorBase {
 
-    private BundleActivator[] m_activators = new BundleActivator[] {
+    private final boolean m_quiet = Boolean.parseBoolean(System.getProperty("quiet", "false"));
+    private final BundleActivator[] m_activators = new BundleActivator[] {
         new org.apache.ace.deployment.deploymentadmin.Activator(),
         new org.apache.ace.deployment.service.impl.Activator(),
         new org.apache.ace.deployment.task.Activator(),
         new org.apache.ace.discovery.property.Activator(),
+        new org.apache.ace.connectionfactory.impl.Activator(),
         new org.apache.ace.target.log.Activator(),
         new org.apache.ace.target.log.store.impl.Activator(),
         new org.apache.ace.identification.property.Activator(),
@@ -30,9 +33,21 @@ public class Activator extends Dependenc
     };
     
     private volatile ConfigurationAdmin m_config;
-    
-    private boolean m_quiet = Boolean.parseBoolean(System.getProperty("quiet", "false"));
-    
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+        for (int i = 0; i < m_activators.length; i++) {
+            BundleActivator a = m_activators[i];
+            a.stop(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public void init(BundleContext context, DependencyManager manager) throws Exception {
         for (int i = 0; i < m_activators.length; i++) {
@@ -48,7 +63,7 @@ public class Activator extends Dependenc
                 System.out.println("Not starting activator " + packageName + ".");
             }
         }
-        
+
         manager.add(createComponent()
             .setImplementation(this)
             .add(createServiceDependency()
@@ -56,14 +71,25 @@ public class Activator extends Dependenc
                 .setRequired(true)));
     }
     
+    /**
+     * Called by the dependency manager when the configuration admin service becomes available.
+     */
     public void start() {
         try {
             String syncInterval = System.getProperty("syncinterval", "2000");
+            String stopUnaffectedBundles = System.getProperty("org.apache.felix.deploymentadmin.stopunaffectedbundle", "false");
+            System.setProperty("org.apache.felix.deploymentadmin.stopunaffectedbundle", stopUnaffectedBundles);
+
             configureFactory("org.apache.ace.target.log.factory", "name", "auditlog");
             configureFactory("org.apache.ace.target.log.store.factory", "name", "auditlog");
+
             configure("org.apache.ace.scheduler", "org.apache.ace.deployment.task.DeploymentUpdateTask", syncInterval);
-            String stopUnaffectedBundles = System.getProperty("org.apache.felix.deploymentadmin.stopunaffectedbundle", "false");
-            System.setProperty("org.apache.felix.deploymentadmin.stopunaffectedbundle", stopUnaffectedBundles);
+
+            String auth = System.getProperty("auth");
+            if (auth != null && !"".equals(auth.trim())) {
+                configureAuth("org.apache.ace.connectionfactory", auth);
+            }
+
             String agents = System.getProperty("agents");
             if (agents != null) {
                 // format: a,b,c;d,e,f
@@ -108,9 +134,10 @@ public class Activator extends Dependenc
             }
             else {
                 String server = System.getProperty("discovery", "http://localhost:8080");
-                configure("org.apache.ace.discovery.property", "serverURL", server);
-                boolean isFileUrl = "file".equals((new URL(server)).getProtocol());
                 String targetId = System.getProperty("identification", "defaultTargetID");
+                boolean isFileUrl = "file".equals((new URL(server)).getProtocol());
+                
+                configure("org.apache.ace.discovery.property", "serverURL", server);
                 configure("org.apache.ace.identification.property", "targetID", targetId);
                 if (!isFileUrl) {
                     configureFactory("org.apache.ace.target.log.sync.factory", "name", "auditlog");
@@ -167,12 +194,38 @@ public class Activator extends Dependenc
             conf.update(properties);
         }
     }
-
-    @Override
-    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
-        for (int i = 0; i < m_activators.length; i++) {
-            BundleActivator a = m_activators[i];
-            a.stop(context);
+    
+    private void configureAuth(String factoryPid, String value) throws IOException {
+        try {
+            File file = new File(value);
+            if (file.exists()) {
+                if (file.isDirectory()) {
+                    for (File f : file.listFiles()) {
+                        loadProperties(factoryPid, f);
+                    }
+                } else {
+                    loadProperties(factoryPid, file);
+                }
+            } else {
+                loadProperties(factoryPid, new URL(value));
+            }
+        } catch (IOException e) {
+            System.err.println("Invalid authentication properties for " + value + " (" + e.getMessage() + ")");
         }
     }
+    
+    private Properties loadProperties(String factoryPID, File f) throws IOException {
+        return loadProperties(factoryPID, f.toURI().toURL());
+    }
+    
+    private Properties loadProperties(String factoryPID, URL url) throws IOException {
+        Configuration conf = m_config.createFactoryConfiguration(factoryPID, null);
+        
+        Properties props = new Properties();
+        props.load(url.openStream());
+        
+        conf.update(props);
+        
+        return props;
+    }
 }

Modified: ace/trunk/ace-obr-servlet/pom.xml
URL: http://svn.apache.org/viewvc/ace/trunk/ace-obr-servlet/pom.xml?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-obr-servlet/pom.xml (original)
+++ ace/trunk/ace-obr-servlet/pom.xml Mon Apr 23 12:15:01 2012
@@ -47,6 +47,7 @@
         </export.package>
         <import.package>
             !org.apache.ace.obr.servlet,
+            org.apache.ace.authentication.api;resolution:=optional;version=${project.version},
             *
         </import.package>
         <bundle.activator>
@@ -57,6 +58,10 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.ace</groupId>
+            <artifactId>org.apache.ace.authentication.api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ace</groupId>
             <artifactId>org.apache.ace.obr.metadata</artifactId>
         </dependency>
         <dependency>

Modified: ace/trunk/ace-obr-servlet/src/main/java/org/apache/ace/obr/servlet/BundleServlet.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-obr-servlet/src/main/java/org/apache/ace/obr/servlet/BundleServlet.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-obr-servlet/src/main/java/org/apache/ace/obr/servlet/BundleServlet.java (original)
+++ ace/trunk/ace-obr-servlet/src/main/java/org/apache/ace/obr/servlet/BundleServlet.java Mon Apr 23 12:15:01 2012
@@ -18,7 +18,12 @@
  */
 package org.apache.ace.obr.servlet;
 
+import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
+import static javax.servlet.http.HttpServletResponse.SC_CONFLICT;
+import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
 import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
+import static javax.servlet.http.HttpServletResponse.SC_OK;
+import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
 
 import java.io.Closeable;
 import java.io.EOFException;
@@ -26,33 +31,73 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.Dictionary;
 
+import javax.servlet.ServletException;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.ace.authentication.api.AuthenticationService;
 import org.apache.ace.obr.storage.BundleStore;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedService;
 import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.User;
 
+/**
+ * Provides access to the OBR through a REST-ish API.
+ */
 public class BundleServlet extends HttpServlet implements ManagedService {
-    public static final String TEXT_MIMETYPE = "text/plain";
-
     private static final long serialVersionUID = 1L;
+
+    /** A boolean denoting whether or not authentication is enabled. */
+    private static final String KEY_USE_AUTHENTICATION = "authentication.enabled";
+
     private static final int COPY_BUFFER_SIZE = 4096;
 
+    public static final String TEXT_MIMETYPE = "text/plain";
+
+    private volatile DependencyManager m_dm; // injected by Dependency Manager
     private volatile LogService m_log; /* will be injected by dependencymanager */
     private volatile BundleStore m_store; /* will be injected by dependencymanager */
+    private volatile AuthenticationService m_authService;
+
+    private volatile boolean m_useAuth = false;
 
     @Override
     public String getServletInfo() {
         return "Apache ACE OBR Servlet";
     }
 
-    @SuppressWarnings("unchecked")
     public void updated(Dictionary settings) throws ConfigurationException {
-        // nothing needs to be done, settings are propagated by the dependency manager
+        if (settings != null) {
+            String useAuthString = (String) settings.get(KEY_USE_AUTHENTICATION);
+            if (useAuthString == null
+                || !("true".equalsIgnoreCase(useAuthString) || "false".equalsIgnoreCase(useAuthString))) {
+                throw new ConfigurationException(KEY_USE_AUTHENTICATION, "Missing or invalid value!");
+            }
+            boolean useAuth = Boolean.parseBoolean(useAuthString);
+
+            m_useAuth = useAuth;
+        }
+        else {
+            m_useAuth = false;
+        }
+    }
+
+    /**
+     * Called by Dependency Manager upon initialization of this component.
+     * 
+     * @param comp the component to initialize, cannot be <code>null</code>.
+     */
+    protected void init(Component comp) {
+        comp.add(m_dm.createServiceDependency()
+            .setService(AuthenticationService.class)
+            .setRequired(m_useAuth)
+            .setInstanceBound(true)
+            );
     }
 
     /**
@@ -69,21 +114,21 @@ public class BundleServlet extends HttpS
     protected void doPost(HttpServletRequest request, HttpServletResponse response) {
         String path = request.getPathInfo();
         if ((path == null) || (path.length() <= 1)) {
-            sendResponse(response, HttpServletResponse.SC_BAD_REQUEST);
+            sendResponse(response, SC_BAD_REQUEST);
         }
         else {
             String id = path.substring(1);
             try {
                 if (m_store.put(id, request.getInputStream())) {
-                    sendResponse(response, HttpServletResponse.SC_OK);
+                    sendResponse(response, SC_OK);
                 }
                 else {
-                    sendResponse(response, HttpServletResponse.SC_CONFLICT);
+                    sendResponse(response, SC_CONFLICT);
                 }
             }
             catch (IOException e) {
                 m_log.log(LogService.LOG_WARNING, "Exception handling request: " + request.getRequestURL(), e);
-                sendResponse(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+                sendResponse(response, SC_INTERNAL_SERVER_ERROR);
             }
         }
     }
@@ -101,14 +146,14 @@ public class BundleServlet extends HttpS
     protected void doDelete(HttpServletRequest request, HttpServletResponse response) {
         String path = request.getPathInfo();
         if ((path == null) || (path.length() <= 1)) {
-            sendResponse(response, HttpServletResponse.SC_BAD_REQUEST);
+            sendResponse(response, SC_BAD_REQUEST);
         }
         else {
             // Remove leading slash...
             String id = path.substring(1);
             try {
                 if (m_store.remove(id)) {
-                    sendResponse(response, HttpServletResponse.SC_OK);
+                    sendResponse(response, SC_OK);
                 }
                 else {
                     sendResponse(response, SC_NOT_FOUND);
@@ -116,7 +161,7 @@ public class BundleServlet extends HttpS
             }
             catch (IOException e) {
                 m_log.log(LogService.LOG_WARNING, "Exception handling request: " + request.getRequestURL(), e);
-                sendResponse(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+                sendResponse(response, SC_INTERNAL_SERVER_ERROR);
             }
         }
     }
@@ -136,7 +181,7 @@ public class BundleServlet extends HttpS
     protected void doGet(HttpServletRequest request, HttpServletResponse response) {
         String path = request.getPathInfo();
         if ((path == null) || (path.length() <= 1)) {
-            sendResponse(response, HttpServletResponse.SC_BAD_REQUEST);
+            sendResponse(response, SC_BAD_REQUEST);
         }
         else {
             // Remove leasing slash...
@@ -162,19 +207,51 @@ public class BundleServlet extends HttpS
             }
             catch (EOFException ex) {
                 // ACE-260: lower log-level of this exception; as it is probably because the remote hung up early...
-                m_log.log(LogService.LOG_DEBUG, "EOF Exception in request: " + request.getRequestURL() + "; probably the remote hung up early.");
+                m_log.log(LogService.LOG_DEBUG, "EOF Exception in request: " + request.getRequestURL()
+                    + "; probably the remote hung up early.");
             }
             catch (IOException ex) {
                 // ACE-260: all other exception are logged, as we might have a possible resource leak...
                 m_log.log(LogService.LOG_WARNING, "Exception in request: " + request.getRequestURL(), ex);
+                sendResponse(response, SC_INTERNAL_SERVER_ERROR);
             }
             finally {
-                closeSafely(fileStream, request);
                 closeSafely(output, request);
             }
         }
     }
-    
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        if (!authenticate(req)) {
+            // Authentication failed; don't proceed with the original request...
+            resp.sendError(SC_UNAUTHORIZED);
+        } else {
+            // Authentication successful, proceed with original request...
+            super.service(req, resp);
+        }
+    }
+
+    /**
+     * Authenticates, if needed the user with the information from the given request.
+     * 
+     * @param request the request to obtain the credentials from, cannot be <code>null</code>.
+     * @return <code>true</code> if the authentication was successful, <code>false</code> otherwise.
+     */
+    private boolean authenticate(HttpServletRequest request) {
+        if (m_useAuth) {
+            User user = m_authService.authenticate(request);
+            if (user == null) {
+                m_log.log(LogService.LOG_INFO, "Authentication failure!");
+            }
+            return (user != null);
+        }
+        return true;
+    }
+
     private void closeSafely(Closeable resource, HttpServletRequest request) {
         if (resource != null) {
             try {
@@ -182,7 +259,8 @@ public class BundleServlet extends HttpS
             }
             catch (EOFException ex) {
                 // ACE-260: lower log-level of this exception; as it is probably because the remote hung up early...
-                m_log.log(LogService.LOG_DEBUG, "EOF Exception trying to close stream: " + request.getRequestURL() + "; probably the remote hung up early.");
+                m_log.log(LogService.LOG_DEBUG, "EOF Exception trying to close stream: " + request.getRequestURL()
+                    + "; probably the remote hung up early.");
             }
             catch (Exception ex) {
                 // ACE-260: all other exception are logged, as we might have a possible resource leak...

Modified: ace/trunk/ace-repository-api/src/main/java/org/apache/ace/repository/Repository.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-api/src/main/java/org/apache/ace/repository/Repository.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-api/src/main/java/org/apache/ace/repository/Repository.java (original)
+++ ace/trunk/ace-repository-api/src/main/java/org/apache/ace/repository/Repository.java Mon Apr 23 12:15:01 2012
@@ -28,10 +28,9 @@ import org.apache.ace.range.SortedRangeS
  */
 public interface Repository
 {
-
     /**
      * Determines the versions inside the repository.
-     *
+     * 
      * @returns A <code>SortedRangeSet</code> representing all the versions currently inside the repository.
      * @throws java.io.IOException If there is an error determining the current versions.
      */
@@ -39,7 +38,7 @@ public interface Repository
 
     /**
      * Commits data into the repository.
-     *
+     * 
      * @param data The data to be committed.
      * @param fromVersion The version the data is based upon.
      * @return True if the commit succeeded, false otherwise if the <code>fromVersion</code> is not the latest version.
@@ -52,8 +51,9 @@ public interface Repository
     /**
      * Checks out the version of the repository that have been passed to this
      * method as parameter.
+     * 
      * @return a stream containing a checkout of the passed in version of
-     * the repository, or null if the version does not exist
+     *         the repository, or null if the version does not exist
      * @throws java.io.IOException if there is an error reading the version
      * @throws IllegalArgumentException if the version is invalid.
      */

Modified: ace/trunk/ace-repository-api/src/main/java/org/apache/ace/repository/RepositoryReplication.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-api/src/main/java/org/apache/ace/repository/RepositoryReplication.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-api/src/main/java/org/apache/ace/repository/RepositoryReplication.java (original)
+++ ace/trunk/ace-repository-api/src/main/java/org/apache/ace/repository/RepositoryReplication.java Mon Apr 23 12:15:01 2012
@@ -28,10 +28,9 @@ import org.apache.ace.range.SortedRangeS
  */
 public interface RepositoryReplication
 {
-
     /**
      * Determines the versions inside the repository.
-     *
+     * 
      * @returns A <code>SortedRangeSet</code> representing all the versions currently inside the repository.
      * @throws java.io.IOException If there is an error determining the current versions.
      */
@@ -39,7 +38,7 @@ public interface RepositoryReplication
 
     /**
      * Gets the specified version.
-     *
+     * 
      * @return A stream containing the specified version's data or <code>null</code> if the version does not exist.
      * @throws java.io.IOException If there is an error reading the version.
      * @throws IllegalArgumentException If the specified version is not greater than 0.
@@ -48,7 +47,7 @@ public interface RepositoryReplication
 
     /**
      * Store the stream data as the specified version.
-     *
+     * 
      * @return returns True if all went fine, false if the version already existed.
      * @throws java.io.IOException If the stream data could not be stored successfully due to I/O problems.
      * @throws IllegalArgumentException If the version number is not greater than 0.

Modified: ace/trunk/ace-repository-ext/pom.xml
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-ext/pom.xml?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-ext/pom.xml (original)
+++ ace/trunk/ace-repository-ext/pom.xml Mon Apr 23 12:15:01 2012
@@ -42,6 +42,10 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.ace</groupId>
+            <artifactId>org.apache.ace.connectionfactory</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ace</groupId>
             <artifactId>org.apache.ace.range.api</artifactId>
         </dependency>
         <dependency>

Modified: ace/trunk/ace-repository-ext/src/main/java/org/apache/ace/repository/ext/impl/CachedRepositoryImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-ext/src/main/java/org/apache/ace/repository/ext/impl/CachedRepositoryImpl.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-ext/src/main/java/org/apache/ace/repository/ext/impl/CachedRepositoryImpl.java (original)
+++ ace/trunk/ace-repository-ext/src/main/java/org/apache/ace/repository/ext/impl/CachedRepositoryImpl.java Mon Apr 23 12:15:01 2012
@@ -19,17 +19,14 @@
 package org.apache.ace.repository.ext.impl;
 
 import java.io.ByteArrayInputStream;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URL;
 
 import org.apache.ace.range.RangeIterator;
 import org.apache.ace.range.SortedRangeSet;
 import org.apache.ace.repository.Repository;
 import org.apache.ace.repository.ext.BackupRepository;
 import org.apache.ace.repository.ext.CachedRepository;
-import org.osgi.service.useradmin.User;
 
 /**
  * Provides a CachedRepository, which uses either a <code>Repository</code> and a <code>BackupRepository</code>
@@ -40,48 +37,25 @@ import org.osgi.service.useradmin.User;
 public class CachedRepositoryImpl implements CachedRepository {
     public static final long UNCOMMITTED_VERSION = -1;
 
-    private final User m_user;
     private volatile long m_mostRecentVersion;
 
     private final BackupRepository m_local;
     private final Repository m_remote;
 
     /**
-     * Creates a cached repository which uses <code>remote</code>, <code>customer</code> and
-     * <code>name</code> to create a <code>RemoteRepository</code>, and uses the <code>Files</code>s
-     * passed in as a for local storage and backup.
-     * @param user A user object, which is allowed to access <code>remote</code>.
-     * @param remote The location of the remote repository.
-     * @param customer The customer name to be used with the remote repository.
-     * @param name The name to be used with the remote repository.
-     * @param local A local file to be used for storage of changes to the repository.
-     * @param backup A local file to be used as a local backup of what was on the server.
-     * @param mostRecentVersion The version from which <code>backup</code> was checked out or committed.
-     * If no version has been committed yet, use <code>UNCOMMITTED_VERSION</code>.
-     */
-    public CachedRepositoryImpl(User user, URL remote, String customer, String name, File local, File backup, long mostRecentVersion) {
-        this(user,
-            new RemoteRepository(remote, customer, name),
-            new FilebasedBackupRepository(local, backup),
-            mostRecentVersion);
-    }
-
-    /**
      * Creates a cached repository using.
-     * @param user A user object, which is allowed to access <code>remote</code>.
+     * 
      * @param remote A repository which holds committed versions.
      * @param backup A backup repository for local changes.
      * @param mostRecentVersion The version from which <code>backup</code> was checked out or committed.
      * If no version has been committed yet, use <code>UNCOMMITTED_VERSION</code>.
      */
-    public CachedRepositoryImpl(User user, Repository remote, BackupRepository backup, long mostRecentVersion) {
-        m_user = user;
+    public CachedRepositoryImpl(Repository remote, BackupRepository backup, long mostRecentVersion) {
         m_remote = remote;
         m_local = backup;
         m_mostRecentVersion = mostRecentVersion;
     }
 
-
     public InputStream checkout(boolean fail) throws IOException, IllegalArgumentException {
         m_mostRecentVersion = highestRemoteVersion();
         if (m_mostRecentVersion == 0) {

Modified: ace/trunk/ace-repository-ext/src/main/java/org/apache/ace/repository/ext/impl/RemoteRepository.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-ext/src/main/java/org/apache/ace/repository/ext/impl/RemoteRepository.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-ext/src/main/java/org/apache/ace/repository/ext/impl/RemoteRepository.java (original)
+++ ace/trunk/ace-repository-ext/src/main/java/org/apache/ace/repository/ext/impl/RemoteRepository.java Mon Apr 23 12:15:01 2012
@@ -29,6 +29,7 @@ import java.net.URL;
 
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.ace.connectionfactory.ConnectionFactory;
 import org.apache.ace.range.SortedRangeSet;
 import org.apache.ace.repository.Repository;
 
@@ -40,50 +41,42 @@ public class RemoteRepository implements
     private static final String COMMAND_QUERY = "/query";
     private static final String COMMAND_CHECKOUT = "/checkout";
     private static final String COMMAND_COMMIT = "/commit";
+    
     private static final String MIME_APPLICATION_OCTET_STREAM = "application/octet-stream";
+    
     private static final int COPY_BUFFER_SIZE = 4096;
 
     private final URL m_url;
     private final String m_customer;
     private final String m_name;
-    private final String m_filter;
 
-
-    RemoteRepository(URL url, String customer, String name, String filter) {
-        m_url = url;
-        m_customer = customer;
-        m_name = name;
-        m_filter = filter;
-    }
+    private volatile ConnectionFactory m_connectionFactory;
 
     /**
-     * Creates a remote repository that connects to a given location with a given customer-
-     * and repository name.
+     * Creates a remote repository that connects to a given location with a given customer- and repository name.
+     * 
      * @param url The location of the repository.
      * @param customer The customer name to use.
      * @param name The repository name to use.
      */
     public RemoteRepository(URL url, String customer, String name) {
-        this(url, customer, name, null);
-    }
+        if (url == null || customer == null || name == null) {
+            throw new IllegalArgumentException("None of the parameters can be null!");
+        }
 
-    /**
-     * Creates a remote repository that connects to a given location with a given filter.
-     * @param url The location of the repository.
-     * @param filter An LDAP filter string to select the repository.
-     */
-    public RemoteRepository(URL url, String filter) {
-        this(url, null, null, filter);
+        m_url = url;
+        m_customer = customer;
+        m_name = name;
     }
 
-
     public InputStream checkout(long version) throws IOException, IllegalArgumentException {
         if (version <= 0) {
             throw new IllegalArgumentException("Version must be greater than 0.");
         }
 
         URL url = buildCommand(m_url, COMMAND_CHECKOUT, version);
-        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        HttpURLConnection connection = (HttpURLConnection) m_connectionFactory.createConnection(url);
+
         if (connection.getResponseCode() == HttpServletResponse.SC_NOT_FOUND) {
             throw new IllegalArgumentException("Requested version not found in remote repository. (" + connection.getResponseMessage() + ")");
         }
@@ -96,7 +89,8 @@ public class RemoteRepository implements
 
     public boolean commit(InputStream data, long fromVersion) throws IOException, IllegalArgumentException {
         URL url = buildCommand(m_url, COMMAND_COMMIT, fromVersion);
-        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        HttpURLConnection connection = (HttpURLConnection) m_connectionFactory.createConnection(url);
+        
         connection.setDoOutput(true);
         connection.setRequestProperty("Content-Type", MIME_APPLICATION_OCTET_STREAM);
 
@@ -104,12 +98,14 @@ public class RemoteRepository implements
         copy(data, out);
         out.flush();
         out.close();
+
         return connection.getResponseCode() == HttpServletResponse.SC_OK;
     }
 
     public SortedRangeSet getRange() throws IOException {
         URL url = buildCommand(m_url, COMMAND_QUERY, 0);
-        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        HttpURLConnection connection = (HttpURLConnection) m_connectionFactory.createConnection(url);
+        
         if (connection.getResponseCode() == HttpServletResponse.SC_OK) {
             BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
             String line = reader.readLine();
@@ -120,6 +116,7 @@ public class RemoteRepository implements
             reader.close();
             return new SortedRangeSet(representation);
         }
+
         throw new IOException("Connection error: " + connection.getResponseMessage());
     }
 
@@ -142,6 +139,7 @@ public class RemoteRepository implements
      * Builds a command string to use in the request to the server, based on the parameters
      * this object was created with. The version is only mandatory for <code>CHECKOUT</code>
      * and <code>COMMIT</code>.
+     * 
      * @param command A command string, use the <code>COMMAND_</code> constants in this file.
      * @param version A version statement.
      * @return The command string.
@@ -149,29 +147,23 @@ public class RemoteRepository implements
     private URL buildCommand(URL url, String command, long version) {
         StringBuffer result = new StringBuffer();
 
-        if (m_filter != null) {
-            result.append(m_filter);
+        if (m_customer != null) {
+            if (result.length() != 0) {
+                result.append("&");
+            }
+            result.append("customer=").append(m_customer);
         }
-        else {
-
-            if (m_customer != null) {
-                if (result.length() != 0) {
-                    result.append("&");
-                }
-                result.append("customer=").append(m_customer);
-            }
-            if (m_name != null) {
-                if (result.length() != 0) {
-                    result.append("&");
-                }
-                result.append("name=").append(m_name);
-            }
-            if (command != COMMAND_QUERY) {
-                if (result.length() != 0) {
-                    result.append("&");
-                }
-                result.append("version=").append(version);
+        if (m_name != null) {
+            if (result.length() != 0) {
+                result.append("&");
+            }
+            result.append("name=").append(m_name);
+        }
+        if (command != COMMAND_QUERY) {
+            if (result.length() != 0) {
+                result.append("&");
             }
+            result.append("version=").append(version);
         }
 
         try {
@@ -189,6 +181,6 @@ public class RemoteRepository implements
 
     @Override
     public String toString() {
-        return "RemoteRepository[" + m_url + "," + m_customer + "," + m_name + "," + m_filter + "]";
+        return "RemoteRepository[" + m_url + "," + m_customer + "," + m_name + "]";
     }
 }
\ No newline at end of file

Modified: ace/trunk/ace-repository-servlet/pom.xml
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-servlet/pom.xml?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-servlet/pom.xml (original)
+++ ace/trunk/ace-repository-servlet/pom.xml Mon Apr 23 12:15:01 2012
@@ -47,6 +47,7 @@
         </export.package>
         <import.package>
             !org.apache.ace.repository.servlet,
+            org.apache.ace.authentication.api;resolution:=optional;version=${project.version},
             org.apache.ace.range;version=${project.version},
             org.apache.ace.repository;version=${project.version},
             *
@@ -59,6 +60,10 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.ace</groupId>
+            <artifactId>org.apache.ace.authentication.api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ace</groupId>
             <artifactId>org.apache.ace.range.api</artifactId>
         </dependency>
         <dependency>

Modified: ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryReplicationServlet.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryReplicationServlet.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryReplicationServlet.java (original)
+++ ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryReplicationServlet.java Mon Apr 23 12:15:01 2012
@@ -66,9 +66,8 @@ public class RepositoryReplicationServle
     }
 
     @Override
-    @SuppressWarnings("unchecked")
     public void updated(Dictionary settings) throws ConfigurationException {
-        // nothing special we want to do here
+        super.updated(settings);
     }
 
     @Override

Modified: ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryServlet.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryServlet.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryServlet.java (original)
+++ ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryServlet.java Mon Apr 23 12:15:01 2012
@@ -66,9 +66,8 @@ public class RepositoryServlet extends R
     }
 
     @Override
-    @SuppressWarnings("unchecked")
     public void updated(Dictionary settings) throws ConfigurationException {
-        // nothing special we want to do here
+        super.updated(settings);
     }
 
     @Override

Modified: ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryServletBase.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryServletBase.java?rev=1329199&r1=1329198&r2=1329199&view=diff
==============================================================================
--- ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryServletBase.java (original)
+++ ace/trunk/ace-repository-servlet/src/main/java/org/apache/ace/repository/servlet/RepositoryServletBase.java Mon Apr 23 12:15:01 2012
@@ -18,20 +18,29 @@
  */
 package org.apache.ace.repository.servlet;
 
+import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Dictionary;
+
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
+import org.apache.ace.authentication.api.AuthenticationService;
 import org.apache.ace.range.SortedRangeSet;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedService;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.User;
 
 /**
  * Base class for the repository servlets. Both the repository and the repository replication
@@ -39,12 +48,25 @@ import org.osgi.service.cm.ManagedServic
  * put in two subclasses.
  */
 public abstract class RepositoryServletBase extends HttpServlet implements ManagedService {
+
+    /** A boolean denoting whether or not authentication is enabled. */
+    private static final String KEY_USE_AUTHENTICATION = "authentication.enabled";
+
     private static final int COPY_BUFFER_SIZE = 1024;
+    
     private static final String QUERY = "/query";
+    
     protected static final String TEXT_MIMETYPE = "text/plain";
     protected static final String BINARY_MIMETYPE = "application/octet-stream";
 
+    // injected by Dependency Manager
+    private volatile DependencyManager m_dm; 
+    private volatile AuthenticationService m_authService;
+
+    private volatile boolean m_useAuth = false;
+    
     protected volatile BundleContext m_context;
+    protected volatile LogService m_log;
 
     @Override
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
@@ -168,6 +190,50 @@ public abstract class RepositoryServletB
     protected abstract ServiceReference[] getRepositories(String filter) throws InvalidSyntaxException;
 
     /**
+     * Called by Dependency Manager upon initialization of this component.
+     * 
+     * @param comp the component to initialize, cannot be <code>null</code>.
+     */
+    protected void init(Component comp) {
+        comp.add(m_dm.createServiceDependency()
+            .setService(AuthenticationService.class)
+            .setRequired(m_useAuth)
+            .setInstanceBound(true)
+            );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        if (!authenticate(req)) {
+            // Authentication failed; don't proceed with the original request...
+            resp.sendError(SC_UNAUTHORIZED);
+        } else {
+            // Authentication successful, proceed with original request...
+            super.service(req, resp);
+        }
+    }
+
+    /**
+     * Authenticates, if needed the user with the information from the given request.
+     * 
+     * @param request the request to obtain the credentials from, cannot be <code>null</code>.
+     * @return <code>true</code> if the authentication was successful, <code>false</code> otherwise.
+     */
+    private boolean authenticate(HttpServletRequest request) {
+        if (m_useAuth) {
+            User user = m_authService.authenticate(request);
+            if (user == null) {
+                m_log.log(LogService.LOG_INFO, "Authentication failure!");
+            }
+            return (user != null);
+        }
+        return true;
+    }
+
+    /**
      * Handles a commit command and sends back the response.
      */
     private void handleCommit(String customer, String name, long version, InputStream data, HttpServletResponse response) throws IOException {
@@ -264,8 +330,19 @@ public abstract class RepositoryServletB
         }
     }
 
-    @SuppressWarnings("unchecked")
     public void updated(Dictionary settings) throws ConfigurationException {
-        // nothing special we want to do here, dependency manager will do the propagation
+        if (settings != null) {
+            String useAuthString = (String) settings.get(KEY_USE_AUTHENTICATION);
+            if (useAuthString == null
+                || !("true".equalsIgnoreCase(useAuthString) || "false".equalsIgnoreCase(useAuthString))) {
+                throw new ConfigurationException(KEY_USE_AUTHENTICATION, "Missing or invalid value!");
+            }
+            boolean useAuth = Boolean.parseBoolean(useAuthString);
+
+            m_useAuth = useAuth;
+        }
+        else {
+            m_useAuth = false;
+        }
     }
 }
\ No newline at end of file