Return-Path: X-Original-To: apmail-ace-commits-archive@www.apache.org Delivered-To: apmail-ace-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 94AFF10543 for ; Thu, 10 Oct 2013 14:11:47 +0000 (UTC) Received: (qmail 22772 invoked by uid 500); 10 Oct 2013 14:11:45 -0000 Delivered-To: apmail-ace-commits-archive@ace.apache.org Received: (qmail 22714 invoked by uid 500); 10 Oct 2013 14:11:43 -0000 Mailing-List: contact commits-help@ace.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ace.apache.org Delivered-To: mailing list commits@ace.apache.org Received: (qmail 22665 invoked by uid 99); 10 Oct 2013 14:11:42 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 10 Oct 2013 14:11:42 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 10 Oct 2013 14:11:37 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 18AC42388A32; Thu, 10 Oct 2013 14:11:17 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1530984 [1/5] - in /ace/trunk: org.apache.ace.agent.itest/ org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/ org.apache.ace.agent.update.itest/ org.apache.ace.agent.update.itest/conf/ org.apache.ace.agent.update.itest/src/org/apac... Date: Thu, 10 Oct 2013 14:11:14 -0000 To: commits@ace.apache.org From: jawi@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131010141117.18AC42388A32@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jawi Date: Thu Oct 10 14:11:13 2013 New Revision: 1530984 URL: http://svn.apache.org/r1530984 Log: ACE-330 - limit number of deployment versions per target: - introduced a new concept to configure repositories: RepositoryConfiguration, which can be used to make fiddle settings of repositories, and is used, for example, to limit the number of deployment versions; - moved the OBR url setting needed in the artifact repository, that was scattered throughout the code to RepositoryConfiguration, simplifying some of the calling code; - fixed some concurrency issues in the base repository implementation; - made the integration tests no longer dependent on port 8080 for servlet communication, we could run itests on any port we want. Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryConfigurationImpl.java (with props) ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/RepositoryConfiguration.java (with props) ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/RepositoryConstants.java (with props) Removed: ace/trunk/org.apache.ace.agent.update.itest/conf/ Modified: ace/trunk/org.apache.ace.agent.itest/bnd.bnd ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentDeploymentTest.java ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/BaseAgentTest.java ace/trunk/org.apache.ace.agent.update.itest/bnd.bnd ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/AgentUpdateTest.java ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DiscoveryHandlerImpl.java ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/AuthenticationTestBase.java ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/ObrAuthenticationTest.java ace/trunk/org.apache.ace.client.repository.itest/bnd.bnd ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/TemplateProcessorTest.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/RepositoryAdminLoginContext.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Activator.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Artifact2FeatureAssociationRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ChangeNotifierImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ChangeNotifierManager.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionObjectImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Distribution2TargetAssociationRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DistributionRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Feature2DistributionAssociationRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/FeatureRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ObjectRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminLoginContextImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySerializer.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySet.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetPropertyResolver.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/ArtifactRepository.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/impl/ArtifactTest.java ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/impl/ModelTest.java ace/trunk/org.apache.ace.client.rest.itest/bnd.bnd ace/trunk/org.apache.ace.client.rest.itest/src/org/apache/ace/client/rest/itest/RESTClientTest.java ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/RESTClientServlet.java ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/Workspace.java ace/trunk/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/ConnectionFactoryImplTest.java ace/trunk/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsFactoryTest.java ace/trunk/org.apache.ace.deployment.rp.autoconf.itest/bnd.bnd ace/trunk/org.apache.ace.test/src/org/apache/ace/it/IntegrationTestBase.java ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinClient.java Modified: ace/trunk/org.apache.ace.agent.itest/bnd.bnd URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.itest/bnd.bnd?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.agent.itest/bnd.bnd (original) +++ ace/trunk/org.apache.ace.agent.itest/bnd.bnd Thu Oct 10 14:11:13 2013 @@ -1,8 +1,10 @@ Test-Cases: ${classes;CONCRETE;EXTENDS;junit.framework.TestCase} --runbundles: org.mockito.mockito-all,\ +-runbundles: \ + org.mockito.mockito-all,\ org.apache.ace.agent;version=latest,\ org.apache.ace.test;version=latest,\ org.apache.ace.builder;version=latest,\ + org.apache.felix.configadmin,\ org.apache.felix.dependencymanager,\ org.apache.felix.dependencymanager.shell,\ org.apache.felix.gogo.command,\ @@ -59,10 +61,9 @@ Private-Package: aQute.bnd.annotation.co junit.osgi,\ org.mockito.mockito-all -runsystempackages: sun.reflect --runproperties: org.apache.felix.log.storeDebug=true,\ +-runproperties: \ org.apache.felix.eventadmin.Timeout=0,\ - org.apache.ace.server.port=8080,\ - org.osgi.service.http.port=8080,\ + org.apache.felix.log.storeDebug=true,\ org.apache.felix.log.maxSize=1000 Import-Package: org.apache.ace.agent,\ !org.osgi.service.component.annotations,\ Modified: ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentDeploymentTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentDeploymentTest.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentDeploymentTest.java (original) +++ ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentDeploymentTest.java Thu Oct 10 14:11:13 2013 @@ -41,6 +41,7 @@ import org.apache.ace.agent.Configuratio import org.apache.ace.agent.DeploymentHandler; import org.apache.ace.agent.EventListener; import org.apache.ace.agent.LoggingHandler.Levels; +import org.apache.ace.test.constants.TestConstants; import org.apache.felix.dm.Component; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; @@ -419,10 +420,13 @@ public class AgentDeploymentTest extends public void testGetSizeEstimateForDeploymentPackage() throws Exception { AgentControl control = getService(AgentControl.class); - Map props = createAgentConfiguration(false /* useStreaming */, 10 /* secs */); + Map props = createAgentConfiguration(false /* useStreaming */, 1000 /* secs */); ConfigurationHandler configurationHandler = control.getConfigurationHandler(); configurationHandler.putAll(props); + + // Allow configuration to propagate... + Thread.sleep(100L); synchronized (m_servlet) { m_servlet.reset(); @@ -650,6 +654,7 @@ public class AgentDeploymentTest extends private Map createAgentConfiguration(boolean useStreaming, int syncInterval) { Map props = new HashMap(); + props.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, String.format("http://localhost:%d/", TestConstants.PORT)); props.put(AgentConstants.CONFIG_IDENTIFICATION_AGENTID, AGENT_ID); props.put(AgentConstants.CONFIG_LOGGING_LEVEL, LOGLEVEL.name()); props.put(AgentConstants.CONFIG_CONTROLLER_STREAMING, Boolean.toString(useStreaming)); Modified: ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java (original) +++ ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java Thu Oct 10 14:11:13 2013 @@ -40,7 +40,6 @@ import org.osgi.framework.ServiceRegistr public class AgentExtensionTest extends BaseAgentTest { public void testLifecycle() throws Exception { - AgentControl agentControl = getService(AgentControl.class); assertNotNull(agentControl); Modified: ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/BaseAgentTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/BaseAgentTest.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/BaseAgentTest.java (original) +++ ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/BaseAgentTest.java Thu Oct 10 14:11:13 2013 @@ -85,11 +85,11 @@ public abstract class BaseAgentTest exte Bundle agentBundle = getAgentBundle(); File dataDir = agentBundle.getBundleContext().getDataFile(""); -// System.out.println("BaseAgentTest: Stopping agent bundle"); + // System.out.println("BaseAgentTest: Stopping agent bundle"); agentBundle.stop(); -// System.out.println("BaseAgentTest: Cleaning bundle data dir (" + dataDir + ")"); + // System.out.println("BaseAgentTest: Cleaning bundle data dir (" + dataDir + ")"); cleanDir(dataDir); -// System.out.println("BaseAgentTest: Cleaning system properties"); + // System.out.println("BaseAgentTest: Cleaning system properties"); Set keysBeRemoved = new HashSet(); for (Object key : System.getProperties().keySet()) { if (key instanceof String && ((String) key).startsWith(AgentConstants.CONFIG_KEY_NAMESPACE)) { @@ -99,7 +99,7 @@ public abstract class BaseAgentTest exte for (String removeKey : keysBeRemoved) { System.clearProperty(removeKey); } -// System.out.println("BaseAgentTest: Starting agent bundle"); + // System.out.println("BaseAgentTest: Starting agent bundle"); agentBundle.start(); } Modified: ace/trunk/org.apache.ace.agent.update.itest/bnd.bnd URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/bnd.bnd?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.agent.update.itest/bnd.bnd (original) +++ ace/trunk/org.apache.ace.agent.update.itest/bnd.bnd Thu Oct 10 14:11:13 2013 @@ -2,7 +2,8 @@ # it updates the agent bundle. This causes problems if other tests try to wire to # the the api package after the fact. Test-Cases: ${classes;CONCRETE;EXTENDS;junit.framework.TestCase} --runbundles: org.mockito.mockito-all,\ +-runbundles: \ + org.mockito.mockito-all,\ org.apache.ace.agent;version=latest,\ org.apache.ace.test;version=latest,\ org.apache.felix.dependencymanager,\ @@ -14,11 +15,7 @@ Test-Cases: ${classes;CONCRETE;EXTENDS;j org.apache.ace.authentication.api;version=latest,\ org.apache.ace.connectionfactory;version=latest,\ org.apache.ace.deployment.provider.api;version=latest,\ - org.apache.felix.gogo.command,\ - org.apache.felix.gogo.runtime,\ - org.apache.felix.gogo.shell,\ - org.apache.felix.dependencymanager.shell,\ - org.apache.ace.configurator.impl;version=latest,\ + org.apache.ace.deployment.provider.filebased;version=latest,\ org.apache.felix.configadmin,\ org.apache.ace.http.listener;version=latest,\ biz.aQute.bnd,\ @@ -37,12 +34,10 @@ Private-Package: org.apache.ace.agent.it junit.osgi,\ org.mockito.mockito-all -runsystempackages: sun.reflect --runproperties: org.apache.felix.log.storeDebug=true,\ +-runproperties: \ org.apache.felix.eventadmin.Timeout=0,\ - org.apache.ace.server.port=8080,\ - org.osgi.service.http.port=8080,\ - org.apache.felix.log.maxSize=1000,\ - org.apache.ace.configurator.CONFIG_DIR=../org.apache.ace.agent.update.itest/conf + org.apache.felix.log.storeDebug=true,\ + org.apache.felix.log.maxSize=1000 Import-Package: org.apache.ace.agent,\ !org.osgi.service.component.annotations,\ * Modified: ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/AgentUpdateTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/AgentUpdateTest.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/AgentUpdateTest.java (original) +++ ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/AgentUpdateTest.java Thu Oct 10 14:11:13 2013 @@ -24,6 +24,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.jar.Attributes; @@ -37,7 +39,10 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.ace.agent.AgentConstants; +import org.apache.ace.agent.AgentControl; import org.apache.ace.it.IntegrationTestBase; +import org.apache.ace.test.constants.TestConstants; import org.apache.felix.dm.Component; import org.osgi.framework.Bundle; import org.osgi.framework.Version; @@ -54,70 +59,32 @@ import org.osgi.service.http.HttpService * */ public class AgentUpdateTest extends IntegrationTestBase { - private volatile HttpService m_http; - private volatile AgentUpdateOBRServlet m_servlet; - - private enum Phase { - CORRUPT_STREAM, BUNDLE_DOES_NOT_RESOLVE, BUNDLE_DOES_NOT_START, BUNDLE_WORKS - } - - @Override - protected Component[] getDependencies() { - return new Component[] { - createComponent() - .setImplementation(this) - .add(createServiceDependency().setService(HttpService.class).setRequired(true)) - }; - } - - @Override - public void configureAdditionalServices() throws Exception { - Thread.sleep(200); - m_servlet = new AgentUpdateOBRServlet(); - m_http.registerServlet("/obr", m_servlet, null, null); - } - - @Override - public void doTearDown() throws Exception { - m_http.unregister("/obr"); - } - - public void testAgentUpdate() throws Exception { - final int defaultTimeout = 15; - - CountDownLatch latch; - - latch = m_servlet.setPhase(Phase.CORRUPT_STREAM, new CountDownLatch(1)); - assertTrue("Timed out while recovering from update with broken stream.", latch.await(defaultTimeout, TimeUnit.SECONDS)); - - latch = m_servlet.setPhase(Phase.BUNDLE_DOES_NOT_RESOLVE, new CountDownLatch(1)); - assertTrue("Timed out while recovering from update with agent that does not resolve.", latch.await(defaultTimeout, TimeUnit.SECONDS)); - - latch = m_servlet.setPhase(Phase.BUNDLE_DOES_NOT_START, new CountDownLatch(1)); - assertTrue("Timed out while recovering from update with agent that does not start.", latch.await(defaultTimeout, TimeUnit.SECONDS)); - - latch = m_servlet.setPhase(Phase.BUNDLE_WORKS, new CountDownLatch(1)); - assertTrue("Timed out while starting working bundle?!", latch.await(defaultTimeout, TimeUnit.SECONDS)); - - int timeout = defaultTimeout; - while (timeout-- > 0) { - Thread.sleep(200); - for (Bundle b : m_bundleContext.getBundles()) { - if ("org.apache.ace.agent".equals(b.getSymbolicName())) { - if (b.getVersion().equals(new Version("2.0.0"))) { - return; - } - } + private static class DummyAuditLogServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String pathInfo = req.getPathInfo(); + if ("/send".equals(pathInfo)) { + resp.setStatus(HttpServletResponse.SC_OK); + } else { + resp.setStatus(HttpServletResponse.SC_NOT_FOUND); } } - fail("Timed out waiting for update with new agent."); } - + private static class AgentUpdateOBRServlet extends HttpServlet { private static final long serialVersionUID = 1L; private Phase m_phase; private CountDownLatch m_latch; + public synchronized CountDownLatch setPhase(Phase phase, CountDownLatch latch) { + m_phase = phase; + m_latch = latch; + System.out.println("Updating in phase: " + phase); + return latch; + } + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String path = req.getPathInfo(); @@ -141,13 +108,6 @@ public class AgentUpdateTest extends Int } } - public synchronized CountDownLatch setPhase(Phase phase, CountDownLatch latch) { - m_phase = phase; - m_latch = latch; - System.out.println("Updating in phase: " + phase); - return latch; - } - private InputStream getBundle() throws IOException { return new FileInputStream(new File("../org.apache.ace.agent/generated/org.apache.ace.agent.jar")); } @@ -188,7 +148,84 @@ public class AgentUpdateTest extends Int } } + private enum Phase { + CORRUPT_STREAM, BUNDLE_DOES_NOT_RESOLVE, BUNDLE_DOES_NOT_START, BUNDLE_WORKS + } + private static String createResource(String bsn, String version) { return ""; } + + private volatile HttpService m_http; + private volatile AgentUpdateOBRServlet m_servlet; + + public void testAgentUpdate() throws Exception { + final int defaultTimeout = 150; + + CountDownLatch latch; + + latch = m_servlet.setPhase(Phase.CORRUPT_STREAM, new CountDownLatch(1)); + assertTrue("Timed out while recovering from update with broken stream.", latch.await(defaultTimeout, TimeUnit.SECONDS)); + + latch = m_servlet.setPhase(Phase.BUNDLE_DOES_NOT_RESOLVE, new CountDownLatch(1)); + assertTrue("Timed out while recovering from update with agent that does not resolve.", latch.await(defaultTimeout, TimeUnit.SECONDS)); + + latch = m_servlet.setPhase(Phase.BUNDLE_DOES_NOT_START, new CountDownLatch(1)); + assertTrue("Timed out while recovering from update with agent that does not start.", latch.await(defaultTimeout, TimeUnit.SECONDS)); + + latch = m_servlet.setPhase(Phase.BUNDLE_WORKS, new CountDownLatch(1)); + assertTrue("Timed out while starting working bundle?!", latch.await(defaultTimeout, TimeUnit.SECONDS)); + + int timeout = defaultTimeout; + while (timeout-- > 0) { + Thread.sleep(200); + for (Bundle b : m_bundleContext.getBundles()) { + if ("org.apache.ace.agent".equals(b.getSymbolicName())) { + if (b.getVersion().equals(new Version("2.0.0"))) { + return; + } + } + } + } + fail("Timed out waiting for update with new agent."); + } + + @Override + protected void configureProvisionedServices() throws Exception { + String serverURL = String.format("http://localhost:%d/", TestConstants.PORT); + String obrURL = serverURL.concat("obr/"); + configure("org.apache.ace.deployment.servlet.agent", + "org.apache.ace.server.servlet.endpoint", "/agent", + "obr.url", obrURL, + "authentication.enabled", "false"); + + Map props = new HashMap(); + props.put(AgentConstants.CONFIG_DISCOVERY_SERVERURLS, serverURL); + + AgentControl agentControl = getService(AgentControl.class); + agentControl.getConfigurationHandler().putAll(props); + } + + @Override + protected void configureAdditionalServices() throws Exception { + m_servlet = new AgentUpdateOBRServlet(); + m_http.registerServlet("/obr", m_servlet, null, null); + + m_http.registerServlet("/auditlog", new DummyAuditLogServlet(), null, null); + } + + @Override + protected void doTearDown() throws Exception { + m_http.unregister("/obr"); + m_http.unregister("/auditlog"); + } + + @Override + protected Component[] getDependencies() { + return new Component[] { + createComponent() + .setImplementation(this) + .add(createServiceDependency().setService(HttpService.class).setRequired(true)) + }; + } } Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DiscoveryHandlerImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DiscoveryHandlerImpl.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DiscoveryHandlerImpl.java (original) +++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DiscoveryHandlerImpl.java Thu Oct 10 14:11:13 2013 @@ -134,7 +134,6 @@ public class DiscoveryHandlerImpl extend */ @Override public URL getServerUrl() { - List serverURLs = m_serverURLs; // local reference boolean checkURLs = m_checkURLs; // local value Modified: ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/AuthenticationTestBase.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/AuthenticationTestBase.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/AuthenticationTestBase.java (original) +++ ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/AuthenticationTestBase.java Thu Oct 10 14:11:13 2013 @@ -23,7 +23,6 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; import java.util.Date; import java.util.Enumeration; @@ -46,7 +45,7 @@ public class AuthenticationTestBase exte System.out.println("Log:"); while (e.hasMoreElements()) { LogEntry entry = (LogEntry) e.nextElement(); - System.out.println(" * " + (new Date(entry.getTime())) + " - " + entry.getMessage() + " - " + entry.getBundle().getBundleId() + " - " + entry.getException()); + System.out.println(" * " + (new Date(entry.getTime())) + " - " + entry.getMessage() + " - " + entry.getBundle().getBundleId()); if (entry.getException() != null) { entry.getException().printStackTrace(); } @@ -93,26 +92,22 @@ public class AuthenticationTestBase exte protected final boolean waitForURL(ConnectionFactory connectionFactory, URL url, int responseCode, int timeout) { long deadline = System.currentTimeMillis() + timeout; while (System.currentTimeMillis() < deadline) { + HttpURLConnection connection = null; try { - URLConnection connection = connectionFactory.createConnection(url); + connection = (HttpURLConnection) connectionFactory.createConnection(url); - connection.connect(); - - if (connection instanceof HttpURLConnection) { - int respCode = ((HttpURLConnection) connection).getResponseCode(); - if (respCode == responseCode) { - return true; - } - else { - System.err.println("Got response code " + respCode + " for " + url); - } + int respCode = ((HttpURLConnection) connection).getResponseCode(); + if (respCode == responseCode) { + return true; + } + else { + System.err.println("Got response code " + respCode + " for " + url); } - } - catch (ClassCastException cce) { - throw new IllegalArgumentException("Expected url to be an HTTP url, not: " + url.toString(), cce); } catch (IOException ioe) { - // retry + if (connection != null) { + connection.disconnect(); + } } try { Thread.sleep(100); Modified: ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/ObrAuthenticationTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/ObrAuthenticationTest.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/ObrAuthenticationTest.java (original) +++ ace/trunk/org.apache.ace.authentication.itest/src/org/apache/ace/it/authentication/ObrAuthenticationTest.java Thu Oct 10 14:11:13 2013 @@ -63,6 +63,8 @@ public class ObrAuthenticationTest exten private volatile ConnectionFactory m_connectionFactory; private volatile LogReaderService m_logReader; + private URL m_obrURL; + @Override protected Component[] getDependencies() { return new Component[] { @@ -107,6 +109,10 @@ public class ObrAuthenticationTest exten "org.apache.ace.server.servlet.endpoint", m_endpoint, "authentication.enabled", "true"); + m_obrURL = new URL("http://localhost:" + TestConstants.PORT + m_endpoint + "/"); + + configure("org.apache.ace.client.repository", "obrlocation", m_obrURL.toExternalForm()); + configure("org.apache.ace.obr.storage.file", "OBRInstance", "singleOBRStore", OBRFileStoreConstants.FILE_LOCATION_KEY, fileLocation); @@ -120,15 +126,12 @@ public class ObrAuthenticationTest exten importSingleUser(m_userRepository, userName, password); waitForUser(m_userAdmin, userName); - URL obrURL = new URL("http://localhost:" + TestConstants.PORT + m_endpoint + "/"); - m_artifactRepository.setObrBase(obrURL); - - URL testURL = new URL(obrURL, "repository.xml"); + URL testURL = new URL(m_obrURL, "repository.xml"); assertTrue("Failed to access OBR in time!", waitForURL(m_connectionFactory, testURL, 401, 15000)); m_authConfigPID = configureFactory("org.apache.ace.connectionfactory", - "authentication.baseURL", obrURL.toExternalForm(), + "authentication.baseURL", m_obrURL.toExternalForm(), "authentication.type", "basic", "authentication.user.name", userName, "authentication.user.password", password); Modified: ace/trunk/org.apache.ace.client.repository.itest/bnd.bnd URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository.itest/bnd.bnd?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository.itest/bnd.bnd (original) +++ ace/trunk/org.apache.ace.client.repository.itest/bnd.bnd Thu Oct 10 14:11:13 2013 @@ -73,7 +73,12 @@ Test-Cases: ${classes;CONCRETE;EXTENDS;o org.apache.felix.gogo.runtime,\ org.apache.felix.gogo.shell,\ org.apache.ace.feedback.common;version=latest --runproperties: org.apache.felix.eventadmin.Timeout=0 +-runproperties: \ + org.apache.felix.eventadmin.Timeout=0,\ + org.apache.felix.log.storeDebug=true,\ + org.apache.felix.log.maxSize=-1,\ + org.osgi.framework.bootdelegation="com.yourkit.*,com.sun.*,sun.*,apple.*,com.apple.*" + Private-Package: org.apache.ace.it.repositoryadmin Bundle-Version: 1.0.0 Bundle-Name: Apache ACE Client Repository itest Modified: ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java (original) +++ ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java Thu Oct 10 14:11:13 2013 @@ -18,23 +18,18 @@ */ package org.apache.ace.it.repositoryadmin; -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.TOPIC_ALL; - import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; 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.CopyOnWriteArrayList; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -64,6 +59,7 @@ import org.apache.ace.repository.Reposit import org.apache.ace.repository.impl.constants.RepositoryConstants; import org.apache.ace.test.constants.TestConstants; import org.apache.felix.dm.Component; +import org.apache.felix.dm.ComponentStateListener; import org.osgi.framework.Constants; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; @@ -76,9 +72,9 @@ import org.osgi.service.http.HttpService import org.osgi.service.useradmin.User; import org.osgi.util.tracker.ServiceTracker; -public abstract class BaseRepositoryAdminTest extends IntegrationTestBase implements EventHandler { +public abstract class BaseRepositoryAdminTest extends IntegrationTestBase { - final class MockUser implements User { + final class MockUser implements User { private final String m_name; public MockUser() { @@ -109,58 +105,45 @@ public abstract class BaseRepositoryAdmi protected static final String ENDPOINT_NAME = "/AdminRepTest"; protected static final String HOST = "http://localhost:" + TestConstants.PORT; - protected volatile ConfigurationAdmin m_configAdmin; /* Injected by dependency manager */ - protected volatile RepositoryAdmin m_repositoryAdmin; /* Injected by dependency manager */ - protected volatile ArtifactRepository m_artifactRepository; /* Injected by dependency manager */ - protected volatile Artifact2FeatureAssociationRepository m_artifact2featureRepository; /* Injected by dependency manager */ - protected volatile FeatureRepository m_featureRepository; /* Injected by dependency manager */ - protected volatile Feature2DistributionAssociationRepository m_feature2distributionRepository; /* Injected by dependency manager */ - protected volatile DistributionRepository m_distributionRepository; /* Injected by dependency manager */ - protected volatile Distribution2TargetAssociationRepository m_distribution2targetRepository; /* Injected by dependency manager */ - protected volatile TargetRepository m_targetRepository; /* Injected by dependency manager */ - protected volatile DeploymentVersionRepository m_deploymentVersionRepository; /* Injected by dependency manager */ - protected volatile StatefulTargetRepository m_statefulTargetRepository; /* Injected by dependency manager */ - protected volatile LogStore m_auditLogStore; /* Injected by dependency manager */ - protected volatile List m_waitingForTopic = Collections.synchronizedList(new ArrayList()); - protected volatile Semaphore m_semaphore; - protected URL m_endpoint; - - private volatile boolean m_runAndWaitDebug = false; + protected URL m_obrURL; + + /* All injected by dependency manager */ + protected volatile ConfigurationAdmin m_configAdmin; + protected volatile RepositoryAdmin m_repositoryAdmin; + protected volatile ArtifactRepository m_artifactRepository; + protected volatile Artifact2FeatureAssociationRepository m_artifact2featureRepository; + protected volatile FeatureRepository m_featureRepository; + protected volatile Feature2DistributionAssociationRepository m_feature2distributionRepository; + protected volatile DistributionRepository m_distributionRepository; + protected volatile Distribution2TargetAssociationRepository m_distribution2targetRepository; + protected volatile TargetRepository m_targetRepository; + protected volatile DeploymentVersionRepository m_deploymentVersionRepository; + protected volatile StatefulTargetRepository m_statefulTargetRepository; + protected volatile LogStore m_auditLogStore; - public void handleEvent(Event event) { - if (m_runAndWaitDebug) { - System.err.println("Received event: " + event.getTopic()); - } - if (m_waitingForTopic.remove(event.getTopic())) { - if (m_runAndWaitDebug) { - System.err.println("Event was expected."); - } - if ((m_semaphore != null) && m_waitingForTopic.isEmpty()) { - m_semaphore.release(); - m_runAndWaitDebug = false; - } - } - } - protected final void addObr(String endpoint, String fileLocation) throws IOException, InterruptedException { + String baseURL = String.format("http://localhost:%d%s/", TestConstants.PORT, endpoint); + + m_obrURL = new URL(baseURL); + + configure("org.apache.ace.client.repository", "obrlocation", m_obrURL.toExternalForm()); 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? - URL url = new URL("http://localhost:" + TestConstants.PORT + endpoint + "/repository.xml"); - int response = ((HttpURLConnection) url.openConnection()).getResponseCode(); + URL repoURL = new URL(baseURL + "repository.xml"); + int response = ((HttpURLConnection) repoURL.openConnection()).getResponseCode(); int tries = 0; while ((response != 200) && (tries++ < 50)) { - response = ((HttpURLConnection) url.openConnection()).getResponseCode(); + response = ((HttpURLConnection) repoURL.openConnection()).getResponseCode(); Thread.sleep(100); // If we get interrupted, there will be a good reason for it. } if (tries == 50) { throw new IOException("The OBR servlet does not seem to be responding well. Last response code: " + response); } } - + /* Configure a new repository instance */ protected final void addRepository(String instanceName, String customer, String name, boolean isMaster) throws IOException, InterruptedException, InvalidSyntaxException { @@ -185,16 +168,17 @@ public abstract class BaseRepositoryAdmi } @Override - protected void configureAdditionalServices() throws Exception { + protected void configureAdditionalServices() throws Exception { // remove all repositories, in case a test case does not reach it's cleanup section due to an exception removeAllRepositories(); } @Override - protected void configureProvisionedServices() throws Exception { + protected void configureProvisionedServices() throws Exception { m_endpoint = new URL(HOST + ENDPOINT_NAME); getService(SessionFactory.class).createSession("test-session-ID", null); + configureFactory("org.apache.ace.log.server.store.factory", "name", "auditlog", "authentication.enabled", "false"); } @@ -216,10 +200,10 @@ public abstract class BaseRepositoryAdmi m_repositoryAdmin.logout(true); } catch (Exception ioe) { -// ioe.printStackTrace(System.out); + // ioe.printStackTrace(System.out); } } - + protected ArtifactObject createBasicArtifactObject(String name, String mimetype, String processorPID) throws InterruptedException { Map attr = new HashMap(); @@ -239,7 +223,7 @@ public abstract class BaseRepositoryAdmi protected ArtifactObject createBasicBundleObject(String symbolicName, String version, String processorPID) { return createBasicBundleObject(symbolicName, version, processorPID, null); } - + protected ArtifactObject createBasicBundleObject(String symbolicName, String version, String processorPID, String size) { Map attr = new HashMap(); attr.put(BundleHelper.KEY_SYMBOLICNAME, symbolicName); @@ -291,6 +275,7 @@ public abstract class BaseRepositoryAdmi Properties propsServlet = new Properties(); propsServlet.put(HttpConstants.ENDPOINT, endpoint + "invalid"); propsServlet.put("OBRInstance", "singleOBRServlet"); + propsServlet.put("authentication.enabled", "false"); Configuration configServlet = m_configAdmin.getConfiguration("org.apache.ace.obr.servlet"); configServlet.update(propsServlet); @@ -308,15 +293,8 @@ public abstract class BaseRepositoryAdmi } protected Component[] getDependencies() { - Dictionary topics = new Hashtable(); - topics.put(EventConstants.EVENT_TOPIC, new String[] { PUBLIC_TOPIC_ROOT + "*", - PRIVATE_TOPIC_ROOT + "*", - RepositoryAdmin.PUBLIC_TOPIC_ROOT + "*", - RepositoryAdmin.PRIVATE_TOPIC_ROOT + "*", - TOPIC_ALL }); return new Component[] { createComponent() - .setInterface(EventHandler.class.getName(), topics) .setImplementation(this) .add(createServiceDependency().setService(HttpService.class).setRequired(true)) .add(createServiceDependency().setService(RepositoryAdmin.class).setRequired(true)) @@ -334,18 +312,69 @@ public abstract class BaseRepositoryAdmi }; } - protected T runAndWaitForEvent(Callable callable, boolean debug, String... topic) throws Exception { - m_runAndWaitDebug = debug; - T result = null; - m_waitingForTopic.clear(); - m_waitingForTopic.addAll(Arrays.asList(topic)); - m_semaphore = new Semaphore(0); - result = callable.call(); - assertTrue("We expect the event within a reasonable timeout.", m_semaphore.tryAcquire(15000, TimeUnit.MILLISECONDS)); - m_semaphore = null; - return result; + protected T runAndWaitForEvent(Callable callable, final boolean debug, final String... topicList) throws Exception { + Dictionary topics = new Hashtable(); + topics.put(EventConstants.EVENT_TOPIC, topicList); + + final CopyOnWriteArrayList waitingForTopic = new CopyOnWriteArrayList(Arrays.asList(topicList)); + final CountDownLatch topicLatch = new CountDownLatch(topicList.length); + final CountDownLatch startLatch = new CountDownLatch(1); + + Component comp = m_dependencyManager.createComponent() + .setInterface(EventHandler.class.getName(), topics) + .setImplementation(new EventHandler() { + @Override + public void handleEvent(Event event) { + if (debug) { + System.err.println("Received event: " + event.getTopic()); + } + if (waitingForTopic.remove(event.getTopic())) { + if (debug) { + System.err.println("Event was expected."); + } + topicLatch.countDown(); + } + } + }); + comp.addStateListener(new ComponentStateListener() { + public void stopping(Component comp) { + } + + public void stopped(Component comp) { + } + + public void starting(Component comp) { + } + + public void started(Component comp) { + startLatch.countDown(); + } + }); + + if (debug) { + System.err.printf("Waiting for events: %s.%n", Arrays.toString(topicList)); + } + + m_dependencyManager.add(comp); + + try { + assertTrue(startLatch.await(1500, TimeUnit.MILLISECONDS)); + + T result = callable.call(); + + boolean r = topicLatch.await(15000, TimeUnit.MILLISECONDS); + if (!r && debug) { + System.err.println("EVENT NOTIFICATION FAILED!!!"); + } + assertTrue("We expect the event within a reasonable timeout.", r); + + return result; + } + finally { + m_dependencyManager.remove(comp); + } } - + protected void startRepositoryService() throws IOException { // configure the (replication)repository servlets configure("org.apache.ace.repository.servlet.RepositoryServlet", HttpConstants.ENDPOINT, @@ -354,32 +383,36 @@ public abstract class BaseRepositoryAdmi @Override protected void doTearDown() throws Exception { - try { - m_repositoryAdmin.logout(true); - } catch (RuntimeException e) { - // Ignore... - } - - try { - cleanUp(); - } catch (Exception e) { - // Ignore... - } - - try { - removeAllRepositories(); - } catch (IOException e) { - // Ignore... - } + try { + m_repositoryAdmin.logout(true); + } + catch (RuntimeException e) { + // Ignore... + } + + try { + cleanUp(); + } + catch (Exception e) { + // Ignore... + } + + try { + removeAllRepositories(); + } + catch (IOException e) { + // Ignore... + } } private void clearRepository(ObjectRepository rep) { for (T entity : rep.get()) { try { - rep.remove(entity); - } catch (RuntimeException e) { - // Ignore; try to recover... - } + rep.remove(entity); + } + catch (RuntimeException e) { + // Ignore; try to recover... + } } assertEquals("Something went wrong clearing the repository.", 0, rep.get().size()); } @@ -387,10 +420,11 @@ public abstract class BaseRepositoryAdmi private void clearResourceProcessors(ArtifactRepository rep) { for (ArtifactObject entity : rep.getResourceProcessors()) { try { - rep.remove(entity); - } catch (RuntimeException e) { - // Ignore; try to recover... - } + rep.remove(entity); + } + catch (RuntimeException e) { + // Ignore; try to recover... + } } assertEquals("Something went wrong clearing the repository.", 0, rep.get().size()); } Modified: ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java (original) +++ ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/RepositoryAdminTest.java Thu Oct 10 14:11:13 2013 @@ -55,7 +55,7 @@ public class RepositoryAdminTest extends public void testAssociationsWithMovingEndpoints() throws Exception { final ArtifactObject b1 = createBasicBundleObject("thebundle", "1", null); final FeatureObject g1 = createBasicFeatureObject("thefeature"); - + final Artifact2FeatureAssociation bg = runAndWaitForEvent(new Callable() { public Artifact2FeatureAssociation call() throws Exception { Map properties = new HashMap(); @@ -152,7 +152,7 @@ public class RepositoryAdminTest extends .setLocation(m_endpoint).setCustomer("apache").setName("deployment").setWriteable()); m_repositoryAdmin.login(loginContext); - + m_repositoryAdmin.checkout(); runAndWaitForEvent(new Callable() { @@ -188,14 +188,14 @@ public class RepositoryAdminTest extends assertTrue("Turning on the autoapprove should not automatically approve whatever was waiting.", sgo.needsApprove()); sgo.approve(); - + runAndWaitForEvent(new Callable() { public Void call() throws Exception { m_repositoryAdmin.commit(); return null; } - }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); - + }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + assertFalse("We approved the new version by hand, so we should not need approval.", sgo.needsApprove()); runAndWaitForEvent(new Callable() { @@ -212,8 +212,8 @@ public class RepositoryAdminTest extends m_repositoryAdmin.commit(); return null; } - }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); - + }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + assertFalse("With autoapprove on, adding new deployment information should still not need approval (at least, after the two CHANGED events).", sgo.needsApprove()); runAndWaitForEvent(new Callable() { @@ -270,7 +270,6 @@ public class RepositoryAdminTest extends // Supply the OBR. addObr("/obr", "store"); - m_artifactRepository.setObrBase(new URL(HOST + "/obr/")); m_artifactRepository.importArtifact(temp.toURI().toURL(), true); @@ -345,8 +344,8 @@ public class RepositoryAdminTest extends } /** - * Tests read only repository access: marking a repository as readonly for a login should - * mean that it does not get committed, but local changes will stay around between logins. + * Tests read only repository access: marking a repository as readonly for a login should mean that it does not get + * committed, but local changes will stay around between logins. */ public void testReadOnlyRepositoryAccess() throws Exception { User user1 = new MockUser(); @@ -441,8 +440,7 @@ public class RepositoryAdminTest extends } /** - * Tests the behavior with logging in and out (with multiple users), and communication - * with the server. + * Tests the behavior with logging in and out (with multiple users), and communication with the server. * * @throws Exception */ Modified: ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/TemplateProcessorTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/TemplateProcessorTest.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/TemplateProcessorTest.java (original) +++ ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/TemplateProcessorTest.java Thu Oct 10 14:11:13 2013 @@ -50,7 +50,6 @@ import org.apache.ace.client.repository. import org.apache.ace.client.repository.object.TargetObject; import org.apache.ace.client.repository.stateful.StatefulTargetObject; import org.apache.ace.client.repository.stateful.StatefulTargetObject.StoreState; -import org.apache.ace.test.constants.TestConstants; import org.apache.felix.dm.Component; import org.osgi.framework.InvalidSyntaxException; import org.osgi.service.useradmin.User; @@ -180,7 +179,7 @@ public class TemplateProcessorTest exten m_repositoryAdmin.commit(); return null; } - }, true, TOPIC_STATUS_CHANGED); + }, false, TOPIC_STATUS_CHANGED); assertEquals("Store state for target should still be new, because the resource processor is missing.", StoreState.New, sgo.getStoreState()); @@ -258,7 +257,6 @@ public class TemplateProcessorTest exten setupRepository(); addObr("/obr", "store"); - m_artifactRepository.setObrBase(new URL("http://localhost:" + TestConstants.PORT + "/obr/")); // create some template things String xmlHeader = Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/RepositoryAdminLoginContext.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/RepositoryAdminLoginContext.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/RepositoryAdminLoginContext.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/RepositoryAdminLoginContext.java Thu Oct 10 14:11:13 2013 @@ -97,12 +97,4 @@ public interface RepositoryAdminLoginCon * @return this context, never null. */ public RepositoryAdminLoginContext add(BaseRepositoryContext repositoryContext); - - /** - * When uploads are needed, this is the base OBR that will be used. - * - * @param base The URL of the OBR to be used. - * @return this object, to allow chaining. - */ - public RepositoryAdminLoginContext setObrBase(URL base); } Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Activator.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Activator.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Activator.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Activator.java Thu Oct 10 14:11:13 2013 @@ -40,6 +40,7 @@ import org.apache.ace.client.repository. import org.apache.ace.client.repository.object.TargetObject; import org.apache.ace.client.repository.repository.ArtifactRepository; import org.apache.ace.client.repository.repository.DeploymentVersionRepository; +import org.apache.ace.client.repository.repository.RepositoryConfiguration; import org.apache.ace.client.repository.repository.TargetRepository; import org.apache.ace.client.repository.stateful.StatefulTargetRepository; import org.apache.ace.client.repository.stateful.impl.StatefulTargetRepositoryImpl; @@ -59,49 +60,53 @@ import org.osgi.service.log.LogService; import org.osgi.service.prefs.PreferencesService; /** - * Activator for the RepositoryAdmin bundle. Creates the repository admin, which internally - * creates all required repositories. + * Activator for the RepositoryAdmin bundle. Creates the repository admin, which internally creates all required + * repositories. */ public class Activator extends DependencyActivatorBase implements SessionFactory, ManagedService { - private static final String PID = "org.apache.ace.client.repository"; - private static final String KEY_SHOWUNREGISTEREDTARGETS = "showunregisteredtargets"; - private final Map m_sessions = new HashMap(); - private volatile DependencyManager m_dependencyManager; - private boolean m_showUnregisteredTargets; + /** + * Small container that keeps the session-related services for us. + */ + private static final class SessionData { + private final List m_services = new ArrayList(); - @Override - public synchronized void init(BundleContext context, DependencyManager manager) throws Exception { - m_dependencyManager = manager; - - Properties props = new Properties(); - props.put(Constants.SERVICE_PID, PID); - props.put(CommandProcessor.COMMAND_SCOPE, "clientrepo"); - props.put(CommandProcessor.COMMAND_FUNCTION, new String[] { "sessions" }); - - manager.add(createComponent() - .setInterface(new String[] { SessionFactory.class.getName(), ManagedService.class.getName() }, props) - .setImplementation(this) - ); - } + final void addComponents(DependencyManager manager, Component... comps) { + synchronized (m_services) { + for (Component c : comps) { + m_services.add(c); + } + } - /** Shell command to show the active sessions. */ - public void sessions() { - synchronized (m_sessions) { - if (m_sessions.isEmpty()) { - System.out.println("No sessions."); - } - else { - System.out.println("Sessions:"); - for (Entry session : m_sessions.entrySet()) { - System.out.println(" * " + session.getKey()); - } - } + for (Component c : comps) { + manager.add(c); + } + } + + final boolean isEmpty() { + synchronized (m_services) { + return m_services.isEmpty(); + } + } + + final void removeAllComponents(DependencyManager manager) { + Component[] comps; + synchronized (m_services) { + comps = m_services.toArray(new Component[m_services.size()]); + m_services.clear(); + } + + for (Component c : comps) { + manager.remove(c); + } } } - - @Override - public synchronized void destroy(BundleContext context, DependencyManager manager) throws Exception { - } + + private static final String PID = "org.apache.ace.client.repository"; + + private final Map m_sessions = new HashMap(); + private final RepositoryConfigurationImpl m_repoConfiguration = new RepositoryConfigurationImpl(); + + private volatile DependencyManager m_dependencyManager; public void createSession(String sessionID, Map sessionConfiguration) { SessionData sessionData = null; @@ -111,19 +116,17 @@ public class Activator extends Dependenc m_sessions.put(sessionID, sessionData); } } - - boolean showUnregisteredTargets = m_showUnregisteredTargets; - if (sessionConfiguration != null) { - Object value = sessionConfiguration.get(KEY_SHOWUNREGISTEREDTARGETS); - showUnregisteredTargets = parseBoolean(value, m_showUnregisteredTargets); - } // Allow session to be created outside the lock; to avoid potential deadlocks... if (sessionData != null) { - createSessionServices(sessionData, sessionID, showUnregisteredTargets); + createSessionServices(sessionData, sessionID, getConfiguration(sessionConfiguration)); } } + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + } + public void destroySession(String sessionID) { SessionData sessionData = null; synchronized (m_sessions) { @@ -135,16 +138,53 @@ public class Activator extends Dependenc destroySessionServices(sessionData, sessionID); } } - + + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + m_dependencyManager = manager; + + Properties props = new Properties(); + props.put(Constants.SERVICE_PID, PID); + props.put(CommandProcessor.COMMAND_SCOPE, "clientrepo"); + props.put(CommandProcessor.COMMAND_FUNCTION, new String[] { "sessions" }); + + manager.add(createComponent() + .setInterface(new String[] { SessionFactory.class.getName(), ManagedService.class.getName() }, props) + .setImplementation(this) + ); + } + + /** Shell command to show the active sessions. */ + public void sessions() { + synchronized (m_sessions) { + if (m_sessions.isEmpty()) { + System.out.println("No sessions."); + } + else { + System.out.println("Sessions:"); + for (Entry session : m_sessions.entrySet()) { + System.out.println(" * " + session.getKey()); + } + } + } + } + + @Override + public void updated(Dictionary properties) throws ConfigurationException { + m_repoConfiguration.update(properties); + } + /** * Creates all necessary session-related service for the given session. * - * @param sd the session data to keep the session-related services; - * @param sessionID the session ID to use. + * @param sd + * the session data to keep the session-related services; + * @param sessionID + * the session ID to use. */ @SuppressWarnings("unchecked") - private void createSessionServices(SessionData sd, String sessionID, boolean showUnregisteredTargets) { - RepositoryAdminImpl rai = new RepositoryAdminImpl(sessionID); + private void createSessionServices(SessionData sd, String sessionID, RepositoryConfiguration repoConfig) { + RepositoryAdminImpl rai = new RepositoryAdminImpl(sessionID, repoConfig); Component repositoryAdminComponent = createComponent() .setInterface(RepositoryAdmin.class.getName(), rai.getSessionProps()) .setImplementation(rai) @@ -168,12 +208,12 @@ public class Activator extends Dependenc Distribution2TargetAssociation.PRIVATE_TOPIC_ALL, TargetObject.PRIVATE_TOPIC_ALL, DeploymentVersionObject.PRIVATE_TOPIC_ALL, - RepositoryAdmin.PRIVATE_TOPIC_HOLDUNTILREFRESH, - RepositoryAdmin.PRIVATE_TOPIC_REFRESH, - RepositoryAdmin.PRIVATE_TOPIC_LOGIN + RepositoryAdmin.PRIVATE_TOPIC_HOLDUNTILREFRESH, + RepositoryAdmin.PRIVATE_TOPIC_REFRESH, + RepositoryAdmin.PRIVATE_TOPIC_LOGIN }); - - StatefulTargetRepositoryImpl statefulTargetRepositoryImpl = new StatefulTargetRepositoryImpl(sessionID, showUnregisteredTargets); + + StatefulTargetRepositoryImpl statefulTargetRepositoryImpl = new StatefulTargetRepositoryImpl(sessionID, repoConfig); Component statefulTargetRepositoryComponent = createComponent() .setInterface(new String[] { StatefulTargetRepository.class.getName(), EventHandler.class.getName() }, topic) .setImplementation(statefulTargetRepositoryImpl) @@ -184,7 +224,7 @@ public class Activator extends Dependenc .add(createServiceDependency().setService(BundleHelper.class).setRequired(true)) .add(createServiceDependency().setService(EventAdmin.class).setRequired(true)) .add(createServiceDependency().setService(LogService.class).setRequired(false)); - + rai.addPreCommitMember(statefulTargetRepositoryImpl); // Publish our components to our session data for later use... @@ -194,69 +234,29 @@ public class Activator extends Dependenc /** * Removes the session-related services from the session. * - * @param sd the session data that keeps the session-related services; - * @param sessionID the session ID to use. + * @param sd + * the session data that keeps the session-related services; + * @param sessionID + * the session ID to use. */ private void destroySessionServices(SessionData sd, String sessionID) { sd.removeAllComponents(m_dependencyManager); } /** - * Small container that keeps the session-related services for us. + * Creates a copy of the repository configuration that is supposed to remain stable for the duration of a session, + * if there are settings overridden. If no settings are to be overridden, the current (mutable!) repository + * configuration is used. + * + * @param sessionConfiguration + * the session configuration overriding the current repository configuration values, can be + * null to keep the current configuration as-is. + * @return a new {@link RepositoryConfiguration} instance, never null. */ - private static final class SessionData { - private final List m_services = new ArrayList(); - - final void addComponents(DependencyManager manager, Component... comps) { - synchronized (m_services) { - for (Component c : comps) { - m_services.add(c); - } - } - - for (Component c : comps) { - manager.add(c); - } - } - - final void removeAllComponents(DependencyManager manager) { - Component[] comps; - synchronized (m_services) { - comps = m_services.toArray(new Component[m_services.size()]); - m_services.clear(); - } - - for (Component c : comps) { - manager.remove(c); - } - } - - final boolean isEmpty() { - synchronized (m_services) { - return m_services.isEmpty(); - } + private RepositoryConfiguration getConfiguration(Map sessionConfiguration) { + if (sessionConfiguration != null) { + return new RepositoryConfigurationImpl(m_repoConfiguration, sessionConfiguration); } + return m_repoConfiguration; } - - @Override - public void updated(Dictionary properties) throws ConfigurationException { - if (properties == null) { - // by default, we show unregistered targets - m_showUnregisteredTargets = true; - } - else { - Object value = properties.get(KEY_SHOWUNREGISTEREDTARGETS); - m_showUnregisteredTargets = parseBoolean(value, true); - } - } - - private boolean parseBoolean(Object value, boolean defaultValue) { - if (value instanceof String) { - return Boolean.parseBoolean((String) value); - } - else if (value instanceof Boolean) { - return (Boolean) value; - } - return defaultValue; - } } Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Artifact2FeatureAssociationRepositoryImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Artifact2FeatureAssociationRepositoryImpl.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Artifact2FeatureAssociationRepositoryImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/Artifact2FeatureAssociationRepositoryImpl.java Thu Oct 10 14:11:13 2013 @@ -24,6 +24,7 @@ import org.apache.ace.client.repository. import org.apache.ace.client.repository.object.ArtifactObject; import org.apache.ace.client.repository.object.FeatureObject; import org.apache.ace.client.repository.repository.Artifact2FeatureAssociationRepository; +import org.apache.ace.client.repository.repository.RepositoryConfiguration; import org.osgi.framework.InvalidSyntaxException; import com.thoughtworks.xstream.io.HierarchicalStreamReader; @@ -38,8 +39,8 @@ public class Artifact2FeatureAssociation private final ArtifactRepositoryImpl m_artifactRepository; private final FeatureRepositoryImpl m_featureRepository; - public Artifact2FeatureAssociationRepositoryImpl(ArtifactRepositoryImpl artifactRepository, FeatureRepositoryImpl featureRepository, ChangeNotifier notifier) { - super(notifier, XML_NODE); + public Artifact2FeatureAssociationRepositoryImpl(ArtifactRepositoryImpl artifactRepository, FeatureRepositoryImpl featureRepository, ChangeNotifier notifier, RepositoryConfiguration repoConfig) { + super(notifier, XML_NODE, repoConfig); m_artifactRepository = artifactRepository; m_featureRepository = featureRepository; } Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java Thu Oct 10 14:11:13 2013 @@ -40,6 +40,7 @@ import org.apache.ace.client.repository. import org.apache.ace.client.repository.object.ArtifactObject; import org.apache.ace.client.repository.object.TargetObject; import org.apache.ace.client.repository.repository.ArtifactRepository; +import org.apache.ace.client.repository.repository.RepositoryConfiguration; import org.apache.ace.connectionfactory.ConnectionFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @@ -69,10 +70,9 @@ public class ArtifactRepositoryImpl exte private volatile ConnectionFactory m_connectionFactory; private final Map m_helpers = new HashMap(); - private URL m_obrBase; - public ArtifactRepositoryImpl(ChangeNotifier notifier) { - super(notifier, XML_NODE); + public ArtifactRepositoryImpl(ChangeNotifier notifier, RepositoryConfiguration repoConfig) { + super(notifier, XML_NODE, repoConfig); } public List getResourceProcessors() { @@ -111,12 +111,6 @@ public class ArtifactRepositoryImpl exte } @Override - ArtifactObjectImpl createNewInhabitant(Map attributes) { - ArtifactHelper helper = getHelper(attributes.get(ArtifactObject.KEY_MIMETYPE)); - return new ArtifactObjectImpl(helper.checkAttributes(attributes), helper.getMandatoryAttributes(), this, this); - } - - @Override ArtifactObjectImpl createNewInhabitant(Map attributes, Map tags) { ArtifactHelper helper = getHelper(attributes.get(ArtifactObject.KEY_MIMETYPE)); ArtifactObjectImpl ao = new ArtifactObjectImpl(helper.checkAttributes(attributes), helper.getMandatoryAttributes(), tags, this, this); @@ -280,6 +274,13 @@ public class ArtifactRepositoryImpl exte } } + /** + * @return the OBR base URL to use, can be null. + */ + public URL getObrBase() { + return getRepositoryConfiguration().getOBRLocation(); + } + public ArtifactObject importArtifact(URL artifact, boolean upload) throws IllegalArgumentException, IOException { try { if ((artifact == null) || (artifact.toString().length() == 0)) { @@ -295,11 +296,11 @@ public class ArtifactRepositoryImpl exte return importArtifact(artifact, recognizer, helper, mimetype, false, upload); } catch (IllegalArgumentException iae) { - m_log.log(LogService.LOG_INFO, "Error importing artifact: " + iae.getMessage()); + m_log.log(LogService.LOG_WARNING, "Error importing artifact: " + iae.getMessage(), iae); throw iae; } catch (IOException ioe) { - m_log.log(LogService.LOG_INFO, "Error storing artifact: " + ioe.getMessage()); + m_log.log(LogService.LOG_WARNING, "Error storing artifact: " + ioe.getMessage(), ioe); throw ioe; } } @@ -322,11 +323,11 @@ public class ArtifactRepositoryImpl exte return importArtifact(artifact, recognizer, helper, mimetype, true, upload); } catch (IllegalArgumentException iae) { - m_log.log(LogService.LOG_INFO, "Error importing artifact: " + iae.getMessage()); + m_log.log(LogService.LOG_WARNING, "Error importing artifact: " + iae.getMessage(), iae); throw iae; } catch (IOException ioe) { - m_log.log(LogService.LOG_INFO, "Error storing artifact: " + ioe.getMessage()); + m_log.log(LogService.LOG_WARNING, "Error storing artifact: " + ioe.getMessage(), ioe); throw ioe; } } @@ -371,10 +372,12 @@ public class ArtifactRepositoryImpl exte */ private void checkURL(URL artifact) throws IllegalArgumentException { + URLConnection connection = null; // First, check whether we can actually reach something from this URL. InputStream is = null; try { - is = openInputStream(artifact); + connection = m_connectionFactory.createConnection(artifact); + is = connection.getInputStream(); } catch (IOException ioe) { throw new IllegalArgumentException("Artifact " + artifact + " does not point to a valid file."); @@ -388,6 +391,9 @@ public class ArtifactRepositoryImpl exte // Too bad, nothing to do. } } + if (connection instanceof HttpURLConnection) { + ((HttpURLConnection) connection).disconnect(); + } } // Then, check whether the name is legal. @@ -413,48 +419,54 @@ public class ArtifactRepositoryImpl exte * for any problem uploading the artifact. */ private String upload(URL artifact, String filename, String mimetype) throws IOException { - if (m_obrBase == null) { + URL obrBase = getObrBase(); + if (obrBase == null) { throw new IOException("There is no storage available for this artifact."); } + URLConnection inputConn = null; + URLConnection outputConn = null; InputStream input = null; OutputStream output = null; - URL url = m_obrBase; + URL url = obrBase; String location = null; + + int blockSize = 8192; + try { - input = openInputStream(artifact); + inputConn = m_connectionFactory.createConnection(artifact); + input = inputConn.getInputStream(); - if(filename != null){ - url = new URL(m_obrBase,"?filename=" + filename); - } - URLConnection connection = m_connectionFactory.createConnection(url); - - connection.setDoOutput(true); - connection.setDoInput(true); - connection.setUseCaches(false); + if (filename != null) { + url = new URL(obrBase, "?filename=" + filename); + } - connection.setRequestProperty("Content-Type", mimetype); - if (connection instanceof HttpURLConnection) { + outputConn = m_connectionFactory.createConnection(url); + outputConn.setDoOutput(true); + outputConn.setDoInput(true); + outputConn.setUseCaches(false); + outputConn.setRequestProperty("Content-Type", mimetype); + if (outputConn instanceof HttpURLConnection) { // ACE-294: enable streaming mode causing only small amounts of memory to be // used for this commit. Otherwise, the entire input stream is cached into // memory prior to sending it to the server... - ((HttpURLConnection) connection).setChunkedStreamingMode(8192); + ((HttpURLConnection) outputConn).setChunkedStreamingMode(blockSize); } - output = connection.getOutputStream(); + output = outputConn.getOutputStream(); - byte[] buffer = new byte[4 * 1024]; + byte[] buffer = new byte[blockSize]; for (int count = input.read(buffer); count != -1; count = input.read(buffer)) { output.write(buffer, 0, count); } output.close(); - if (connection instanceof HttpURLConnection) { - int responseCode = ((HttpURLConnection) connection).getResponseCode(); + if (outputConn instanceof HttpURLConnection) { + int responseCode = ((HttpURLConnection) outputConn).getResponseCode(); switch (responseCode) { case HttpURLConnection.HTTP_CREATED: - location = connection.getHeaderField("Location"); + location = outputConn.getHeaderField("Location"); break; case HttpURLConnection.HTTP_CONFLICT: throw new IOException("Artifact already exists in storage."); @@ -466,7 +478,7 @@ public class ArtifactRepositoryImpl exte } } catch (IOException ioe) { - throw new IOException("Error importing artifact " + artifact.toString() + ": " + ioe.getMessage()); + throw new IOException("Error importing artifact " + artifact.toString() + ": " + ioe.getMessage(), ioe); } finally { if (input != null) { @@ -477,6 +489,10 @@ public class ArtifactRepositoryImpl exte // Not much we can do } } + if (inputConn instanceof HttpURLConnection) { + ((HttpURLConnection) inputConn).disconnect(); + } + if (output != null) { try { output.close(); @@ -485,22 +501,21 @@ public class ArtifactRepositoryImpl exte // Not much we can do } } + if (outputConn instanceof HttpURLConnection) { + ((HttpURLConnection) outputConn).disconnect(); + } } return location; } - public void setObrBase(URL obrBase) { - m_obrBase = obrBase; - } - public String preprocessArtifact(ArtifactObject artifact, TargetObject target, String targetID, String version) throws IOException { ArtifactPreprocessor preprocessor = getHelper(artifact.getMimetype()).getPreprocessor(); if (preprocessor == null) { return artifact.getURL(); } else { - return preprocessor.preprocess(artifact.getURL(), new TargetPropertyResolver(target), targetID, version, m_obrBase); + return preprocessor.preprocess(artifact.getURL(), new TargetPropertyResolver(target), targetID, version, getObrBase()); } } @@ -514,20 +529,11 @@ public class ArtifactRepositoryImpl exte } } - public URL getObrBase() { - return m_obrBase; - } - /** * Custom comparator which sorts service references by service rank, highest rank first. */ - private static Comparator SERVICE_RANK_COMPARATOR = new Comparator() { // TODO - // ServiceReferences - // are - // comparable - // by - // default - // now + // TODO ServiceReferences are comparable by default now + private static Comparator SERVICE_RANK_COMPARATOR = new Comparator() { public int compare(ServiceReference o1, ServiceReference o2) { int rank1 = 0; int rank2 = 0; @@ -550,11 +556,6 @@ public class ArtifactRepositoryImpl exte } }; - private InputStream openInputStream(URL artifactURL) throws IOException { - URLConnection connection = m_connectionFactory.createConnection(artifactURL); - return connection.getInputStream(); - } - /** * Converts a given URL to a {@link ArtifactResource} that abstracts the way we access the contents of the URL away * from the URL itself. This way, we can avoid having to pass authentication credentials, or a Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationImpl.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationImpl.java Thu Oct 10 14:11:13 2013 @@ -166,7 +166,6 @@ public class AssociationImplendpoint. */ - @SuppressWarnings("unchecked") private List locateEndpoint(ObjectRepositoryImpl objectRepositoryImpl, Filter filter, List endpoints, int cardinality, Class clazz, boolean notify) { List candidates = objectRepositoryImpl.get(filter); Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationRepositoryImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationRepositoryImpl.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationRepositoryImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/AssociationRepositoryImpl.java Thu Oct 10 14:11:13 2013 @@ -25,6 +25,7 @@ import java.util.Map; import org.apache.ace.client.repository.Association; import org.apache.ace.client.repository.AssociationRepository; import org.apache.ace.client.repository.RepositoryObject; +import org.apache.ace.client.repository.repository.RepositoryConfiguration; /** @@ -43,8 +44,8 @@ import org.apache.ace.client.repository. public abstract class AssociationRepositoryImpl, T extends Association> extends ObjectRepositoryImpl implements AssociationRepository { private Object m_lock = new Object(); - public AssociationRepositoryImpl(ChangeNotifier notifier, String xmlNode) { - super(notifier, xmlNode); + public AssociationRepositoryImpl(ChangeNotifier notifier, String xmlNode, RepositoryConfiguration repoConfig) { + super(notifier, xmlNode, repoConfig); } @SuppressWarnings("unchecked") @@ -58,7 +59,9 @@ public abstract class AssociationReposit attributes.put(Association.LEFT_CARDINALITY, "" + leftCardinality); attributes.put(Association.RIGHT_CARDINALITY, "" + rightCardinality); association = (T) createNewInhabitant(attributes); - add(association); + if (!add(association)) { + return null; + } } catch (Exception e) { // We have not been able to instantiate our constructor. Not much to do about that. @@ -111,4 +114,13 @@ public abstract class AssociationReposit super.remove(entity); } } + + /** + * Creates a new inhabitant of the repository based on a map of attributes. + * + * @param attributes + * A map of attributes + * @return The new inhabitant. + */ + abstract I createNewInhabitant(Map attributes); } Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ChangeNotifierImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ChangeNotifierImpl.java?rev=1530984&r1=1530983&r2=1530984&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ChangeNotifierImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ChangeNotifierImpl.java Thu Oct 10 14:11:13 2013 @@ -26,16 +26,17 @@ import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; /** - * ChangeNotifierImpl provides a basic implementation of a ChangeNotifier, intended to be used - * by classes related to the RepositoryAdmin.
+ * ChangeNotifierImpl provides a basic implementation of a ChangeNotifier, intended to be used by classes related to the + * RepositoryAdmin.
*
* Topics are built up in the following fashion: *
    - *
  • ...TopicRoot All topics start with a TopicRoot, which is the same for all related classes, and ends with a "/". - * There can be internal and external topics, hence two TopicRoot parameters in the constructor.
  • - *
  • entityRoot This is followed by a class-specific root, usually consisting of the classname with an added "/".
  • - *
  • Finally, for each call to notifyChanged, a topic can be specified, which is something like - * "CHANGED" or "ADDED".
  • + *
  • ...TopicRoot All topics start with a TopicRoot, which is the same for all related classes, and ends with a + * "/". There can be internal and external topics, hence two TopicRoot parameters in the constructor.
  • + *
  • entityRoot This is followed by a class-specific root, usually consisting of the classname with an added + * "/".
  • + *
  • Finally, for each call to notifyChanged, a topic can be specified, which is something like "CHANGED" + * or "ADDED".
  • *
