You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by br...@apache.org on 2013/08/28 14:28:02 UTC
svn commit: r1518177 [1/4] - in /ace/trunk: org.apache.ace.agent.itest/
org.apache.ace.agent.itest/conf/
org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/
org.apache.ace.agent.launcher/
org.apache.ace.agent.launcher/src/org/apache/ace/agent/la...
Author: bramk
Date: Wed Aug 28 12:28:00 2013
New Revision: 1518177
URL: http://svn.apache.org/r1518177
Log:
ACE-347 API refactor, code cleanup, new features
* Added deployment integration testing
* Removed unneeded 3rd party (DM/commons-codec)
* Added propper connection failure handling
* Added support for extension service
* Improved configuration
* more..
Added:
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
- copied, changed from r1516756, ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/ManagementAgentTest.java
ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/BaseAgentTest.java
ace/trunk/org.apache.ace.agent.launcher/launcher-example.properties
ace/trunk/org.apache.ace.agent.update.itest/ (with props)
ace/trunk/org.apache.ace.agent.update.itest/.classpath
ace/trunk/org.apache.ace.agent.update.itest/.gitignore
ace/trunk/org.apache.ace.agent.update.itest/.project
ace/trunk/org.apache.ace.agent.update.itest/.settings/
ace/trunk/org.apache.ace.agent.update.itest/.settings/org.eclipse.jdt.core.prefs
ace/trunk/org.apache.ace.agent.update.itest/bnd.bnd
ace/trunk/org.apache.ace.agent.update.itest/build.xml
ace/trunk/org.apache.ace.agent.update.itest/conf/
ace/trunk/org.apache.ace.agent.update.itest/conf/org.apache.ace.deployment.servlet.agent.cfg
ace/trunk/org.apache.ace.agent.update.itest/src/
ace/trunk/org.apache.ace.agent.update.itest/src/.gitignore
ace/trunk/org.apache.ace.agent.update.itest/src/org/
ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/
ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/
ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/
ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/
ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/AgentUpdateTest.java
ace/trunk/org.apache.ace.agent.update.itest/test/
ace/trunk/org.apache.ace.agent.update.itest/test/.gitignore
ace/trunk/org.apache.ace.agent/README
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/EventListener.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/EventsHandler.java
- copied, changed from r1517469, ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/LoggingHandler.java
- copied, changed from r1517469, ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConnectionUtil.java
Removed:
ace/trunk/org.apache.ace.agent.itest/conf/
ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/ManagementAgentTest.java
ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/ManagementAgentUpdateTest.java
ace/trunk/org.apache.ace.agent.launcher/launcher.properties
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ReflectionUtil.java
Modified:
ace/trunk/org.apache.ace.agent.itest/bnd.bnd
ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/Launcher.java
ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/launcher-defaults.properties
ace/trunk/org.apache.ace.agent/bnd.bnd
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentContext.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentControl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentUpdateHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConfigurationHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConnectionHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/DeploymentHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/DiscoveryHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/DownloadResult.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/FeedbackChannel.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/FeedbackHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/IdentificationHandler.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/RetryAfterException.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentControlImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentUpdateHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ComponentBase.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConfigurationHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConnectionHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DefaultController.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DependencyTrackerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DeploymentHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DiscoveryHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DownloadCallableImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DownloadHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventLoggerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/CustomControllerTest.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DeploymentHandlerImplTest.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DownloadHandlerTest.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/FeedbackHandlerImplTest.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/IdentificationHandlerImplTest.java
ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java
ace/trunk/org.apache.ace.builder/.classpath
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=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent.itest/bnd.bnd (original)
+++ ace/trunk/org.apache.ace.agent.itest/bnd.bnd Wed Aug 28 12:28:00 2013
@@ -2,33 +2,62 @@ Test-Cases: ${classes;CONCRETE;EXTENDS;j
-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.dependencymanager,\
- osgi.cmpn,\
- org.apache.felix.http.jetty,\
- org.apache.ace.deployment.servlet;version=latest,\
- org.apache.ace.deployment.api;version=latest,\
- org.apache.ace.deployment.streamgenerator;version=latest,\
- org.apache.ace.authentication.api;version=latest,\
- org.apache.ace.connectionfactory;version=latest,\
- org.apache.ace.deployment.provider.api;version=latest,\
+ org.apache.felix.dependencymanager.shell,\
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.felix.configadmin,\
- org.apache.ace.http.listener;version=latest
-Private-Package: org.apache.ace.agent.itest
+ org.apache.felix.http.jetty,\
+ biz.aQute.bnd,\
+ osgi.cmpn
+Private-Package: aQute.bnd.annotation.component,\
+ aQute.bnd.help,\
+ aQute.bnd.service.action,\
+ aQute.lib.deployer,\
+ aQute.lib.osgi.eclipse,\
+ aQute.libg.filelock,\
+ aQute.bnd.build,\
+ aQute.bnd.maven.support,\
+ aQute.bnd.settings,\
+ aQute.libg.command,\
+ aQute.libg.tuple,\
+ org.apache.ace.agent.itest,\
+ aQute.lib.osgi,\
+ aQute.bnd.annotation,\
+ aQute.bnd.annotation.metatype,\
+ aQute.bnd.component,\
+ aQute.bnd.make,\
+ aQute.bnd.make.component,\
+ aQute.bnd.make.metatype,\
+ aQute.bnd.maven,\
+ aQute.bnd.service,\
+ aQute.lib.base64,\
+ aQute.lib.collections,\
+ aQute.lib.filter,\
+ aQute.lib.hex,\
+ aQute.lib.io,\
+ aQute.lib.tag,\
+ aQute.libg.cryptography,\
+ aQute.libg.generics,\
+ aQute.libg.header,\
+ aQute.libg.qtokens,\
+ aQute.libg.reporter,\
+ aQute.libg.sed,\
+ aQute.libg.tarjan,\
+ aQute.libg.version
-runee: JavaSE-1.6
-runvm: -ea
-runfw: org.apache.felix.framework
-buildpath: osgi.core;version='[4.2,5)',\
- junit.osgi,\
- org.mockito.mockito-all,\
org.apache.ace.agent;version=latest,\
+ org.apache.ace.builder;version=latest,\
org.apache.ace.test;version=latest,\
org.apache.felix.dependencymanager,\
- org.apache.felix.http.jetty
+ org.apache.felix.http.jetty,\
+ biz.aQute.bnd,\
+ junit.osgi,\
+ org.mockito.mockito-all
-runsystempackages: sun.reflect
-runproperties: org.apache.felix.log.storeDebug=true,\
org.apache.felix.eventadmin.Timeout=0,\
@@ -36,6 +65,7 @@ Private-Package: org.apache.ace.agent.it
org.osgi.service.http.port=8080,\
org.apache.felix.log.maxSize=1000
Import-Package: org.apache.ace.agent,\
+ !org.osgi.service.component.annotations,\
*
Bundle-Version: 1.0.0
Bundle-Name: Apache ACE Agent itest
Added: 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=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentDeploymentTest.java (added)
+++ ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentDeploymentTest.java Wed Aug 28 12:28:00 2013
@@ -0,0 +1,453 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.agent.itest;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+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.agent.EventListener;
+import org.apache.ace.agent.LoggingHandler;
+import org.apache.ace.builder.DeploymentPackageBuilder;
+import org.apache.felix.dm.Component;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.http.HttpService;
+
+import aQute.lib.osgi.Builder;
+import aQute.lib.osgi.Jar;
+
+/**
+ * Tests updating the management agent. In fact it tests different failure paths first, and finally gets to update the
+ * agent. The tests it does are:
+ * <ul>
+ * <li>Try to update to a corrupt bundle (with some random garbage injected in the JAR file).</li>
+ * <li>Try to update to a bundle that does not resolve because of some impossible import package statement.</li>
+ * <li>Try to update to a bundle that does resolve, but does not start because of a non-existing bundle activator.</li>
+ * <li>Update to a new version of the agent (actually, it's the same bundle, but with a different version.</li>
+ * </ul>
+ */
+public class AgentDeploymentTest extends BaseAgentTest {
+
+ private enum Failure {
+ EMPTY_STREAM, CORRUPT_STREAM, ABORT_STREAM, VERSIONS_RETRY_AFTER, DEPLOYMENT_RETRY_AFTER
+
+ }
+
+ private volatile TestDeploymentServlet m_servlet;
+ private volatile HttpService m_http;
+ private volatile TestEventListener m_listener;
+
+ private final Version version1 = Version.parseVersion("1.0.0");
+ private final Version version2 = Version.parseVersion("2.0.0");
+ private final Version version3 = Version.parseVersion("3.0.0");
+ private final Version version4 = Version.parseVersion("4.0.0");
+ private final Version version5 = Version.parseVersion("5.0.0");
+ private final Version version6 = Version.parseVersion("6.0.0");
+
+ private TestPackage m_package1;
+ private TestPackage m_package2;
+ private TestPackage m_package3;
+ private TestPackage m_package4;
+ private TestPackage m_package5;
+ private TestPackage m_package6;
+
+ @Override
+ protected Component[] getDependencies() {
+ m_listener = new TestEventListener();
+ return new Component[] {
+ createComponent()
+ .setImplementation(this)
+ .add(createServiceDependency().setService(HttpService.class).setRequired(true)),
+ createComponent()
+ .setInterface(EventListener.class.getName(), null)
+ .setImplementation(m_listener)
+ };
+ }
+
+ @Override
+ public void configureAdditionalServices() throws Exception {
+
+ TestBundle bundle1v1 = new TestBundle("bundle1", version1);
+ TestBundle bundle1v2 = new TestBundle("bundle1", version2);
+ TestBundle bundle2v1 = new TestBundle("bundle2", version1);
+ TestBundle bundle2v2 = new TestBundle("bundle2", version2);
+
+ TestBundle bundle3v1 = new TestBundle("bundle3", version1, Constants.BUNDLE_ACTIVATOR, "no.Such.Class");
+ TestBundle bundle3v2 = new TestBundle("bundle3", version2);
+
+ m_package1 = new TestPackage("007", version1, bundle1v1);
+ m_package2 = new TestPackage("007", version2, bundle1v2);
+ m_package3 = new TestPackage("007", version3, bundle1v2, bundle2v1);
+ m_package4 = new TestPackage("007", version4, bundle1v2, bundle2v2);
+ m_package5 = new TestPackage("007", version5, bundle1v2, bundle2v2, bundle3v1);
+ m_package6 = new TestPackage("007", version6, bundle1v2, bundle2v2, bundle3v2);
+
+ m_servlet = new TestDeploymentServlet("007");
+ m_http.registerServlet("/deployment", m_servlet, null, null);
+ m_http.registerServlet("/agent", new TestUpdateServlet(), null, null);
+ m_http.registerServlet("/auditlog", new TestAuditlogServlet(), null, null);
+
+ }
+
+ public void tearDown() throws Exception {
+ m_http.unregister("/deployment");
+ m_http.unregister("/agent");
+ m_http.unregister("/auditlog");
+ }
+
+ public void testDeployment() throws Exception {
+
+ AgentControl control = getService(AgentControl.class);
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_LOGGING_LEVEL, LoggingHandler.Levels.DEBUG.name());
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_IDENTIFICATION_AGENTID, "007");
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_CONTROLLER_STREAMING, "true");
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_CONTROLLER_SYNCDELAY, "1");
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_CONTROLLER_SYNCINTERVAL, "2");
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_CONTROLLER_RETRIES, "2");
+ waitForInstalledVersion(Version.emptyVersion);
+
+ expectSuccessfulDeployment(m_package1, Failure.VERSIONS_RETRY_AFTER);
+ expectSuccessfulDeployment(m_package2, Failure.DEPLOYMENT_RETRY_AFTER);
+ expectSuccessfulDeployment(m_package3, Failure.EMPTY_STREAM);
+ expectSuccessfulDeployment(m_package4, Failure.CORRUPT_STREAM);
+ expectSuccessfulDeployment(m_package5, Failure.ABORT_STREAM);
+ expectSuccessfulDeployment(m_package6, null);
+
+ resetAgentBundleState();
+
+ control = getService(AgentControl.class);
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_LOGGING_LEVEL, LoggingHandler.Levels.DEBUG.name());
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_IDENTIFICATION_AGENTID, "007");
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_CONTROLLER_STREAMING, "true");
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_CONTROLLER_SYNCDELAY, "2");
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_CONTROLLER_SYNCINTERVAL, "2");
+ control.getConfigurationHandler().put(AgentConstants.CONFIG_CONTROLLER_RETRIES, "2");
+ m_servlet.clearPackages();
+
+ control.getConfigurationHandler().put("ace.agent.controller.updateStreaming", "false");
+ control.getConfigurationHandler().put("ace.agent.identification.agentId", "007");
+ control.getConfigurationHandler().put("ace.agent.controller.syncDelay", "2");
+ waitForInstalledVersion(Version.emptyVersion);
+
+ expectSuccessfulDeployment(m_package1, Failure.VERSIONS_RETRY_AFTER);
+ expectSuccessfulDeployment(m_package2, Failure.DEPLOYMENT_RETRY_AFTER);
+ expectSuccessfulDeployment(m_package3, Failure.EMPTY_STREAM);
+ expectSuccessfulDeployment(m_package4, Failure.CORRUPT_STREAM);
+ expectSuccessfulDeployment(m_package5, Failure.ABORT_STREAM);
+ expectSuccessfulDeployment(m_package6, null);
+ }
+
+ private void expectSuccessfulDeployment(TestPackage dpackage, Failure failure) throws Exception {
+ synchronized (m_servlet) {
+ if (failure != null) {
+ m_servlet.setFailure(Failure.VERSIONS_RETRY_AFTER);
+ }
+ m_servlet.addPackage(dpackage);
+ m_listener.getTopics().clear();
+ }
+ waitForEventReceived("org/osgi/service/deployment/INSTALL");
+ waitForEventReceived("org/osgi/service/deployment/COMPLETE");
+ waitForInstalledVersion(dpackage.getVersion());
+ }
+
+ private void waitForInstalledVersion(Version version) throws Exception {
+ ServiceReference reference = m_bundleContext.getServiceReference(AgentControl.class.getName());
+ AgentControl control = (AgentControl) m_bundleContext.getService(reference);
+ int timeout = 100;
+ while (!control.getDeploymentHandler().getInstalledVersion().equals(version)) {
+ Thread.sleep(100);
+ if (timeout-- <= 0) {
+ m_bundleContext.ungetService(reference);
+ fail("Timed out while waiting for deployment " + version);
+ }
+ }
+ m_bundleContext.ungetService(reference);
+ }
+
+ private void waitForEventReceived(String topic) throws Exception {
+ int timeout = 100;
+ while (!m_listener.getTopics().contains(topic)) {
+ Thread.sleep(100);
+ if (timeout-- <= 0) {
+ fail("Timed out while waiting for event " + topic);
+ }
+ }
+ }
+
+ private static File createPackage(String name, Version version, File... bundles) throws Exception {
+ DeploymentPackageBuilder builder = DeploymentPackageBuilder.createDeploymentPackage(name, version.toString());
+ for (File bundle : bundles) {
+ builder.addBundle(bundle.toURI().toURL());
+ }
+ File file = File.createTempFile("testpackage", ".jar");
+ OutputStream fos = new FileOutputStream(file);
+ builder.generate(fos);
+ fos.close();
+ return file;
+ }
+
+ private static File createBundle(String bsn, Version version, String... headers) throws Exception {
+ Builder b = new Builder();
+ b.setProperty("Bundle-SymbolicName", bsn);
+ b.setProperty("Bundle-Version", version.toString());
+ for (int i = 0; i < headers.length; i += 2) {
+ b.setProperty(headers[i], headers[i + 1]);
+ }
+ b.setProperty("Include-Resource", "bnd.bnd");
+ Jar jar = b.build();
+ jar.getManifest(); // Not sure whether this is needed...
+ File file = File.createTempFile("testbundle", ".jar");
+ jar.write(file);
+ return file;
+ }
+
+ private static class TestBundle {
+
+ private final String m_name;
+ private final Version m_version;
+ private final String[] m_headers;
+ private final File m_file;
+
+ public TestBundle(String name, Version version, String... headers) throws Exception {
+ m_name = name;
+ m_version = version;
+ m_headers = headers;
+ m_file = createBundle(name, version, headers);
+ }
+
+ public String getName() {
+ return m_name;
+ }
+
+ public Version getVersion() {
+ return m_version;
+ }
+
+ public String[] getHeaders() {
+ return m_headers;
+ }
+
+ public File getFile() {
+ return m_file;
+ }
+ }
+
+ private static class TestPackage {
+
+ private final String m_name;
+ private final Version m_version;
+ private final TestBundle[] m_bundles;
+ private final File m_file;
+
+ public TestPackage(String name, Version version, TestBundle... bundles) throws Exception {
+ m_name = name;
+ m_version = version;
+ m_bundles = bundles;
+
+ File[] files = new File[bundles.length];
+ for (int i = 0; i < bundles.length; i++) {
+ files[i] = bundles[i].getFile();
+ }
+ m_file = createPackage(name, version, files);
+ }
+
+ public String getName() {
+ return m_name;
+ }
+
+ public Version getVersion() {
+ return m_version;
+ }
+
+ public TestBundle[] getBundles() {
+ return m_bundles;
+ }
+
+ public File getFile() {
+ return m_file;
+ }
+ }
+
+ private static class TestEventListener implements EventListener {
+
+ private final List<String> m_topics = new ArrayList<String>();
+
+ @Override
+ public synchronized void handle(String topic, Map<String, String> payload) {
+ System.out.println("Event: " + topic + " => " + payload);
+ m_topics.add(topic);
+ }
+
+ public List<String> getTopics() {
+ return m_topics;
+ }
+ }
+
+ private static class TestDeploymentServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ private final Map<String, TestPackage> m_packages = new HashMap<String, TestPackage>();
+ private final String m_agentId;
+
+ private Failure m_failure;
+
+ public TestDeploymentServlet(String agentId) {
+ m_agentId = agentId;
+ }
+
+ @Override
+ protected synchronized void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+ String pathinfoTail = req.getPathInfo().replaceFirst("/" + m_agentId + "/versions/?", "");
+ if (pathinfoTail.equals("")) {
+ sendVersions(resp);
+ }
+ else {
+ TestPackage dpackage = m_packages.get(pathinfoTail);
+ if (dpackage == null) {
+ throw new IllegalStateException("Test error! Should never happen... " + pathinfoTail);
+ }
+ sendPackage(dpackage, resp);
+ }
+ }
+
+ public synchronized void addPackage(TestPackage testPackage) {
+ m_packages.put(testPackage.getVersion().toString(), testPackage);
+ }
+
+ public synchronized void clearPackages() {
+ m_packages.clear();
+ }
+
+ public synchronized void setFailure(Failure failure) {
+ m_failure = failure;
+ }
+
+ private void sendPackage(TestPackage dpackage, HttpServletResponse resp) throws IOException {
+ if (m_failure == Failure.DEPLOYMENT_RETRY_AFTER) {
+ resp.addHeader("Retry-After", "3");
+ resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+ m_failure = null;
+ return;
+ }
+
+ long middle = dpackage.getFile().length() / 2;
+ FileInputStream fis = null;
+ OutputStream os = null;
+ try {
+ fis = new FileInputStream(dpackage.getFile());
+ os = resp.getOutputStream();
+
+ if (m_failure == Failure.EMPTY_STREAM) {
+ m_failure = null;
+ return;
+ }
+
+ if (m_failure == Failure.CORRUPT_STREAM) {
+ os.write("garbage".getBytes());
+ m_failure = null;
+ }
+
+ int b;
+ int count = 0;
+ while ((b = fis.read()) != -1) {
+ os.write(b);
+ if (count++ == middle && m_failure == Failure.ABORT_STREAM) {
+ m_failure = null;
+ break;
+ }
+ }
+
+ }
+ finally {
+ fis.close();
+ if (os != null) {
+ os.close();
+ }
+ }
+ }
+
+ private void sendVersions(HttpServletResponse resp) throws IOException {
+ if (m_failure == Failure.VERSIONS_RETRY_AFTER) {
+ resp.addHeader("Retry-After", "3");
+ resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+ m_failure = null;
+ return;
+ }
+ PrintWriter writer = resp.getWriter();
+ for (String version : m_packages.keySet()) {
+ writer.println(version);
+ }
+ writer.close();
+ resp.setContentType("text/plain");
+ resp.setStatus(200);
+ }
+ }
+
+ private static class TestUpdateServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ resp.setContentType("text/plain");
+ resp.setStatus(200);
+ }
+ }
+
+ private static class TestAuditlogServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ // FIXME Ignoring auditlog.. but why do we get and empty send if we set range to high?
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ response.setContentType("text/plain");
+ PrintWriter writer = response.getWriter();
+ writer.println(request.getParameter("tid") + "," + request.getParameter("logid") + ",0-10");
+ writer.close();
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ InputStream is = request.getInputStream();
+ while (is.read() != -1) {
+ }
+ is.close();
+ response.setContentType("text/plain");
+ }
+ }
+}
Copied: ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java (from r1516756, ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/ManagementAgentTest.java)
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java?p2=ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java&p1=ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/ManagementAgentTest.java&r1=1516756&r2=1518177&rev=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/ManagementAgentTest.java (original)
+++ ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/AgentExtensionTest.java Wed Aug 28 12:28:00 2013
@@ -18,22 +18,113 @@
*/
package org.apache.ace.agent.itest;
-import junit.framework.Assert;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Properties;
+import org.apache.ace.agent.AgentConstants;
import org.apache.ace.agent.AgentControl;
-import org.apache.ace.it.IntegrationTestBase;
+import org.apache.ace.agent.ConnectionHandler;
+import org.apache.ace.agent.DiscoveryHandler;
+import org.apache.ace.agent.IdentificationHandler;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
/**
- * Integration test for Management Agent Configuration
- *
+ * Integration test for Agent life-cycle. When the agent is configured to use external handler services, the agent must
+ * only be active and available if and when those external services are available. In addition, when multiple services
+ * for a handler are published the highest ranked should be used.
*/
-public class ManagementAgentTest extends IntegrationTestBase {
+public class AgentExtensionTest extends BaseAgentTest {
- public void testOneAgentConfiguration() throws Exception {
+ public void testLifecycle() throws Exception {
- // agent factory should be up
AgentControl agentControl = getService(AgentControl.class);
- Assert.assertNotNull(agentControl);
+ assertNotNull(agentControl);
+ getAgentBundle().stop();
+ System.setProperty(AgentConstants.CONFIG_IDENTIFICATION_DISABLED, "true");
+ System.setProperty(AgentConstants.CONFIG_DISCOVERY_DISABLED, "true");
+ System.setProperty(AgentConstants.CONFIG_CONNECTION_DISABLED, "true");
+ getAgentBundle().start();
+
+ assertNull(locateService(AgentControl.class));
+
+ ServiceRegistration idreg1 = registerIdentification("TEST1", 1);
+ assertNull(locateService(AgentControl.class));
+ ServiceRegistration direg1 = registerDiscovery(new URL("http://test1"), 1);
+ assertNull(locateService(AgentControl.class));
+ ServiceRegistration coreg1 = registerConnectionHandler();
+ assertNotNull(locateService(AgentControl.class));
+
+ assertEquals("TEST1", locateService(AgentControl.class).getAgentId());
+
+ ServiceRegistration idreg2 = registerIdentification("TEST2", 2);
+
+ assertEquals("TEST2", locateService(AgentControl.class).getAgentId());
+
+ idreg2.unregister();
+
+ assertEquals("TEST1", locateService(AgentControl.class).getAgentId());
+
+ idreg1.unregister();
+
+ assertNull(locateService(AgentControl.class));
+
+ direg1.unregister();
+ coreg1.unregister();
+ }
+
+ private ServiceRegistration registerIdentification(final String id, final int rank) {
+ return m_bundleContext
+ .registerService(IdentificationHandler.class.getName(), new IdentificationHandler() {
+
+ @Override
+ public String getAgentId() {
+ return id;
+ }
+ }, new Properties() {
+ {
+ put(Constants.SERVICE_RANKING, rank);
+ }
+ });
+
+ }
+
+ private ServiceRegistration registerDiscovery(final URL url, final int rank) {
+ return m_bundleContext
+ .registerService(DiscoveryHandler.class.getName(), new DiscoveryHandler() {
+
+ @Override
+ public URL getServerUrl() {
+ return url;
+ }
+ }, new Properties() {
+ {
+ put(Constants.SERVICE_RANKING, rank);
+ }
+ });
+
+ }
+
+ private ServiceRegistration registerConnectionHandler() {
+ return m_bundleContext
+ .registerService(ConnectionHandler.class.getName(), new ConnectionHandler() {
+
+ @Override
+ public URLConnection getConnection(URL url) throws IOException {
+ return url.openConnection();
+ }
+ }, null);
+ }
+
+ private <T> T locateService(Class<T> iface) {
+ ServiceReference reference = m_bundleContext.getServiceReference(iface.getName());
+ if (reference == null) {
+ return null;
+ }
+ return (T) m_bundleContext.getService(reference);
}
}
Added: 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=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/BaseAgentTest.java (added)
+++ ace/trunk/org.apache.ace.agent.itest/src/org/apache/ace/agent/itest/BaseAgentTest.java Wed Aug 28 12:28:00 2013
@@ -0,0 +1,69 @@
+package org.apache.ace.agent.itest;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Stack;
+
+import org.apache.ace.agent.AgentConstants;
+import org.apache.ace.agent.AgentControl;
+import org.apache.ace.it.IntegrationTestBase;
+import org.osgi.framework.Bundle;
+
+public abstract class BaseAgentTest extends IntegrationTestBase {
+
+ @Override
+ public void configureProvisionedServices() throws Exception {
+ resetAgentBundleState();
+ }
+
+ protected void resetAgentBundleState() throws Exception {
+ Bundle agentBundle = getAgentBundle();
+ System.out.println("BaseAgentTest: Stopping agent bundle");
+ File dataDir = agentBundle.getBundleContext().getDataFile("");
+ agentBundle.stop();
+ System.out.println("BaseAgentTest: Cleaning bundle data dir");
+ cleanDir(dataDir);
+ System.out.println("BaseAgentTest: Cleaning system properties");
+ Set<String> keysBeRemoved = new HashSet<String>();
+ for (Object key : System.getProperties().keySet()) {
+ if (key instanceof String && ((String) key).startsWith(AgentConstants.CONFIG_KEY_NAMESPACE)) {
+ keysBeRemoved.add((String) key);
+ }
+ }
+ for (String removeKey : keysBeRemoved) {
+ System.clearProperty(removeKey);
+ }
+ System.out.println("BaseAgentTest: Starting agent bundle");
+ agentBundle.start();
+ }
+
+ protected Bundle getAgentBundle() {
+ for (Bundle bundle : m_bundleContext.getBundles()) {
+ if (bundle.getSymbolicName().equals(AgentControl.class.getPackage().getName())) {
+ return bundle;
+ }
+ }
+ throw new IllegalStateException("No agentBundle found");
+ }
+
+ private void cleanDir(File dir) {
+ if (!dir.isDirectory()) {
+ throw new IllegalStateException();
+ }
+ Stack<File> dirs = new Stack<File>();
+ dirs.push(dir);
+ while (!dirs.isEmpty()) {
+ File currentDir = dirs.pop();
+ File[] files = currentDir.listFiles();
+ for (File file : files) {
+ if (file.isDirectory()) {
+ dirs.push(file);
+ }
+ else {
+ file.delete();
+ }
+ }
+ }
+ }
+}
Added: ace/trunk/org.apache.ace.agent.launcher/launcher-example.properties
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.launcher/launcher-example.properties?rev=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.launcher/launcher-example.properties (added)
+++ ace/trunk/org.apache.ace.agent.launcher/launcher-example.properties Wed Aug 28 12:28:00 2013
@@ -0,0 +1,33 @@
+
+#
+# Agent properties:
+#
+# These properties control the agent and may also be set through system properties.
+# For a complete list and documentation see the AgentConstants.
+#
+agent.logging.level=DEBUG
+
+agent.identification.disabled=false
+agent.identification.agentid=Agent007
+
+agent.discovery.disabled=false
+agent.discovery.serverurls=http://localhost:80,http://localhost:8080
+agent.discovery.checking=true
+
+agent.controller.disabled=false
+agent.controller.syncdelay=10
+agent.controller.syncinterval=10
+agent.controller.streaming=false
+agent.controller.fixpackages=true
+agent.controller.retries=1
+
+agent.connection.disabled=false
+agent.connection.authtype=NONE
+
+agent.feedback.channels=auditlog,custom
+
+
+#
+# Framework properties; Keys are prepended by 'framework.'
+#
+framework.felix.log.level=1
\ No newline at end of file
Modified: ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/Launcher.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/Launcher.java?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/Launcher.java (original)
+++ ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/Launcher.java Wed Aug 28 12:28:00 2013
@@ -35,7 +35,9 @@ import java.util.Map.Entry;
import java.util.Properties;
import java.util.ServiceLoader;
+import org.apache.ace.agent.AgentConstants;
import org.apache.ace.agent.AgentControl;
+import org.apache.ace.agent.LoggingHandler;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
@@ -94,33 +96,12 @@ public class Launcher {
}
}
+ // convenience debug override
if (command.hasOption("v")) {
configuration.put("verbose", "true");
+ configuration.put(AgentConstants.CONFIG_LOGGING_LEVEL, LoggingHandler.Levels.DEBUG.name());
}
- // // overwrite with user args
- // if (command.hasOption("a")) {
- // configuration.put(CONFIG_IDENTIFICATION_KEY,
- // command.getOptionValue("a"));
- // }
- // if (command.hasOption("s")) {
- // configuration.put(CONFIG_SERVERURL_KEY, command.getOptionValue("s"));
- // }
- // if (command.hasOption("v")) {
- // configuration.put(CONFIG_LOGLEVEL_KEY, "DEBUG");
- // }
- //
- // // set defaults
- // if (!configuration.containsKey(CONFIG_LOGLEVEL_KEY)) {
- // configuration.put(CONFIG_LOGLEVEL_KEY, "INFO");
- // }
- //
- // // basic checks
- // if (!configuration.containsKey(CONFIG_IDENTIFICATION_KEY)) {
- // System.err.println("No agent specified");
- // System.exit(1);
- // }
-
new Launcher(configuration).run();
}
@@ -179,18 +160,18 @@ public class Launcher {
* Main execution logic of the launcher; Start a framework, install bundles and pass configuration to the
* {@link AgentFactory}.
*
- * @throws Exception
- * on failure
+ * @throws Exception on failure
*/
public void run() throws Exception {
try {
FrameworkFactory frameworkFactory = loadFrameworkFactory();
Map<String, String> frameworkProperties = createFrameworkProperties();
- if (m_verbose)
+ if (m_verbose) {
System.out.println("Launching OSGI framework\n factory\t: "
+ frameworkFactory.getClass().getName()
+ "\n properties\t: " + frameworkProperties);
+ }
Framework framework = frameworkFactory.newFramework(frameworkProperties);
BundleContext context = null;
@@ -202,10 +183,17 @@ public class Launcher {
installBundles(context, bundleProvider);
}
+ for (Entry<String, String> entry : m_configuration.entrySet()) {
+ if (entry.getKey().startsWith(AgentConstants.CONFIG_KEY_NAMESPACE)) {
+ System.setProperty(entry.getKey(), entry.getValue());
+ }
+ }
+
framework.start();
- if (m_verbose)
+ if (m_verbose) {
System.out.println("Startup complete..");
+ }
framework.waitForStop(0);
}
catch (Exception e) {
@@ -219,8 +207,9 @@ public class Launcher {
private Bundle[] installBundles(BundleContext context, BundleProvider extensionProvider) throws BundleException, IOException {
List<Bundle> bundles = new ArrayList<Bundle>();
for (String bundleName : extensionProvider.getBundleNames()) {
- if (m_verbose)
+ if (m_verbose) {
System.out.println("Installing bundle\t: " + bundleName);
+ }
InputStream inputStream = null;
try {
inputStream = extensionProvider.getInputStream(bundleName);
@@ -241,8 +230,7 @@ public class Launcher {
* Load {@link FrameworkFactory} through the {@link ServiceLoader}.
*
* @return the first factory
- * @throws Exception
- * on failure
+ * @throws Exception on failure
*/
private FrameworkFactory loadFrameworkFactory() throws Exception {
ServiceLoader<FrameworkFactory> frameworkFactoryLoader = ServiceLoader.load(FrameworkFactory.class);
@@ -257,8 +245,7 @@ public class Launcher {
* Load {@link BundleProvider}s through the {@link ServiceLoader}.
*
* @return list of providers
- * @throws Exception
- * on failure
+ * @throws Exception on failure
*/
private BundleProvider[] loadBundleProviders() throws Exception {
ServiceLoader<BundleProvider> bundleFactoryLoader = ServiceLoader.load(BundleProvider.class);
@@ -274,15 +261,14 @@ public class Launcher {
* Build the framework launch properties.
*
* @return the launch properties
- * @throws Exception
- * on failure
+ * @throws Exception on failure
*/
private Map<String, String> createFrameworkProperties() throws Exception {
Map<String, String> frameworkProperties = new HashMap<String, String>();
for (Entry<String, String> entry : m_configuration.entrySet()) {
if (entry.getKey().startsWith("framework.")) {
String frameworkKey = entry.getKey().replaceFirst("framework.", "");
- String frameworkValue = m_configuration.get(entry.getValue());
+ String frameworkValue = m_configuration.get(entry.getKey());
frameworkProperties.put(frameworkKey, frameworkValue);
}
}
@@ -301,8 +287,7 @@ public class Launcher {
* Determines the export clause for the agent API package.
*
* @return the export clause
- * @throws Exception
- * on failure
+ * @throws Exception on failure
*/
private String getAgentApiPackageSpec() throws IOException {
String apiPackage = AgentControl.class.getPackage().getName();
Modified: ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/launcher-defaults.properties
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/launcher-defaults.properties?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/launcher-defaults.properties (original)
+++ ace/trunk/org.apache.ace.agent.launcher/src/org/apache/ace/agent/launcher/launcher-defaults.properties Wed Aug 28 12:28:00 2013
@@ -1 +1,2 @@
-#TODO
\ No newline at end of file
+#TODO
+#framework.felix.log.level=4
\ No newline at end of file
Propchange: ace/trunk/org.apache.ace.agent.update.itest/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Aug 28 12:28:00 2013
@@ -0,0 +1,7 @@
+bin
+bin_test
+generated
+store
+bundle-cache
+felix-cache
+
Added: ace/trunk/org.apache.ace.agent.update.itest/.classpath
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/.classpath?rev=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.update.itest/.classpath (added)
+++ ace/trunk/org.apache.ace.agent.update.itest/.classpath Wed Aug 28 12:28:00 2013
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="bin" path="src"/>
+ <classpathentry kind="src" output="bin_test" path="test"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Added: ace/trunk/org.apache.ace.agent.update.itest/.gitignore
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/.gitignore?rev=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.update.itest/.gitignore (added)
+++ ace/trunk/org.apache.ace.agent.update.itest/.gitignore Wed Aug 28 12:28:00 2013
@@ -0,0 +1,3 @@
+/bin/
+/bin_test/
+/generated/
Added: ace/trunk/org.apache.ace.agent.update.itest/.project
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/.project?rev=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.update.itest/.project (added)
+++ ace/trunk/org.apache.ace.agent.update.itest/.project Wed Aug 28 12:28:00 2013
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.apache.ace.agent.update.itest</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>bndtools.core.bndbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>bndtools.core.bndnature</nature>
+ </natures>
+</projectDescription>
Added: ace/trunk/org.apache.ace.agent.update.itest/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/.settings/org.eclipse.jdt.core.prefs?rev=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.update.itest/.settings/org.eclipse.jdt.core.prefs (added)
+++ ace/trunk/org.apache.ace.agent.update.itest/.settings/org.eclipse.jdt.core.prefs Wed Aug 28 12:28:00 2013
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
Added: 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=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.update.itest/bnd.bnd (added)
+++ ace/trunk/org.apache.ace.agent.update.itest/bnd.bnd Wed Aug 28 12:28:00 2013
@@ -0,0 +1,49 @@
+# NOTE: This test is stored in a seperate from the main agent itest project because
+# 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,\
+ org.apache.ace.agent;version=latest,\
+ org.apache.ace.test;version=latest,\
+ org.apache.felix.dependencymanager,\
+ osgi.cmpn,\
+ org.apache.felix.http.jetty,\
+ org.apache.ace.deployment.servlet;version=latest,\
+ org.apache.ace.deployment.api;version=latest,\
+ org.apache.ace.deployment.streamgenerator;version=latest,\
+ 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.felix.configadmin,\
+ org.apache.ace.http.listener;version=latest,\
+ biz.aQute.bnd,\
+ org.apache.ace.builder;version=latest
+Private-Package: org.apache.ace.agent.itest
+-runee: JavaSE-1.6
+-runvm: -ea
+-runfw: org.apache.felix.framework
+-buildpath: osgi.core;version='[4.2,5)',\
+ org.apache.ace.agent;version=latest,\
+ org.apache.ace.test;version=latest,\
+ org.apache.felix.dependencymanager,\
+ org.apache.felix.http.jetty,\
+ biz.aQute.bnd,\
+ junit.osgi,\
+ org.mockito.mockito-all
+-runsystempackages: sun.reflect
+-runproperties: org.apache.felix.log.storeDebug=true,\
+ org.apache.felix.eventadmin.Timeout=0,\
+ org.apache.ace.server.port=8080,\
+ org.osgi.service.http.port=8080,\
+ org.apache.felix.log.maxSize=1000
+Import-Package: org.apache.ace.agent,\
+ !org.osgi.service.component.annotations,\
+ *
+Bundle-Version: 1.0.0
+Bundle-Name: Apache ACE Agent itest
+Bundle-Description: Integration test bundle for the Apache ACE Agent
\ No newline at end of file
Added: ace/trunk/org.apache.ace.agent.update.itest/build.xml
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/build.xml?rev=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.update.itest/build.xml (added)
+++ ace/trunk/org.apache.ace.agent.update.itest/build.xml Wed Aug 28 12:28:00 2013
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+
+ <!-- -->
+
+ <import file="../cnf/build.xml" />
+</project>
Added: ace/trunk/org.apache.ace.agent.update.itest/conf/org.apache.ace.deployment.servlet.agent.cfg
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/conf/org.apache.ace.deployment.servlet.agent.cfg?rev=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.update.itest/conf/org.apache.ace.deployment.servlet.agent.cfg (added)
+++ ace/trunk/org.apache.ace.agent.update.itest/conf/org.apache.ace.deployment.servlet.agent.cfg Wed Aug 28 12:28:00 2013
@@ -0,0 +1,4 @@
+org.apache.ace.server.servlet.endpoint=/agent
+# OBR settings
+obr.url = http://localhost:${org.apache.ace.server.port}/obr/
+authentication.enabled = false
Added: ace/trunk/org.apache.ace.agent.update.itest/src/.gitignore
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/src/.gitignore?rev=1518177&view=auto
==============================================================================
(empty)
Added: 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=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/AgentUpdateTest.java (added)
+++ ace/trunk/org.apache.ace.agent.update.itest/src/org/apache/ace/agent/itest/AgentUpdateTest.java Wed Aug 28 12:28:00 2013
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.agent.itest;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.ace.it.IntegrationTestBase;
+import org.apache.felix.dm.Component;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.service.http.HttpService;
+
+/**
+ * Tests updating the management agent. In fact it tests different failure paths first, and finally gets to update the
+ * agent. The tests it does are:
+ * <ul>
+ * <li>Try to update to a corrupt bundle (with some random garbage injected in the JAR file).</li>
+ * <li>Try to update to a bundle that does not resolve because of some impossible import package statement.</li>
+ * <li>Try to update to a bundle that does resolve, but does not start because of a non-existing bundle activator.</li>
+ * <li>Update to a new version of the agent (actually, it's the same bundle, but with a different version.</li>
+ * </ul>
+ */
+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
+ }
+
+ private enum PhaseStatus {
+ ACTIVE, DONE
+ }
+
+ @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);
+ }
+
+ public void tearDown() throws Exception {
+ m_http.unregister("/obr");
+ }
+
+ public void testAgentUpdate() throws Exception {
+
+ int timeout = 50;
+ m_servlet.setPhase(Phase.CORRUPT_STREAM);
+ while (m_servlet.getPhaseStatus() == PhaseStatus.ACTIVE) {
+ Thread.sleep(200);
+ if (timeout-- <= 0) {
+ fail("Timed out while recovering from update with broken stream.");
+ }
+ }
+ timeout = 50;
+ m_servlet.setPhase(Phase.BUNDLE_DOES_NOT_RESOLVE);
+ while (m_servlet.getPhaseStatus() == PhaseStatus.ACTIVE) {
+ Thread.sleep(200);
+ if (timeout-- <= 0) {
+ fail("Timed out while recovering from update with agent that does not resolve.");
+ }
+ }
+ timeout = 50;
+ m_servlet.setPhase(Phase.BUNDLE_DOES_NOT_START);
+ while (m_servlet.getPhaseStatus() == PhaseStatus.ACTIVE) {
+ Thread.sleep(200);
+ if (timeout-- <= 0) {
+ fail("Timed out while recovering from update with agent that does not start.");
+ }
+ }
+ timeout = 50;
+ m_servlet.setPhase(Phase.BUNDLE_WORKS);
+ 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.");
+ }
+
+ private static class AgentUpdateOBRServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ private Phase m_phase;
+ private PhaseStatus m_phaseStatus;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String path = req.getPathInfo();
+ if ("/repository.xml".equals(path)) {
+ PrintWriter w = resp.getWriter();
+ w.println("<?xml version='1.0' encoding='utf-8'?><repository>");
+ w.println(createResource("org.apache.ace.agent", "1.0.0"));
+ w.println(createResource("org.apache.ace.agent", "2.0.0"));
+ w.println("</repository>");
+ }
+ else {
+ if (path.endsWith("1.0.0.jar")) {
+ write(getBundle(), "1.0.0", resp.getOutputStream());
+ }
+ else if (path.endsWith("2.0.0.jar")) {
+ write(getBundle(), "2.0.0", resp.getOutputStream());
+ }
+ else {
+ throw new Error("Statement should never be reached.");
+ }
+ }
+ }
+
+ public synchronized void setPhase(Phase phase) {
+ m_phase = phase;
+ m_phaseStatus = PhaseStatus.ACTIVE;
+ }
+
+ public synchronized PhaseStatus getPhaseStatus() {
+ return m_phaseStatus;
+ }
+
+ private InputStream getBundle() throws IOException {
+ return new FileInputStream(new File("../org.apache.ace.agent/generated/org.apache.ace.agent.jar"));
+ }
+
+ private synchronized void write(InputStream object, String version, OutputStream outputStream) throws IOException {
+ JarInputStream jis = new JarInputStream(object);
+ Manifest manifest = jis.getManifest();
+ manifest.getMainAttributes().put(new Attributes.Name("Bundle-Version"), version);
+ if (m_phase == Phase.BUNDLE_DOES_NOT_START && "2.0.0".equals(version)) {
+ manifest.getMainAttributes().put(new Attributes.Name("Bundle-Activator"), "org.foo.NonExistingClass");
+ }
+ if (m_phase == Phase.BUNDLE_DOES_NOT_RESOLVE && "2.0.0".equals(version)) {
+ manifest.getMainAttributes().put(new Attributes.Name("Import-Package"), "org.foo.nonexistingpackage");
+ }
+ JarOutputStream jos = new JarOutputStream(outputStream, manifest);
+ JarEntry entry;
+ int length;
+ byte[] buffer = new byte[4096];
+ while ((entry = jis.getNextJarEntry()) != null) {
+ jos.putNextEntry(entry);
+ while ((length = jis.read(buffer)) != -1) {
+ jos.write(buffer, 0, length);
+ if (m_phase == Phase.CORRUPT_STREAM && "2.0.0".equals(version)) {
+ jos.write("garbage".getBytes());
+ }
+ }
+ jos.closeEntry();
+ jis.closeEntry();
+ }
+ jis.close();
+ jos.close();
+ if (m_phase == Phase.BUNDLE_WORKS && "2.0.0".equals(version)) {
+ m_phaseStatus = PhaseStatus.DONE;
+ }
+ if (m_phase != Phase.BUNDLE_WORKS && "1.0.0".equals(version)) {
+ m_phaseStatus = PhaseStatus.DONE;
+ }
+ }
+ }
+
+ private static String createResource(String bsn, String version) {
+ return "<resource id='" + bsn + "/" + version + "' symbolicname='" + bsn + "' version='" + version + "' uri='" + bsn + "-" + version + ".jar'></resource>";
+ }
+}
Added: ace/trunk/org.apache.ace.agent.update.itest/test/.gitignore
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent.update.itest/test/.gitignore?rev=1518177&view=auto
==============================================================================
(empty)
Added: ace/trunk/org.apache.ace.agent/README
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/README?rev=1518177&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent/README (added)
+++ ace/trunk/org.apache.ace.agent/README Wed Aug 28 12:28:00 2013
@@ -0,0 +1,14 @@
+
+TODOs:
+
+1) Download handler now store files in a tmp file and are not able to resume interrupted
+downloads from a new handle. This should be changed to storage in the data dir and using
+names that can be discovered and resumed.
+
+2) Download result provide access to the download through a File. This should be an
+inputstream.
+
+
+3) EventsHandler/EVentListener do not yet support an interest list like eventadmin does.
+This should be added as it will help reduce event load if we start throwing more.
+
Modified: ace/trunk/org.apache.ace.agent/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/bnd.bnd?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/bnd.bnd (original)
+++ ace/trunk/org.apache.ace.agent/bnd.bnd Wed Aug 28 12:28:00 2013
@@ -16,9 +16,7 @@ Private-Package: org.apache.ace.range,\
# No wildcard import here on purpose. Are you sure the agent must
# require an extra external dependency? Probably not...
-Import-Package:javax.net.ssl,\
- org.osgi.framework,\
- org.osgi.service.packageadmin
+Import-Package: !org.apache.felix.dm, *
# This is a minimal set on purpose. Are you really sure the agent must
# expose another package? Probably not...
@@ -27,6 +25,10 @@ Export-Package: org.apache.ace.agent,\
org.osgi.service.deploymentadmin.spi;-split-package:=merge-last
+# Keeping the agent as lean as possible. Remove debug when compiling
+# offline
+javac.debug: off
+
-buildpath: osgi.core;version=4.2,\
osgi.cmpn;version=4.2,\
javax.servlet;version=2.5,\
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java Wed Aug 28 12:28:00 2013
@@ -19,12 +19,163 @@
package org.apache.ace.agent;
/**
- * Compile time constants for this package.
- *
+ * Compile time constants for this package. Includes configuration keys and event topics.
*/
public interface AgentConstants {
/**
+ * Namespace for all agent configuration property
+ */
+ String CONFIG_KEY_NAMESPACE = "agent";
+
+ /**
+ * Agent configuration property key postfix. When set to true, the system property will not overwrite an existing
+ * configuration value
+ */
+ String CONFIG_KEY_RETAIN = ".retain";
+
+ /**
+ * Configuration loglevel for default logger. Should be a valid options s specified by {@link LoggingHandler.Levels}
+ * , default is <code>INFO</code>.
+ */
+ String CONFIG_LOGGING_LEVEL = CONFIG_KEY_NAMESPACE + ".logging.level";
+
+ /**
+ * Configuration option to disable the default identification handler. When set to true some other bundle must
+ * provide it as a service. Should be <code>{true,false}</code>, default is <code>false</code>.
+ */
+ String CONFIG_IDENTIFICATION_DISABLED = CONFIG_KEY_NAMESPACE + ".identification.disabled";
+
+ /**
+ * Configuration option for the agentid of the default identification handler. Should be a filesystem safe string,
+ * default is <code>defaultAgentID</code>/
+ */
+ String CONFIG_IDENTIFICATION_AGENTID = CONFIG_KEY_NAMESPACE + ".identification.agentid";
+
+ /**
+ * Configuration option to disable the default discovery handler. When set to true some other bundle must provide it
+ * as a service. Should be <code>{true,false}</code>, default is <code>false</code>.
+ */
+ String CONFIG_DISCOVERY_DISABLED = CONFIG_KEY_NAMESPACE + ".discovery.disabled";
+
+ /**
+ * Configuration option for the serverurls of the default discovery handler. Should be a comma-seperated list of
+ * valid urls, default is <code>http://localhost:8080</code>.
+ */
+ String CONFIG_DISCOVERY_SERVERURLS = CONFIG_KEY_NAMESPACE + ".discovery.serverurls";
+
+ /**
+ * Configuration option to enable checking for the default discovery handler. Should be e {true,false}, default is
+ * false.
+ */
+ String CONFIG_DISCOVERY_CHECKING = CONFIG_KEY_NAMESPACE + ".discovery.checking";
+
+ /**
+ * Configuration option to disable the default controller. When set to true some other bundle control the agent's
+ * behavior. Should be <code>{true,false}</code>, default is <code>false</code>.
+ */
+ String CONFIG_CONTROLLER_DISABLED = CONFIG_KEY_NAMESPACE + ".controller.disabled";
+
+ /**
+ * Configuration option to set streaming behavior of the default controller. Should be <code>{true,false}</code>,
+ * default is <code>true</code>.
+ */
+ String CONFIG_CONTROLLER_STREAMING = CONFIG_KEY_NAMESPACE + ".controller.streaming";
+
+ /**
+ * Configuration option to set fixpackages behavior of the default controller. Should be <code>{true,false}</code>,
+ * default is <code>true</code>.
+ */
+ String CONFIG_CONTROLLER_FIXPACKAGES = CONFIG_KEY_NAMESPACE + ".controller.fixpackages";
+
+ /**
+ * Configuration option to set retries behavior of the default controller. Should be an int, default is
+ * <code>1</code>.
+ */
+ String CONFIG_CONTROLLER_RETRIES = CONFIG_KEY_NAMESPACE + ".controller.retries";
+
+ /**
+ * Configuration option to set initial sync delay seconds of the default controller. Should be an int, default is
+ * <code>5</code>.
+ */
+ String CONFIG_CONTROLLER_SYNCDELAY = CONFIG_KEY_NAMESPACE + ".controller.syndelay";
+
+ /**
+ * Configuration option to set initial sync interval seconds of the default controller. Should be an int, default is
+ * <code>30</code>.
+ */
+ String CONFIG_CONTROLLER_SYNCINTERVAL = CONFIG_KEY_NAMESPACE + ".controller.syncinterval";
+
+ /**
+ * Configuration option to disable the default {@link ConnectionHandler}. When set to true some other bundle must
+ * provide it as a service. Should be <code>{true,false}</code>, default is <code>false</code>.
+ */
+ String CONFIG_CONNECTION_DISABLED = CONFIG_KEY_NAMESPACE + ".connection.disabled";
+
+ /**
+ * Configuration auth type for the default {@link ConnectionHandler}. Should be a valid type as specified by
+ * {@link ConnectionHandler.Types}, default if <code>NONE</code>.
+ */
+ String CONFIG_CONNECTION_AUTHTYPE = CONFIG_KEY_NAMESPACE + ".connection.authtype";
+
+ /**
+ * Configuration option to set the basic authentication username for the default {@link ConnectionHandler}. Should
+ * be an string, default is <code>""</code>.
+ */
+ String CONFIG_CONNECTION_USERNAME = CONFIG_KEY_NAMESPACE + ".connection.username";
+
+ /**
+ * Configuration option to set the basic authentication password for the default {@link ConnectionHandler}. Should
+ * be an string, default is <code>""</code>.
+ */
+ String CONFIG_CONNECTION_PASSWORD = CONFIG_KEY_NAMESPACE + ".connection.password";
+
+ /**
+ * Configuration option to set the client-cert authentication keystore path for the default
+ * {@link ConnectionHandler} . Should be a valid path, default is <code>""</code>.
+ */
+ String CONFIG_CONNECTION_KEYFILE = CONFIG_KEY_NAMESPACE + ".connection.keyfile";
+
+ /**
+ * Configuration option to set the client-cert authentication keystore password for the default
+ * {@link ConnectionHandler}. Should be a string, default is <code>""</code>.
+ */
+ String CONFIG_CONNECTION_KEYPASS = CONFIG_KEY_NAMESPACE + ".connection.keypass";
+
+ /**
+ * Configuration option to set the client-cert authentication truststore path for the default
+ * {@link ConnectionHandler}. Should be a valid path, default is <code>""</code>.
+ */
+ String CONFIG_CONNECTION_TRUSTFILE = CONFIG_KEY_NAMESPACE + ".connection.trustfile";
+
+ /**
+ * Configuration option to set the client-cert authentication truststore password for the default
+ * {@link ConnectionHandler}. Should be a string, default is <code>""</code>.
+ */
+ String CONFIG_CONNECTION_TRUSTPASS = CONFIG_KEY_NAMESPACE + ".connection.trustpass";
+
+ /**
+ * Configuration option to set the feedback channels for the default {@link FeedbackHandler}. Should be a
+ * comma-separated string, default is <code>auditlog</code>.
+ */
+ String CONFIG_FEEDBACK_CHANNELS = CONFIG_KEY_NAMESPACE + ".feedback.channels";
+
+ /**
+ * Event topic for deployment install events.
+ */
+ String EVENT_DEPLOYMENT_INSTALL = "org/osgi/service/deployment/INSTALL";
+
+ /**
+ * Event topic for deployment uninstall events.
+ */
+ String EVENT_DEPLOYMENT_UNINSTALL = "org/osgi/service/deployment/UNINSTALL";
+
+ /**
+ * Event topic for deployment install events.
+ */
+ String EVENT_DEPLOYMENT_COMPLETE = "org/osgi/service/deployment/COMPLETE";
+
+ /**
* HTTP headers name for Deployment Package size estimate.
*/
String HEADER_DPSIZE = "X-ACE-DPSize";
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentContext.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentContext.java?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentContext.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentContext.java Wed Aug 28 12:28:00 2013
@@ -19,81 +19,13 @@
package org.apache.ace.agent;
import java.io.File;
-import java.util.Dictionary;
-import java.util.Formatter;
-import java.util.concurrent.ScheduledExecutorService;
-
/**
* Internal interface that provides access to handlers, supporting services and static configuration.
- *
*/
public interface AgentContext {
/**
- * Return the identification handler.
- *
- * @return The handler
- */
- IdentificationHandler getIdentificationHandler();
-
- /**
- * Return the discovery handler.
- *
- * @return The handler
- */
- DiscoveryHandler getDiscoveryHandler();
-
- /**
- * Return the connection handler.
- *
- * @return The handler
- */
- ConnectionHandler getConnectionHandler();
-
- /**
- * Return the deployment handler.
- *
- * @return The handler
- */
- DeploymentHandler getDeploymentHandler();
-
- /**
- * Return the download handler.
- *
- * @return The handler
- */
- DownloadHandler getDownloadHandler();
-
- /**
- * Return the configuration handler.
- *
- * @return The handler
- */
- ConfigurationHandler getConfigurationHandler();
-
- /**
- * Return the update handler.
- *
- * @return The handler
- */
- AgentUpdateHandler getAgentUpdateHandler();
-
- /**
- * Return the feedback handler.
- *
- * @return The handler
- */
- FeedbackHandler getFeedbackHandler();
-
- /**
- * Return the executor service.
- *
- * @return The service
- */
- ScheduledExecutorService getExecutorService();
-
- /**
* Return the work directory.
*
* @return The directory
@@ -101,95 +33,10 @@ public interface AgentContext {
File getWorkDir();
/**
- * Post an event to any eventAdmin services outside the agent available at this time. There is no guarantee on
- * delivery. Only string values are supported to avoid any potential class-loading issues.
- *
- * @param topic The topic
- * @param properties The payload
- */
- void postEvent(String topic, Dictionary<String, String> payload);
-
- /**
- * Log a debug message. If <code>args</code> are provided the message will be processed as a format using the
- * standard {@link Formatter}.
- *
- * @param component The component identifier, not <code>null</code>
- * @param message The log message or format, not <code>null</code>
- * @param args The optional formatter arguments
- */
- void logDebug(String component, String message, Object... args);
-
- /**
- * Log a debug message. If <code>args</code> are provided the message will be processed as a format using the
- * standard {@link Formatter}.
- *
- * @param component The component identifier, not <code>null</code>
- * @param message The log message or format, not <code>null</code>
- * @param cause The cause, may be <code>null</code>
- * @param args The optional formatter arguments
- */
- void logDebug(String component, String message, Throwable cause, Object... args);
-
- /**
- * Log an info message. If <code>args</code> are provided the message will be processed as a format using the
- * standard {@link Formatter}.
- *
- * @param component The component identifier, not <code>null</code>
- * @param message The log message or format, not <code>null</code>
- * @param args The optional formatter arguments
- */
- void logInfo(String component, String message, Object... args);
-
- /**
- * Log an info message. If <code>args</code> are provided the message will be processed as a format using the
- * standard {@link Formatter}.
- *
- * @param component The component identifier, not <code>null</code>
- * @param message The log message or format, not <code>null</code>
- * @param cause The cause, may be <code>null</code>
- * @param args The optional formatter arguments
- */
- void logInfo(String component, String message, Throwable cause, Object... args);
-
- /**
- * Log a warning message. If <code>args</code> are provided the message will be processed as a format using the
- * standard {@link Formatter}.
- *
- * @param component The component identifier, not <code>null</code>
- * @param message The log message or format, not <code>null</code>
- * @param args The optional formatter arguments
- */
- void logWarning(String component, String message, Object... args);
-
- /**
- * Log a warning message. If <code>args</code> are provided the message will be processed as a format using the
- * standard {@link Formatter}.
- *
- * @param component The component identifier, not <code>null</code>
- * @param message The log message or format, not <code>null</code>
- * @param cause The cause, may be <code>null</code>
- * @param args The optional formatter arguments
- */
- void logWarning(String component, String message, Throwable cause, Object... args);
-
- /**
- * Log an error message. If <code>args</code> are provided the message will be processed as a format using the
- * standard {@link Formatter}.
- *
- * @param component The component identifier, not <code>null</code>
- * @param message The log message or format, not <code>null</code>
- * @param args The optional formatter arguments
- */
- void logError(String component, String message, Object... args);
-
- /**
- * Log an error message.If <code>args</code> are provided the message will be processed as a format using the
- * standard {@link Formatter}.
+ * Return the handler for a specified interface.
*
- * @param component The component identifier, not <code>null</code>
- * @param message The log message or format, not <code>null</code>
- * @param cause The cause, may be <code>null</code>
- * @param args The optional formatter arguments
+ * @param iface An interface
+ * @return The handler, or <code>null</code>
*/
- void logError(String component, String message, Throwable cause, Object... args);
+ <T> T getHandler(Class<T> iface);
}
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentControl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentControl.java?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentControl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentControl.java Wed Aug 28 12:28:00 2013
@@ -24,6 +24,9 @@ package org.apache.ace.agent;
*/
public interface AgentControl {
+ /** Returns the agent's identifier */
+ String getAgentId();
+
/** Returns the configuration handler */
ConfigurationHandler getConfigurationHandler();
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentUpdateHandler.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentUpdateHandler.java?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentUpdateHandler.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentUpdateHandler.java Wed Aug 28 12:28:00 2013
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.ace.agent;
import java.io.IOException;
@@ -7,8 +25,7 @@ import java.util.SortedSet;
import org.osgi.framework.Version;
/**
- * Agent control delegate interface that is responsible for managing agent updates.
- *
+ * Agent context delegate interface that is responsible for managing agent updates.
*/
public interface AgentUpdateHandler {
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConfigurationHandler.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConfigurationHandler.java?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConfigurationHandler.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConfigurationHandler.java Wed Aug 28 12:28:00 2013
@@ -21,10 +21,11 @@ package org.apache.ace.agent;
import java.util.Set;
/**
- * Agent control delegate interface that is responsible for managing persisted configuration. External launchers may
- * override or set values within the {@link CONFIG_KEY_NAMESPACE} through system properties when the agent starts. If
- * the launcher wants to retain existing persisted values, instead of overwriting them, it should specify an additional
- * property with the same name post-fixed with {@link CONFIG_KEY_RETAIN} set to <code>true</code>. <br/>
+ * Agent context delegate interface that is responsible for managing persisted configuration. External launchers may
+ * override or set values within the {@link AgentConstants.CONFIG_KEY_NAMESPACE} through system properties when the
+ * agent starts. If the launcher wants to retain existing persisted values, instead of overwriting them, it should
+ * specify an additional property with the same name post-fixed with {@link AgentConstants.CONFIG_KEY_RETAIN} set to
+ * <code>true</code>. <br/>
* <br/>
* Example: A launcher that wants to ensure the syncinterval is set to 3000 only when not configuration is already set
* should specify the following two system properties:<br/>
@@ -34,16 +35,6 @@ import java.util.Set;
public interface ConfigurationHandler {
/**
- * Key namespace; All system property keys that start with this are considered.
- */
- String CONFIG_KEY_NAMESPACE = "ace.agent";
-
- /**
- * Retain postfix; The postfix for override property keys.
- */
- String CONFIG_KEY_RETAIN = ".retain";
-
- /**
* Return an unmodifiable copy of the configuration keys.
*
* @return The set of keys
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConnectionHandler.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConnectionHandler.java?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConnectionHandler.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/ConnectionHandler.java Wed Aug 28 12:28:00 2013
@@ -23,12 +23,18 @@ import java.net.URL;
import java.net.URLConnection;
/**
- * Agent control delegate interface that is responsible for opening connection.
- *
+ * Agent context delegate interface that is responsible for opening connection.
*/
public interface ConnectionHandler {
/**
+ * Supported authentication types.
+ */
+ enum Types {
+ NONE, BASIC, CLIENTCERT;
+ }
+
+ /**
* Return a connection for the specified url.
*
* @param url The URL
Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/DeploymentHandler.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/DeploymentHandler.java?rev=1518177&r1=1518176&r2=1518177&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/DeploymentHandler.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/DeploymentHandler.java Wed Aug 28 12:28:00 2013
@@ -23,10 +23,10 @@ import java.io.InputStream;
import java.util.SortedSet;
import org.osgi.framework.Version;
+import org.osgi.service.deploymentadmin.DeploymentException;
/**
- * Agent control delegate interface that provides the deployment functions.
- *
+ * Agent context delegate interface that provides the deployment functions.
*/
public interface DeploymentHandler {
@@ -41,50 +41,38 @@ public interface DeploymentHandler {
* Return the sorted set of available deployment package versions as reported by the server.
*
* @return The sorted set of versions, may be empty
- * @throws RetryAfterException
- * If the server indicates it is too busy with a Retry-After header
- * @throws IOException
- * If the connection to the server fails
+ * @throws RetryAfterException If the server indicates it is too busy with a Retry-After header
+ * @throws IOException If the connection to the server fails
*/
SortedSet<Version> getAvailableVersions() throws RetryAfterException, IOException;
/**
* Return the estimated size for a deployment package as reported by the server.
*
- * @param version
- * The version of the package
- * @param fixPackage
- * Request the server for a fix-package
+ * @param version The version of the package
+ * @param fixPackage Request the server for a fix-package
* @return The estimated size in bytes, <code>-1</code> indicates the size is unknown
- * @throws RetryAfterException
- * If the server indicates it is too busy with a Retry-After header
- * @throws IOException
- * If the connection to the server fails
+ * @throws RetryAfterException If the server indicates it is too busy with a Retry-After header
+ * @throws IOException If the connection to the server fails
*/
long getPackageSize(Version version, boolean fixPackage) throws RetryAfterException, IOException;
/**
* Returns the {@link InputStream} for a deployment package.
*
- * @param version
- * The version of the deployment package
- * @param fixPackage
- * Request the server for a fix-package
+ * @param version The version of the deployment package
+ * @param fixPackage Request the server for a fix-package
* @return The input-stream for the deployment package
- * @throws RetryAfterException
- * If the server indicates it is too busy with a Retry-After header
- * @throws IOException
- * If the connection to the server fails
+ * @throws RetryAfterException If the server indicates it is too busy with a Retry-After header
+ * @throws IOException If the connection to the server fails
*/
InputStream getInputStream(Version version, boolean fixPackage) throws RetryAfterException, IOException;
/**
* Return the {@link DownloadHandle} for a deployment package.
*
- * @param version
- * The version of the deployment package
- * @param fixPackage
- * Request the server for a fix-package
+ * @param version The version of the deployment package
+ * @param fixPackage Request the server for a fix-package
* @return The download handle
*/
DownloadHandle getDownloadHandle(Version version, boolean fixPackage) throws RetryAfterException, IOException;
@@ -92,11 +80,9 @@ public interface DeploymentHandler {
/**
* Install a deployment package from an input stream.
*
- * @param inputStream
- * The inputStream, not <code>null</code>
- * @throws IOException
- * If reading the input stream fails.
+ * @param inputStream The inputStream, not <code>null</code>
+ * @throws IOException If reading the input stream fails.
*/
- // TODO deployment exceptions
- void deployPackage(InputStream inputStream) throws IOException;
+ // TODO should we expose the foreign exception?
+ void deployPackage(InputStream inputStream) throws DeploymentException, IOException;
}