*/ public class ChangeNotifierImpl implements ChangeNotifier { @@ -48,10 +49,15 @@ public class ChangeNotifierImpl implemen /** * Creates a new ChangeNotifierImpl. - * @param eventAdmin An EventAdmin to send events to. - * @param privateTopicRoot The root of all private topics; see TopicRoot in the description of this class. - * @param publicTopicRoot The root of all public topics; see TopicRoot in the description of this class. - * @param entityRoot A class-specific root for the class which will use this ChangeNotifierImpl. + * + * @param eventAdmin + * An EventAdmin to send events to. + * @param privateTopicRoot + * The root of all private topics; see TopicRoot in the description of this class. + * @param publicTopicRoot + * The root of all public topics; see TopicRoot in the description of this class. + * @param entityRoot + * A class-specific root for the class which will use this ChangeNotifierImpl. */ ChangeNotifierImpl(EventAdmin eventAdmin, String privateTopicRoot, String publicTopicRoot, String entityRoot, String sessionID) { m_eventAdmin = eventAdmin; @@ -71,7 +77,7 @@ public class ChangeNotifierImpl implemen public void notifyChanged(String topic, Properties props, boolean internalOnly) { props = addSession(props); - m_eventAdmin.sendEvent(new Event(m_privateTopicRoot + m_entityRoot + topic,(Dictionary) props)); + m_eventAdmin.sendEvent(new Event(m_privateTopicRoot + m_entityRoot + topic, (Dictionary) props)); if (!internalOnly) { m_eventAdmin.postEvent(new Event(m_publicTopicRoot + m_entityRoot + topic, (Dictionary) props)); }