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/20 17:48:29 UTC

svn commit: r1515849 - in /ace/trunk/org.apache.ace.agent: src/org/apache/ace/agent/ src/org/apache/ace/agent/impl/ test/org/apache/ace/agent/impl/ test/org/apache/ace/agent/testutil/

Author: bramk
Date: Tue Aug 20 15:48:28 2013
New Revision: 1515849

URL: http://svn.apache.org/r1515849
Log:
ACE-347 Some refactoring / Added persisted configuration implementation (wip)

Added:
    ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java
Modified:
    ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentControl.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/DeploymentHandler.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/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/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/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/FeedbackChannelImpl.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/UpdateHandlerBase.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/DeploymentHandlerTest.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/IdentificationhandlerImplTest.java
    ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java

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=1515849&r1=1515848&r2=1515849&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 Tue Aug 20 15:48:28 2013
@@ -20,24 +20,27 @@ package org.apache.ace.agent;
 
 import java.util.List;
 
-
 /**
  * The agent's control (service) interface. Provides control functions and access to configuration for consumers that
  * wish to control the agent's behavior.
  */
 public interface AgentControl {
 
-    /** access to the configuration */
-    ConfigurationHandler getConfiguration();
-
-    /** access to the feedback channels */
-    List<String> getFeedbackChannelNames();
-
-    FeedbackChannel getFeedbackChannel(String name);
+    /** Returns the configuration handler */
+    ConfigurationHandler getConfigurationHandler();
 
+    /** Returns the download handler */
     DownloadHandler getDownloadHandler();
 
+    /** Returns the deployment handler */
     DeploymentHandler getDeploymentHandler();
 
+    /** Returns the update handler */
     AgentUpdateHandler getAgentUpdateHandler();
+
+    /** Returns the feedback channels names */
+    List<String> getFeedbackChannelNames();
+
+    /** Returns the feedback channel for a name */
+    FeedbackChannel getFeedbackChannel(String name);
 }

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=1515849&r1=1515848&r2=1515849&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 Tue Aug 20 15:48:28 2013
@@ -18,102 +18,94 @@
  */
 package org.apache.ace.agent;
 
-import java.util.Map;
-import java.util.logging.Level;
+import java.util.Set;
 
 /**
- * The agent's persisted configuration. External launchers can override the default values through system properties
- * when the agent starts. However, once a configuration value has been stored in the persisted configuration is will no
- * longer be overwritten by system properties. This ensures a simple system restart will not override configuration set
- * by runtime controllers.
+ * 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.
+ * However, once a configuration value has been set the corresponding system property will be ignored unless the
+ * override flag is set. This ensures a simple system restart will not override configuration set by runtime
+ * controllers. <br/>
+ * <br/>
+ * Example: A launcher that wants to ensure the syncinterval is set to 3000 should specify the following two system
+ * properties:<br/>
+ * <code>agent.controller.syncinterval=3000</code><br/>
+ * <code>agent.controller.syncinterval.override=true</code>
  */
-// TODO should we support recovery by allow config overrides through system properties or should a luancher just wip
-// the bundle cache when it requires a clean boostrap?
 public interface ConfigurationHandler {
 
-    // NOTE Configuration of the default subsystems for identification, discovery and connection handling is not part of
-    // this definition. Even though they are default implementations the are still extensions.
-
     /**
-     * Sync interval; When sync is active it will automatically install updates and send feedback to the server. The
-     * time unit is seconds. A value of 0 or less disables the sync.
+     * Key namespace; All system property keys that start with this are considered.
      */
-    String CONFIG_KEY_SYNC_INTERVAL = ConfigurationHandler.class.getPackage().getName() + ".syncinterval";
-    long CONFIG_DEFAULT_SYNC_INTERVAL = 300l;
-
-    void setSyncInterval(long seconds);
-
-    long getSyncInterval();
+    String CONFIG_KEY_NAMESPACE = "agent";
 
     /**
-     * SyncRetries value; When an install fails during a sync the agent can try to recover by ignoring optimization
-     * flags and potentially restarting a Deployment Package download. A value of 1 or less disables the retry behavior.
+     * Override postfix; The postfix for override property keys.
      */
-    String CONFIG_KEY_SYNC_RETRIES = ConfigurationHandler.class.getPackage().getName() + ".syncretries";
-    int CONFIG_DEFAULT_SYNC_RETRIES = 3;
-
-    void setSyncRetries(int value);
-
-    int getSyncRetries();
+    String CONFIG_KEY_OVERRIDEPOSTFIX = ".override";
 
     /**
-     * UpdateStreaming flag; When set Deployment Packages are installed directly from the download stream reducing
-     * overhead and disk usage, but disabling resume capabilities. This strategy is of interest to highly resource
-     * constraint devices and/or system with highly reliable connectivity and no need for resume semantics.
+     * Return an unmodifiable copy of the configuration keys.
+     * 
+     * @return The set of keys
      */
-    String CONFIG_KEY_STREAMING_UPDATES = ConfigurationHandler.class.getPackage().getName() + ".updatestreaming";
-    boolean CONFIG_DEFAULT_UPDATE_STREAMING = false;
-
-    void setUpdateStreaming(boolean flag);
-
-    boolean getUpdateStreaming();
+    Set<String> keySet();
 
     /**
-     * StopUnaffected flag; When set all target bundles of a Deployment Package will be restarted as part of the
-     * deployment session. Otherwise the agent tries to minimize the impact by only restarting bundles that are actually
-     * affected. Not stopping unaffected bundles reduces overhead, but may fail in complex wiring scenarios.
+     * Retrieve the configuration value associated with the key, or the specified default.
+     * 
+     * @param key The key, must not be <code>null</code>
+     * @param defaultValue The default value, must not be <code>null</code>
+     * @return The associated value if it exists, otherwise the default value
      */
-    String CONFIG_KEY_STOP_UNAFFECTED = ConfigurationHandler.class.getPackage().getName() + ".stopunaffected";
-    boolean CONFIG_DEFAULT_STOP_UNAFFECTED = true; // spec behavior
-
-    void setStopUnaffected(boolean flag);
-
-    boolean getStopUnaffected();
+    String get(String key, String defaultValue);
 
     /**
-     * FixPackages flag; When set the Agent will request the server for fix packages instead of full deployment
-     * packages. This behavior significantly reduces bandwidth consumption.
+     * Store a configuration value.
+     * 
+     * @param key The key, must not be <code>null</code>
+     * @param value The value, must not be <code>null</code>
      */
-    String CONFIG_KEY_FIX_PACKAGES = ConfigurationHandler.class.getPackage().getName() + ".fixpackages";
-    boolean CONFIG_DEFAULT_FIX_PACKAGES = true;
-
-    void setFixPackage(boolean flag);
-
-    boolean getFixPackages();
+    void put(String key, String value);
 
     /**
-     * Log level; Logging uses standard Java logging to guarantee optimal compatibility in any standard Java
-     * environment.
+     * Remove a configuration value.
+     * 
+     * @param key The key, must not be <code>null</code>
      */
-    String CONFIG_KEY_LOG_LEVEL = ConfigurationHandler.class.getPackage().getName() + ".loglevel";
-    Level CONFIG_DEFAULT_LOG_LEVEL = Level.INFO;
-
-    void setLogLevel(Level level);
+    void remove(String key);
 
-    Level getLogLevel();
+    /**
+     * Retrieve the configuration value associated with the key, or the specified default.
+     * 
+     * @param key The key, must not be <code>null</code>
+     * @param defaultValue The default value
+     * @return The associated value if it exists, otherwise the default value
+     */
+    long getLong(String key, long defaultValue);
 
     /**
-     * Custom configuration keys; This is provided to allow a launcher to specify system properties that should be
-     * included in the persistent configuration map. The initial values of these properties are only read once when the
-     * agent starts and only stored if no value is set in the configuration map.
+     * Store a configuration value.
+     * 
+     * @param key The key, must not be <code>null</code>
+     * @param value The value
      */
-    String CONFIG_KEY_EXTENSION_PROPERTIES = ConfigurationHandler.class.getPackage().getName() + ".extensionkeys";
+    void putLong(String key, long value);
 
     /**
-     * Direct access to the configuration map; This is provided to allow extensions to access custom configuration
-     * properties.
+     * Retrieve the configuration value associated with the key, or the specified default.
+     * 
+     * @param key The key, must not be <code>null</code>
+     * @param defaultValue The default value
+     * @return The associated value if it exists, otherwise the default value
      */
-    void setMap(Map<String, String> configuration);
+    boolean getBoolean(String key, boolean defaultValue);
 
-    Map<String, String> getMap();
+    /**
+     * Store a configuration value.
+     * 
+     * @param key The key, must not be <code>null</code>
+     * @param value The value
+     */
+    void putBoolean(String key, boolean Value);
 }

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=1515849&r1=1515848&r2=1515849&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 Tue Aug 20 15:48:28 2013
@@ -41,47 +41,61 @@ 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);
+    DownloadHandle getDownloadHandle(Version version, boolean fixPackage) throws RetryAfterException, IOException;
 
     /**
      * 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;

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/IdentificationHandler.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/IdentificationHandler.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/IdentificationHandler.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/IdentificationHandler.java Tue Aug 20 15:48:28 2013
@@ -29,5 +29,5 @@ public interface IdentificationHandler {
      * 
      * @return The identification, <code>null</code> if none is available.
      */
-    String getIdentification();
+    String getAgentId();
 }

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java Tue Aug 20 15:48:28 2013
@@ -61,7 +61,7 @@ public class Activator extends Dependenc
     private AgentControl m_agentControl;
     private ScheduledExecutorService m_executorService;
     private AgentUpdateHandlerImpl m_agentUpdateHandler; // we use the implementation type here on purpose
-    private DeploymentAdmin m_deploymentAdmin;
+    private DeploymentAdmin m_internalDeploymentAdmin;
     private Component m_agentControlComponent = null;
     private Component m_defaultControllerComponent = null;
     private EventLoggerImpl m_eventLoggerImpl;
@@ -75,11 +75,11 @@ public class Activator extends Dependenc
 
         m_executorService = Executors.newScheduledThreadPool(1, new InternalThreadFactory());
 
-        m_deploymentAdmin = new DeploymentAdminImpl();
-        configureField(m_deploymentAdmin, BundleContext.class, context);
-        configureField(m_deploymentAdmin, PackageAdmin.class, null);
-        configureField(m_deploymentAdmin, EventAdmin.class, m_internalEventAdmin);
-        configureField(m_deploymentAdmin, LogService.class, m_internalLogService);
+        m_internalDeploymentAdmin = new DeploymentAdminImpl();
+        configureField(m_internalDeploymentAdmin, BundleContext.class, context);
+        configureField(m_internalDeploymentAdmin, PackageAdmin.class, null);
+        configureField(m_internalDeploymentAdmin, EventAdmin.class, m_internalEventAdmin);
+        configureField(m_internalDeploymentAdmin, LogService.class, m_internalLogService);
 
         m_agentContext = new AgentContextImpl(context.getDataFile(""));
         m_agentControl = new AgentControlImpl(m_agentContext);
@@ -90,7 +90,7 @@ public class Activator extends Dependenc
         configureField(m_agentContext, LogService.class, m_internalLogService);
         configureField(m_agentContext, ConfigurationHandler.class, new ConfigurationHandlerImpl(m_agentContext));
         configureField(m_agentContext, ConnectionHandler.class, new ConnectionHandlerImpl(m_agentContext));
-        configureField(m_agentContext, DeploymentHandler.class, new DeploymentHandlerImpl(m_agentContext, m_deploymentAdmin));
+        configureField(m_agentContext, DeploymentHandler.class, new DeploymentHandlerImpl(m_agentContext, m_internalDeploymentAdmin));
         configureField(m_agentContext, DiscoveryHandler.class, new DiscoveryHandlerImpl(m_agentContext));
         configureField(m_agentContext, DownloadHandler.class, new DownloadHandlerImpl(m_agentContext));
         configureField(m_agentContext, IdentificationHandler.class, new IdentificationHandlerImpl(m_agentContext));
@@ -136,14 +136,14 @@ public class Activator extends Dependenc
     synchronized void packageAdminAdded(PackageAdmin packageAdmin) {
         if (m_packageAdmin == null) {
             m_packageAdmin = packageAdmin;
-            configureField(m_deploymentAdmin, PackageAdmin.class, packageAdmin);
+            configureField(m_internalDeploymentAdmin, PackageAdmin.class, packageAdmin);
         }
     }
 
     synchronized void packageAdminRemoved(PackageAdmin packageAdmin) {
         if (m_packageAdmin == packageAdmin) {
             m_packageAdmin = null;
-            configureField(m_deploymentAdmin, PackageAdmin.class, null);
+            configureField(m_internalDeploymentAdmin, PackageAdmin.class, null);
         }
     }
 
@@ -164,7 +164,8 @@ public class Activator extends Dependenc
     void startAgent() throws Exception {
 
         m_internalLogService.log(LogService.LOG_INFO, "Starting agent...");
-        invokeMethod(m_deploymentAdmin, "start", new Class<?>[] {}, new Object[] {});
+        invokeMethod(m_internalDeploymentAdmin, "start", new Class<?>[] {}, new Object[] {});
+        invokeMethod(m_agentContext, "start", new Class<?>[] {}, new Object[] {});
 
         m_internalLogService.log(LogService.LOG_DEBUG, "* agent control service registered");
         m_agentControlComponent = createComponent()
@@ -220,7 +221,7 @@ public class Activator extends Dependenc
             m_internalEventAdmin.unregisterHandler(m_eventLoggerImpl);
         }
 
-        invokeMethod(m_deploymentAdmin, "stop", new Class<?>[] {}, new Object[] {});
+        invokeMethod(m_internalDeploymentAdmin, "stop", new Class<?>[] {}, new Object[] {});
         m_internalLogService.log(LogService.LOG_INFO, "Agent stopped!");
     }
 
@@ -278,13 +279,13 @@ public class Activator extends Dependenc
         private static String getName(int level) {
             switch (level) {
                 case 1:
-                    return "ERROR";
+                    return "[ERROR  ] ";
                 case 2:
-                    return "WARNING";
+                    return "[WARNING] ";
                 case 3:
-                    return "INFO";
+                    return "[INFO   ] ";
                 case 4:
-                    return "DEBUG";
+                    return "[DEBUG  ] ";
                 default:
                     throw new IllegalStateException("Unknown level: " + level);
             }
@@ -292,22 +293,24 @@ public class Activator extends Dependenc
 
         @Override
         public void log(int level, String message) {
-            System.out.println("[" + getName(level) + "] " + message);
+            System.out.println(getName(level) + message);
         }
 
         @Override
         public void log(int level, String message, Throwable exception) {
-            System.out.println("[" + getName(level) + "] " + message);
+            System.out.println(getName(level) + message);
+            exception.printStackTrace(System.out);
         }
 
         @Override
         public void log(ServiceReference sr, int level, String message) {
-            System.out.println("[" + getName(level) + "] " + message);
+            System.out.println(getName(level) + message);
         }
 
         @Override
         public void log(ServiceReference sr, int level, String message, Throwable exception) {
-            System.out.println("[" + getName(level) + "] " + message);
+            System.out.println(getName(level) + message);
+            exception.printStackTrace(System.out);
         }
     }
 

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java Tue Aug 20 15:48:28 2013
@@ -18,6 +18,8 @@
  */
 package org.apache.ace.agent.impl;
 
+import static org.apache.ace.agent.impl.ReflectionUtil.invokeMethod;
+
 import java.io.File;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -57,6 +59,10 @@ public class AgentContextImpl implements
         m_workDir = workDir;
     }
 
+    public void start() throws Exception {
+        invokeMethod(m_configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+    }
+
     @Override
     public IdentificationHandler getIdentificationHandler() {
         return m_identificationHandler;

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentControlImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentControlImpl.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentControlImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentControlImpl.java Tue Aug 20 15:48:28 2013
@@ -48,7 +48,7 @@ public class AgentControlImpl implements
     }
 
     @Override
-    public ConfigurationHandler getConfiguration() {
+    public ConfigurationHandler getConfigurationHandler() {
         return m_agentContext.getConfigurationHandler();
     }
 

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentUpdateHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentUpdateHandlerImpl.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentUpdateHandlerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentUpdateHandlerImpl.java Tue Aug 20 15:48:28 2013
@@ -52,7 +52,7 @@ public class AgentUpdateHandlerImpl exte
         super(agentContext);
         m_bundleContext = bundleContext;
     }
-    
+
     public void uninstallUpdaterBundle() throws BundleException {
         for (Bundle b : m_bundleContext.getBundles()) {
             if (UPDATER_SYMBOLICNAME.equals(b.getSymbolicName())) {
@@ -153,13 +153,15 @@ public class AgentUpdateHandlerImpl exte
                 try {
                     is.close();
                 }
-                catch (IOException e) {}
+                catch (IOException e) {
+                }
             }
             if (jos != null) {
                 try {
                     jos.close();
                 }
-                catch (IOException e) {}
+                catch (IOException e) {
+                }
             }
         }
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConfigurationHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConfigurationHandlerImpl.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConfigurationHandlerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConfigurationHandlerImpl.java Tue Aug 20 15:48:28 2013
@@ -18,81 +18,195 @@
  */
 package org.apache.ace.agent.impl;
 
+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.util.Collections;
-import java.util.Map;
-import java.util.logging.Level;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
 
 import org.apache.ace.agent.ConfigurationHandler;
+import org.osgi.service.log.LogService;
 
 public class ConfigurationHandlerImpl implements ConfigurationHandler {
 
     private final AgentContext m_agentContext;
+    private Properties m_configProps = null;
 
     public ConfigurationHandlerImpl(AgentContext agentContext) {
         m_agentContext = agentContext;
     }
 
-    @Override
-    public void setSyncInterval(long seconds) {
-    }
-
-    @Override
-    public long getSyncInterval() {
-        return 10;
-    }
-
-    @Override
-    public void setSyncRetries(int value) {
-    }
-
-    @Override
-    public int getSyncRetries() {
-        return 3;
-    }
-
-    @Override
-    public void setUpdateStreaming(boolean flag) {
-    }
-
-    @Override
-    public boolean getUpdateStreaming() {
-        return false;
-    }
-
-    @Override
-    public void setStopUnaffected(boolean flag) {
-    }
-
-    @Override
-    public boolean getStopUnaffected() {
-        return false;
-    }
-
-    @Override
-    public void setFixPackage(boolean flag) {
-    }
-
-    @Override
-    public boolean getFixPackages() {
-        return false;
-    }
-
-    @Override
-    public void setLogLevel(Level level) {
-    }
-
-    @Override
-    public Level getLogLevel() {
-        return null;
-    }
-
-    @Override
-    public void setMap(Map<String, String> configuration) {
-    }
-
-    @Override
-    public Map<String, String> getMap() {
-        return Collections.EMPTY_MAP;
+    public void start() throws Exception {
+        synchronized (this) {
+            loadSystemProps();
+        }
+    }
+
+    @Override
+    public Set<String> keySet() {
+        Set<String> keySet = new HashSet<String>();
+        synchronized (this) {
+            ensureLoadConfig();
+            for (Object key : m_configProps.keySet()) {
+                keySet.add((String) key);
+            }
+        }
+        return Collections.unmodifiableSet(keySet);
+    }
+
+    @Override
+    public void put(String key, String value) {
+        ensureNotEmpty(key);
+        ensureNotEmpty(value);
+        synchronized (this) {
+            ensureLoadConfig();
+            String previous = (String) m_configProps.put(key, value);
+            if (previous == null || !previous.equals(value)) {
+                ensureStoreConfig();
+            }
+        }
+    }
+
+    @Override
+    public void remove(String key) {
+        ensureNotEmpty(key);
+        synchronized (this) {
+            ensureLoadConfig();
+            Object value = m_configProps.remove(key);
+            if (value != null) {
+                ensureStoreConfig();
+            }
+        }
+    }
+
+    @Override
+    public String get(String key, String defaultValue) {
+        ensureNotEmpty(key);
+        synchronized (this) {
+            ensureLoadConfig();
+            String value = (String) m_configProps.get(key);
+            if (value == null) {
+                value = defaultValue;
+            }
+            return value;
+        }
+    }
+
+    @Override
+    public long getLong(String key, long defaultValue) {
+        String value = get(key, "");
+        if (value.equals("")) {
+            return defaultValue;
+        }
+        return Long.parseLong(value);
+    }
+
+    @Override
+    public void putLong(String key, long value) {
+        put(key, String.valueOf(value));
+    }
+
+    @Override
+    public boolean getBoolean(String key, boolean defaultValue) {
+        String value = get(key, "");
+        if (value.equals("")) {
+            return defaultValue;
+        }
+        return Boolean.parseBoolean(value);
+    }
+
+    @Override
+    public void putBoolean(String key, boolean value) {
+        put(key, String.valueOf(value));
+    }
+
+    private void loadSystemProps() {
+        ensureLoadConfig();
+        for (Entry<Object, Object> entry : System.getProperties().entrySet()) {
+            String key = (String) entry.getKey();
+            if (key.startsWith(CONFIG_KEY_NAMESPACE) && !key.endsWith(CONFIG_KEY_OVERRIDEPOSTFIX)) {
+                if (!m_configProps.containsKey(key)
+                    || Boolean.parseBoolean(System.getProperties().getProperty(key + CONFIG_KEY_OVERRIDEPOSTFIX))) {
+                    m_configProps.put(entry.getKey(), entry.getValue());
+                }
+            }
+        }
+        ensureStoreConfig();
+    }
+
+    private void ensureLoadConfig() {
+        if (m_configProps != null) {
+            return;
+        }
+        try {
+            m_configProps = new Properties();
+            loadConfig();
+        }
+        catch (IOException e) {
+            m_agentContext.getLogService().log(LogService.LOG_ERROR, "Load config failed", e);
+            throw new IllegalStateException("Load config failed", e);
+        }
+    }
+
+    private void ensureStoreConfig() {
+        if (m_configProps == null) {
+            return;
+        }
+        try {
+            storeConfig();
+        }
+        catch (IOException e) {
+            m_agentContext.getLogService().log(LogService.LOG_ERROR, "Storing config failed", e);
+            throw new IllegalStateException("Store config failed", e);
+        }
+    }
+
+    private void loadConfig() throws IOException {
+        File configFile = getConfigFile();
+        InputStream input = new FileInputStream(configFile);
+        try {
+            m_configProps.clear();
+            m_configProps.load(input);
+        }
+        finally {
+            input.close();
+        }
+    }
+
+    private void storeConfig() throws IOException {
+        OutputStream output = null;
+        try {
+            output = new FileOutputStream(getConfigFile());
+            m_configProps.store(output, "ACE Agent configuration");
+        }
+        finally {
+            output.close();
+        }
+    }
+
+    private File getConfigFile() throws IOException {
+        File file = new File(getConfigDir(), "config.properties");
+        if (!file.exists() && !file.createNewFile())
+            throw new IOException("Unable to acces configuration file: " + file.getAbsolutePath());
+        return file;
+    }
+
+    private File getConfigDir() throws IOException {
+        File dir = new File(m_agentContext.getWorkDir(), "config");
+        if (!dir.exists() && !dir.mkdir())
+            throw new IOException("Unable to acces configuration directory: " + dir.getAbsolutePath());
+        return dir;
+    }
+
+    private static void ensureNotEmpty(String value) {
+        if (value == null || value.equals(""))
+            throw new IllegalArgumentException("Can not pass null as an argument");
     }
 
 }

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConnectionHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConnectionHandlerImpl.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConnectionHandlerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/ConnectionHandlerImpl.java Tue Aug 20 15:48:28 2013
@@ -150,24 +150,24 @@ public class ConnectionHandlerImpl imple
 
     public UrlCredentials getCredentials() {
 
-        String configValue = getConfigurationValue(PROP_AUTHTYPE);
+        String configValue = getConfigStringValue(PROP_AUTHTYPE);
         AuthType authType = AuthType.getAuthType(configValue == null ? "" : configValue.trim().toUpperCase());
         if (authType == null || authType == AuthType.NONE) {
             return UrlCredentials.EMPTY_CREDENTIALS;
         }
 
         if (authType == AuthType.BASIC) {
-            String username = getConfigurationValue(PROP_AUTHUSER);
-            String password = getConfigurationValue(PROP_AUTHPASS);
+            String username = getConfigStringValue(PROP_AUTHUSER);
+            String password = getConfigStringValue(PROP_AUTHPASS);
             return new UrlCredentials(AuthType.BASIC,
                 new Object[] { username == null ? "" : username, password == null ? "" : password });
         }
 
         if (authType == AuthType.CLIENT_CERT) {
-            String keystoreFile = getConfigurationValue(PROP_AUTHKEYFILE);
-            String keystorePass = getConfigurationValue(PROP_AUTHKEYPASS);
-            String truststoreFile = getConfigurationValue(PROP_AUTHTRUSTFILE);
-            String truststorePass = getConfigurationValue(PROP_AUTHTRUSTPASS);
+            String keystoreFile = getConfigStringValue(PROP_AUTHKEYFILE);
+            String keystorePass = getConfigStringValue(PROP_AUTHKEYPASS);
+            String truststoreFile = getConfigStringValue(PROP_AUTHTRUSTFILE);
+            String truststorePass = getConfigStringValue(PROP_AUTHTRUSTPASS);
 
             // TODO This is expensive. Can we cache?
             try {
@@ -185,8 +185,8 @@ public class ConnectionHandlerImpl imple
         return null;
     }
 
-    private String getConfigurationValue(String key) {
-        return m_agentContext.getConfigurationHandler().getMap().get(key);
+    private String getConfigStringValue(String key) {
+        return m_agentContext.getConfigurationHandler().get(key, null);
     }
 
     private static KeyManager[] getKeyManagerFactory(String keystoreFile, String storePass) throws IOException, GeneralSecurityException {

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DefaultController.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DefaultController.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DefaultController.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DefaultController.java Tue Aug 20 15:48:28 2013
@@ -25,6 +25,7 @@ import java.util.SortedSet;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.ace.agent.AgentControl;
 import org.apache.ace.agent.AgentUpdateHandler;
 import org.apache.ace.agent.ConfigurationHandler;
 import org.apache.ace.agent.DeploymentHandler;
@@ -39,6 +40,55 @@ import org.osgi.service.log.LogService;
  */
 public class DefaultController implements Runnable {
 
+    public static final String CONFIG_KEY_BASE = ConfigurationHandlerImpl.CONFIG_KEY_NAMESPACE + ".controller";
+
+    /**
+     */
+    public static final String CONFIG_KEY_DISABLED = CONFIG_KEY_BASE + ".disabled";
+    public static final boolean CONFIG_DEFAULT_DISABLED = false;
+
+    /**
+     * Sync delay; Number of seconds after startup until the initial sync is done.
+     */
+    public static final String CONFIG_KEY_SYNCDELAY = CONFIG_KEY_BASE + ".syncDelay";
+    public static final long CONFIG_DEFAULT_SYNCDELAY = 5l;
+
+    /**
+     * Sync interval; Number of seconds between regular syncs.
+     */
+    public static final String CONFIG_KEY_SYNCINTERVAL = CONFIG_KEY_BASE + ".syncInterval";
+    public static final long CONFIG_DEFAULT_SYNCINTERVAL = 30l;
+
+    /**
+     * SyncRetries value; When an install fails during a sync the agent can try to recover by ignoring optimization
+     * flags and potentially restarting a Deployment Package download. A value of 1 or less disables the retry behavior.
+     */
+    public static final String CONFIG_KEY_UPDATERETRIES = CONFIG_KEY_BASE + ".updateRetries";
+    public static final long CONFIG_DEFAULT_UPDATERETRIES = 1;
+
+    /**
+     * UpdateStreaming flag; When set Deployment Packages are installed directly from the download stream reducing
+     * overhead and disk usage, but disabling resume capabilities. This strategy is of interest to highly resource
+     * constraint devices and/or system with highly reliable connectivity and no need for resume semantics.
+     */
+    public static final String CONFIG_KEY_UPDATESTREAMING = CONFIG_KEY_BASE + ".updateStreaming";
+    public static final boolean CONFIG_DEFAULT_UPDATESTREAMING = false;
+
+    /**
+     * StopUnaffected flag; When set all target bundles of a Deployment Package will be restarted as part of the
+     * deployment session. Otherwise the agent tries to minimize the impact by only restarting bundles that are actually
+     * affected. Not stopping unaffected bundles reduces overhead, but may fail in complex wiring scenarios.
+     */
+    public static final String CONFIG_KEY_STOPUNAFFECTED = CONFIG_KEY_BASE + ".stopUnaffected";
+    public static final boolean CONFIG_DEFAULT_STOPUNAFFECTED = true; // spec behavior
+
+    /**
+     * FixPackages flag; When set the Agent will request the server for fix packages instead of full deployment
+     * packages. This behavior significantly reduces bandwidth consumption.
+     */
+    public static final String CONFIG_KEY_FIXPACKAGES = CONFIG_KEY_BASE + ".fixPackages";
+    public static final boolean CONFIG_DEFAULT_FIXPACKAGES = true;
+
     private final AgentContext m_agentContext;
     private volatile ScheduledFuture<?> m_future;
 
@@ -47,62 +97,90 @@ public class DefaultController implement
     }
 
     public void start() {
-        schedule(1);
+        ConfigurationHandler configurationHandler = m_agentContext.getConfigurationHandler();
+        LogService logService = m_agentContext.getLogService();
+
+        boolean disabled = configurationHandler.getBoolean(CONFIG_KEY_DISABLED, CONFIG_DEFAULT_DISABLED);
+        if (disabled) {
+            logService.log(LogService.LOG_INFO, "Default controller disabled by configuration");
+        }
+        else {
+            long delay = configurationHandler.getLong(CONFIG_KEY_SYNCDELAY, CONFIG_DEFAULT_SYNCDELAY);
+            scheduleRun(delay);
+            logService.log(LogService.LOG_DEBUG, "Controller scheduled to sync in " + delay + " seconds");
+        }
     }
 
     public void stop() {
-        unSchedule();
+        unscheduleRun();
     }
 
     public void run() {
         ConfigurationHandler configurationHandler = m_agentContext.getConfigurationHandler();
-        long syncInterval = configurationHandler.getSyncInterval();
+        LogService logService = m_agentContext.getLogService();
+
+        logService.log(LogService.LOG_DEBUG, "Controller syncing...");
+        long interval = configurationHandler.getLong(CONFIG_KEY_SYNCINTERVAL, CONFIG_DEFAULT_SYNCINTERVAL);
         try {
             runSafeAgent();
             runSafeUpdate();
             runSafeFeedback();
         }
         catch (RetryAfterException e) {
-            syncInterval = e.getSeconds();
+            interval = e.getSeconds();
+            logService.log(LogService.LOG_INFO, "Sync received retry exception from server.");
         }
         catch (IOException e) {
-            // TODO what to do
-            e.printStackTrace();
+            logService.log(LogService.LOG_WARNING, "Sync aborted due to IOException.", e);
         }
         catch (Exception e) {
-            // TODO what to do
-            e.printStackTrace();
+            logService.log(LogService.LOG_ERROR, "Sync aborted due to Exception.", e);
         }
-        reschedule(syncInterval);
+        scheduleRun(interval);
+        logService.log(LogService.LOG_DEBUG, "Sync completed. Rescheduled in " + interval + " seconds");
     }
 
     private void runSafeAgent() throws RetryAfterException, IOException {
         AgentUpdateHandler deploymentHandler = m_agentContext.getAgentUpdateHandler();
+        LogService logService = m_agentContext.getLogService();
+
+        logService.log(LogService.LOG_DEBUG, "Checking for agent update");
         Version current = deploymentHandler.getInstalledVersion();
         SortedSet<Version> available = deploymentHandler.getAvailableVersions();
         Version highest = Version.emptyVersion;
         if (available != null && !available.isEmpty()) {
             highest = available.last();
         }
-        System.out.println("runSafeAgent: " + current + ", latest: " + highest);
-        int val = highest.compareTo(current);
-        if (val > 0) {
+        if (highest.compareTo(current) > 0) {
+            logService.log(LogService.LOG_INFO, "Installing agent update " + current + " => " + highest);
             InputStream inputStream = deploymentHandler.getInputStream(highest);
             deploymentHandler.install(inputStream);
         }
+        else {
+            logService.log(LogService.LOG_DEBUG, "No agent update available for version" + current);
+        }
     }
 
     private void runSafeUpdate() throws RetryAfterException, IOException {
+        ConfigurationHandler configurationHandler = m_agentContext.getConfigurationHandler();
         DeploymentHandler deploymentHandler = m_agentContext.getDeploymentHandler();
+        LogService logService = m_agentContext.getLogService();
+
+        logService.log(LogService.LOG_DEBUG, "Checking for deployment update");
         Version current = deploymentHandler.getInstalledVersion();
         SortedSet<Version> available = deploymentHandler.getAvailableVersions();
         Version highest = Version.emptyVersion;
         if (available != null && !available.isEmpty()) {
             highest = available.last();
         }
-        System.out.println("runSafeUpdate: " + current + ", latest: " + highest);
         if (highest.compareTo(current) > 0) {
-            InputStream inputStream = deploymentHandler.getInputStream(highest, true);
+            logService.log(LogService.LOG_INFO, "Installing deployment update " + current + " => " + highest);
+
+            // FIXME handle downloads
+            // boolean streaming = configurationHandler.getBoolean(CONFIG_KEY_STREAMING_UPDATES,
+            // CONFIG_DEFAULT_UPDATE_STREAMING);
+            boolean fixPackage = configurationHandler.getBoolean(CONFIG_KEY_FIXPACKAGES, CONFIG_DEFAULT_FIXPACKAGES);
+            InputStream inputStream = deploymentHandler.getInputStream(highest, fixPackage);
             try {
                 deploymentHandler.deployPackage(inputStream);
             }
@@ -110,28 +188,30 @@ public class DefaultController implement
                 inputStream.close();
             }
         }
+        else {
+            logService.log(LogService.LOG_DEBUG, "No deployment update available for version" + current);
+        }
     }
 
     private void runSafeFeedback() throws RetryAfterException, IOException {
-        List<String> channelNames = m_agentContext.getAgentControl().getFeedbackChannelNames();
+        AgentControl agentControl = m_agentContext.getAgentControl();
+        LogService logService = m_agentContext.getLogService();
+
+        logService.log(LogService.LOG_DEBUG, "Synchronizing feedback channels");
+        List<String> channelNames = agentControl.getFeedbackChannelNames();
         for (String channelName : channelNames) {
-            FeedbackChannel channel = m_agentContext.getAgentControl().getFeedbackChannel(channelName);
+            logService.log(LogService.LOG_DEBUG, "Synchronizing channel: " + channelName);
+            FeedbackChannel channel = agentControl.getFeedbackChannel(channelName);
             if (channel != null)
                 channel.sendFeedback();
         }
     }
 
-    private void schedule(long seconds) {
-        m_agentContext.getLogService().log(LogService.LOG_INFO, "Scheduling initial poll in " + seconds + " seconds");
-        m_future = m_agentContext.getExecutorService().schedule(this, seconds, TimeUnit.SECONDS);
-    }
-
-    private void reschedule(long seconds) {
-        m_agentContext.getLogService().log(LogService.LOG_DEBUG, "Scheduling next poll in " + seconds + " seconds");
+    private void scheduleRun(long seconds) {
         m_future = m_agentContext.getExecutorService().schedule(this, seconds, TimeUnit.SECONDS);
     }
 
-    private void unSchedule() {
+    private void unscheduleRun() {
         if (m_future != null)
             m_future.cancel(true);
     }

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DeploymentHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DeploymentHandlerImpl.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DeploymentHandlerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DeploymentHandlerImpl.java Tue Aug 20 15:48:28 2013
@@ -78,7 +78,7 @@ public class DeploymentHandlerImpl exten
     };
 
     @Override
-    public DownloadHandle getDownloadHandle(Version version, boolean fixPackage) {
+    public DownloadHandle getDownloadHandle(Version version, boolean fixPackage) throws RetryAfterException, IOException {
         return getDownloadHandle(getPackageURL(version, fixPackage));
     };
 
@@ -87,7 +87,7 @@ public class DeploymentHandlerImpl exten
         return getAvailableVersions(getEndpoint(getServerURL(), getIdentification()));
     };
 
-    private URL getPackageURL(Version version, boolean fixPackage) {
+    private URL getPackageURL(Version version, boolean fixPackage) throws RetryAfterException, IOException {
         URL url = getEndpoint(getServerURL(), getIdentification(), fixPackage ? getInstalledVersion() : Version.emptyVersion, version);
         return url;
     }

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=1515849&r1=1515848&r2=1515849&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 Tue Aug 20 15:48:28 2013
@@ -20,13 +20,14 @@ package org.apache.ace.agent.impl;
 
 import java.io.IOException;
 import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.ace.agent.ConfigurationHandler;
 import org.apache.ace.agent.DiscoveryHandler;
+import org.osgi.service.log.LogService;
 
 /**
  * Default discovery handler that reads the serverURL(s) from the configuration using key {@link DISCOVERY_CONFIG_KEY}.
@@ -34,12 +35,14 @@ import org.apache.ace.agent.DiscoveryHan
  */
 public class DiscoveryHandlerImpl implements DiscoveryHandler {
 
+    public static final String CONFIG_KEY_BASE = ConfigurationHandlerImpl.CONFIG_KEY_NAMESPACE + ".discovery";
+
     /**
      * Configuration key for the default discovery handler. The value must be a comma-separated list of valid base
      * server URLs.
      */
-    // TODO move to and validate in config handler?
-    public static final String DISCOVERY_CONFIG_KEY = "agent.discovery";
+    public static final String CONFIG_KEY_SERVERURLS = CONFIG_KEY_BASE + ".serverUrls";
+    public static final String CONFIG_DEFAULT_SERVERURLS = "http://localhost:8080";
 
     private final AgentContext m_agentContext;
 
@@ -51,23 +54,25 @@ public class DiscoveryHandlerImpl implem
     // thread-safe.
     @Override
     public URL getServerUrl() {
-        String configValue = m_agentContext.getConfigurationHandler().getMap().get(DISCOVERY_CONFIG_KEY);
-        if (configValue == null || configValue.equals(""))
-            try {
-                return new URL("http://localhost:8080");
-            }
-            catch (MalformedURLException e) {
-                e.printStackTrace();
-            }
+        ConfigurationHandler configurationHandler = m_agentContext.getConfigurationHandler();
+        LogService logService = m_agentContext.getLogService();
+
+        String configValue = configurationHandler.get(CONFIG_KEY_SERVERURLS, CONFIG_DEFAULT_SERVERURLS);
+        URL url = null;
         if (configValue.indexOf(",") == -1) {
-            return checkURL(configValue.trim());
+            url = checkURL(configValue.trim());
         }
-        for (String configValuePart : configValue.split(",")) {
-            URL url = checkURL(configValuePart.trim());
-            if (url != null)
-                return url;
+        else {
+            for (String configValuePart : configValue.split(",")) {
+                if (url == null) {
+                    url = checkURL(configValuePart.trim());
+                }
+            }
+        }
+        if (url == null) {
+            logService.log(LogService.LOG_WARNING, "No serverUrl available");
         }
-        return null;
+        return url;
     }
 
     private static final long CACHE_TIME = 1000;
@@ -85,18 +90,22 @@ public class DiscoveryHandlerImpl implem
     private final Map<String, CheckedURL> m_checkedURLs = new HashMap<String, DiscoveryHandlerImpl.CheckedURL>();
 
     private URL checkURL(String serverURL) {
+        LogService logService = m_agentContext.getLogService();
+
         CheckedURL checked = m_checkedURLs.get(serverURL);
         if (checked != null && checked.timestamp > (System.currentTimeMillis() - CACHE_TIME)) {
+            logService.log(LogService.LOG_DEBUG, "Returning cached serverURL: " + checked.url.toExternalForm());
             return checked.url;
         }
         try {
             URL url = new URL(serverURL);
             tryConnect(url);
+            logService.log(LogService.LOG_DEBUG, "Succesfully connected to  serverURL: " + serverURL);
             m_checkedURLs.put(serverURL, new CheckedURL(url, System.currentTimeMillis()));
             return url;
         }
         catch (IOException e) {
-            // TODO log
+            logService.log(LogService.LOG_DEBUG, "Failed to connect to serverURL: " + serverURL);
             return null;
         }
     }

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/FeedbackChannelImpl.java Tue Aug 20 15:48:28 2013
@@ -350,7 +350,7 @@ public class FeedbackChannelImpl impleme
     }
 
     private String getIdentification() {
-        return m_agentContext.getIdentificationHandler().getIdentification();
+        return m_agentContext.getIdentificationHandler().getAgentId();
     }
 
     private URL getServerURL() {

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/IdentificationHandlerImpl.java Tue Aug 20 15:48:28 2013
@@ -18,6 +18,7 @@
  */
 package org.apache.ace.agent.impl;
 
+import org.apache.ace.agent.ConfigurationHandler;
 import org.apache.ace.agent.IdentificationHandler;
 
 /**
@@ -27,12 +28,14 @@ import org.apache.ace.agent.Identificati
  */
 public class IdentificationHandlerImpl implements IdentificationHandler {
 
+    public static final String CONFIG_KEY_BASE = ConfigurationHandlerImpl.CONFIG_KEY_NAMESPACE + ".identification";
+
     /**
      * Configuration key for the default identification handler. The value must be a single file-system and URL safe
      * string.
      */
-    // TODO move to and validate in configuration handler?
-    public static final String IDENTIFICATION_CONFIG_KEY = "agent.discovery";
+    public static final String CONFIG_KEY_IDENTIFICATION = CONFIG_KEY_BASE + ".agentId";
+    public static final String CONFIG_DEFAULT_AGENTID = "defaultTargetID";
 
     private final AgentContext m_agentContext;
 
@@ -40,15 +43,10 @@ public class IdentificationHandlerImpl i
         m_agentContext = agentContext;
     }
 
-    // TODO add a default fallback?
     @Override
-    public String getIdentification() {
-        String configValue = m_agentContext.getConfigurationHandler().getMap().get(IDENTIFICATION_CONFIG_KEY);
-        if (configValue == null)
-            return "defaultTargetID";
-        configValue = configValue.trim();
-        if (configValue.equals(""))
-            return null;
+    public String getAgentId() {
+        ConfigurationHandler configurationHandler = m_agentContext.getConfigurationHandler();
+        String configValue = configurationHandler.get(CONFIG_KEY_IDENTIFICATION, CONFIG_DEFAULT_AGENTID);
         return configValue;
     }
 }

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/UpdateHandlerBase.java Tue Aug 20 15:48:28 2013
@@ -35,11 +35,11 @@ import org.osgi.framework.Version;
 
 public class UpdateHandlerBase {
     protected AgentContext m_agentContext;
-    
+
     public UpdateHandlerBase(AgentContext agentContext) {
         m_agentContext = agentContext;
     }
-    
+
     protected SortedSet<Version> getAvailableVersions(URL endpoint) throws RetryAfterException, IOException {
         SortedSet<Version> versions = new TreeSet<Version>();
         URLConnection connection = null;
@@ -79,7 +79,7 @@ public class UpdateHandlerBase {
             if (urlConnection instanceof HttpURLConnection) {
                 ((HttpURLConnection) urlConnection).setRequestMethod("HEAD");
             }
-    
+
             String dpSizeHeader = urlConnection.getHeaderField(AgentConstants.HEADER_DPSIZE);
             if (dpSizeHeader != null) {
                 try {
@@ -120,11 +120,16 @@ public class UpdateHandlerBase {
     }
 
     protected String getIdentification() {
-        return m_agentContext.getIdentificationHandler().getIdentification();
+        return m_agentContext.getIdentificationHandler().getAgentId();
     }
 
-    protected URL getServerURL() {
-        return m_agentContext.getDiscoveryHandler().getServerUrl();
+    protected URL getServerURL() throws RetryAfterException {
+        // FIXME not sure if this is the proper place
+        URL serverURL = m_agentContext.getDiscoveryHandler().getServerUrl();
+        if (serverURL == null) {
+            throw new RetryAfterException(10);
+        }
+        return serverURL;
     }
 
     private URLConnection getConnection(URL url) throws IOException {

Added: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java?rev=1515849&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java (added)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConfigurationHandlerImplTest.java Tue Aug 20 15:48:28 2013
@@ -0,0 +1,149 @@
+package org.apache.ace.agent.impl;
+
+import static org.easymock.EasyMock.expect;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import org.apache.ace.agent.ConfigurationHandler;
+import org.apache.ace.agent.testutil.BaseAgentTest;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ConfigurationHandlerImplTest extends BaseAgentTest {
+
+    private AgentContext m_agentContext;
+
+    @BeforeMethod
+    public void setUpAgain(Method method) throws Exception {
+        File methodDir = new File(new File(getWorkDir(), ConfigurationHandlerImplTest.class.getName()), method.getName());
+        methodDir.mkdirs();
+        cleanDir(methodDir);
+        m_agentContext = addTestMock(AgentContext.class);
+        expect(m_agentContext.getWorkDir()).andReturn(methodDir).anyTimes();
+        replayTestMocks();
+    }
+
+    @AfterMethod
+    public void tearDownAgain(Method method) throws Exception {
+        verifyTestMocks();
+        clearTestMocks();
+    }
+
+    @Test
+    public void testConfigClean() throws IOException {
+
+        ConfigurationHandler configurationHandler = new ConfigurationHandlerImpl(m_agentContext);
+        ReflectionUtil.invokeMethod(configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+
+        assertNotNull(configurationHandler.keySet());
+        assertEquals(0, configurationHandler.keySet().size());
+        assertEquals(configurationHandler.get("key1", "default1"), "default1");
+
+        // should be persisted
+
+        configurationHandler = new ConfigurationHandlerImpl(m_agentContext);
+        ReflectionUtil.invokeMethod(configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+
+        assertNotNull(configurationHandler.keySet());
+        assertEquals(0, configurationHandler.keySet().size());
+        assertEquals(configurationHandler.get("key1", "default1"), "default1");
+    }
+
+    @Test
+    public void testConfigSystemProps() throws IOException {
+
+        String systemKey1 = ConfigurationHandlerImpl.CONFIG_KEY_NAMESPACE + "key1";
+        String systemKey2 = ConfigurationHandlerImpl.CONFIG_KEY_NAMESPACE + "key2";
+
+        System.setProperty(systemKey1, "value1");
+        System.setProperty(systemKey2, "value2");
+
+        ConfigurationHandler configurationHandler = new ConfigurationHandlerImpl(m_agentContext);
+        ReflectionUtil.invokeMethod(configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+
+        assertNotNull(configurationHandler.keySet());
+        assertEquals(2, configurationHandler.keySet().size());
+        assertEquals(configurationHandler.get(systemKey1, "qqq"), "value1");
+        assertEquals(configurationHandler.get(systemKey2, "qqq"), "value2");
+
+        // should be persisted
+
+        System.clearProperty(systemKey1);
+        System.clearProperty(systemKey2);
+
+        configurationHandler = new ConfigurationHandlerImpl(m_agentContext);
+        ReflectionUtil.invokeMethod(configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+
+        assertNotNull(configurationHandler.keySet());
+        assertEquals(2, configurationHandler.keySet().size());
+        assertEquals(configurationHandler.get(systemKey1, "qqq"), "value1");
+        assertEquals(configurationHandler.get(systemKey2, "qqq"), "value2");
+
+        // should not overwrite by default
+
+        System.setProperty(systemKey1, "value1");
+        System.setProperty(systemKey2, "value2");
+
+        configurationHandler.put(systemKey1, "newvalue1");
+        configurationHandler.put(systemKey2, "newvalue2");
+
+        configurationHandler = new ConfigurationHandlerImpl(m_agentContext);
+        ReflectionUtil.invokeMethod(configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+
+        assertNotNull(configurationHandler.keySet());
+        assertEquals(2, configurationHandler.keySet().size());
+        assertEquals(configurationHandler.get(systemKey1, "qqq"), "newvalue1");
+        assertEquals(configurationHandler.get(systemKey2, "qqq"), "newvalue2");
+
+        // should overwrite if flag is set
+
+        System.setProperty(systemKey1, "value1");
+        System.setProperty(systemKey2, "value2");
+        System.setProperty(systemKey1 + ConfigurationHandlerImpl.CONFIG_KEY_OVERRIDEPOSTFIX, "true");
+        System.setProperty(systemKey2 + ConfigurationHandlerImpl.CONFIG_KEY_OVERRIDEPOSTFIX, "true");
+
+        configurationHandler = new ConfigurationHandlerImpl(m_agentContext);
+        ReflectionUtil.invokeMethod(configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+
+        assertNotNull(configurationHandler.keySet());
+        assertEquals(2, configurationHandler.keySet().size());
+        assertEquals(configurationHandler.get(systemKey1, "qqq"), "value1");
+        assertEquals(configurationHandler.get(systemKey2, "qqq"), "value2");
+    }
+
+    @Test
+    public void testConfigBooleanProps() throws IOException {
+
+        ConfigurationHandler configurationHandler = new ConfigurationHandlerImpl(m_agentContext);
+        ReflectionUtil.invokeMethod(configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+
+        configurationHandler.putBoolean("boolean1", true);
+        configurationHandler.putBoolean("boolean2", false);
+
+        assertEquals(configurationHandler.getBoolean("boolean1", false), true);
+        assertEquals(configurationHandler.getBoolean("boolean2", true), false);
+
+        assertEquals(configurationHandler.getBoolean("booleanX", true), true);
+        assertEquals(configurationHandler.getBoolean("booleanY", false), false);
+    }
+
+    @Test
+    public void testConfigLongProps() throws IOException {
+
+        ConfigurationHandler configurationHandler = new ConfigurationHandlerImpl(m_agentContext);
+        ReflectionUtil.invokeMethod(configurationHandler, "start", new Class<?>[] {}, new Object[] {});
+
+        configurationHandler.putLong("long1", 42);
+        configurationHandler.putLong("long2", 4l);
+
+        assertEquals(configurationHandler.getLong("long1", 0l), 42);
+        assertEquals(configurationHandler.getLong("long2", 0l), 4l);
+
+        assertEquals(configurationHandler.getLong("longX", 42l), 42l);
+    }
+}

Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/ConnectionHandlerImplTest.java Tue Aug 20 15:48:28 2013
@@ -18,7 +18,11 @@
  */
 package org.apache.ace.agent.impl;
 
+import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.notNull;
+import static org.easymock.EasyMock.reset;
 import static org.testng.Assert.assertEquals;
 
 import java.io.IOException;
@@ -68,12 +72,13 @@ public class ConnectionHandlerImplTest e
 
     }
 
-    Map<String, String> m_configuration = new HashMap<String, String>();
-    ConnectionHandler m_connectionHandler;
-    TestWebServer m_webServer;
-    String m_user = "Mickey";
-    String m_pass = "Mantle";
-    URL m_basicAuthURL;
+    private Map<String, String> m_configuration = new HashMap<String, String>();
+    private ConnectionHandler m_connectionHandler;
+    private TestWebServer m_webServer;
+    private String m_user = "Mickey";
+    private String m_pass = "Mantle";
+    private URL m_basicAuthURL;
+    private ConfigurationHandler m_configurationHandler;
 
     @BeforeTest
     public void setUpAgain() throws Exception {
@@ -84,14 +89,12 @@ public class ConnectionHandlerImplTest e
         m_webServer.addServlet(new BasicAuthServlet(m_user, m_pass), "/basicauth/*");
         m_webServer.start();
 
-        ConfigurationHandler configurationHandler = addTestMock(ConfigurationHandler.class);
-        expect(configurationHandler.getMap()).andReturn(m_configuration).anyTimes();
-
+        m_configurationHandler = addTestMock(ConfigurationHandler.class);
         AgentContext agentContext = addTestMock(AgentContext.class);
-        expect(agentContext.getConfigurationHandler()).andReturn(configurationHandler).anyTimes();
+        m_connectionHandler = new ConnectionHandlerImpl(agentContext);
 
+        expect(agentContext.getConfigurationHandler()).andReturn(m_configurationHandler).anyTimes();
         replayTestMocks();
-        m_connectionHandler = new ConnectionHandlerImpl(agentContext);
     }
 
     @AfterTest
@@ -102,16 +105,21 @@ public class ConnectionHandlerImplTest e
 
     @Test
     public void testBasicAuthFORBIDDEN() throws Exception {
-        m_configuration.clear();
+        reset(m_configurationHandler);
+        expect(m_configurationHandler.get(notNull(String.class), anyObject(String.class))).andReturn(null).anyTimes();
+        replay(m_configurationHandler);
         HttpURLConnection connection = (HttpURLConnection) m_connectionHandler.getConnection(m_basicAuthURL);
         assertEquals(connection.getResponseCode(), HttpServletResponse.SC_FORBIDDEN);
+        
     }
 
     @Test
     public void testBasicAuthOK() throws Exception {
-        m_configuration.put(ConnectionHandlerImpl.PROP_AUTHTYPE, "BASIC");
-        m_configuration.put(ConnectionHandlerImpl.PROP_AUTHUSER, m_user);
-        m_configuration.put(ConnectionHandlerImpl.PROP_AUTHPASS, m_pass);
+        reset(m_configurationHandler);
+        expect(m_configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHTYPE), anyObject(String.class))).andReturn("BASIC").anyTimes();
+        expect(m_configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHUSER), anyObject(String.class))).andReturn(m_user).anyTimes();
+        expect(m_configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHPASS), anyObject(String.class))).andReturn(m_pass).anyTimes();
+        replay(m_configurationHandler);
         HttpURLConnection connection = (HttpURLConnection) m_connectionHandler.getConnection(m_basicAuthURL);
         assertEquals(connection.getResponseCode(), HttpServletResponse.SC_OK);
     }

Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DeploymentHandlerTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DeploymentHandlerTest.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DeploymentHandlerTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DeploymentHandlerTest.java Tue Aug 20 15:48:28 2013
@@ -18,6 +18,7 @@
  */
 package org.apache.ace.agent.impl;
 
+import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.notNull;
 import static org.testng.Assert.assertEquals;
@@ -146,13 +147,13 @@ public class DeploymentHandlerTest exten
         expect(deploymentPackage3.getVersion()).andReturn(Version.parseVersion("3.0.0")).anyTimes();
 
         IdentificationHandler identificationHandler = addTestMock(IdentificationHandler.class);
-        expect(identificationHandler.getIdentification()).andReturn(identification).anyTimes();
+        expect(identificationHandler.getAgentId()).andReturn(identification).anyTimes();
 
         DiscoveryHandler discoveryHandler = addTestMock(DiscoveryHandler.class);
         expect(discoveryHandler.getServerUrl()).andReturn(serverURL).anyTimes();
 
         ConfigurationHandler configurationHandler = addTestMock(ConfigurationHandler.class);
-        expect(configurationHandler.getMap()).andReturn(new HashMap<String, String>()).anyTimes();
+        expect(configurationHandler.get(notNull(String.class), anyObject(String.class))).andReturn(null).anyTimes();
 
         DeploymentAdmin deploymentAdmin = addTestMock(DeploymentAdmin.class);
         expect(deploymentAdmin.listDeploymentPackages()).andReturn(

Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/DiscoveryHandlerImplTest.java Tue Aug 20 15:48:28 2013
@@ -18,58 +18,52 @@
  */
 package org.apache.ace.agent.impl;
 
+import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 
 import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
 
 import org.apache.ace.agent.ConfigurationHandler;
 import org.apache.ace.agent.ConnectionHandler;
 import org.apache.ace.agent.DiscoveryHandler;
-import org.apache.ace.agent.impl.AgentContext;
-import org.apache.ace.agent.impl.ConnectionHandlerImpl;
-import org.apache.ace.agent.impl.DiscoveryHandlerImpl;
 import org.apache.ace.agent.testutil.BaseAgentTest;
 import org.apache.ace.agent.testutil.TestWebServer;
+import org.osgi.service.log.LogService;
 import org.testng.annotations.AfterTest;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
 public class DiscoveryHandlerImplTest extends BaseAgentTest {
 
-    Map<String, String> configuration = new HashMap<String, String>();
-
-    DiscoveryHandler m_discoveryHandler;
-
-    TestWebServer m_webServer;
-    TestWebServer m_secondWebServer;
-
-    URL m_availableURL;
-    URL m_unavailableURL;
+    private final int PORT = 8882;
+    private TestWebServer m_webServer;
+    private URL m_availableURL;
+    private URL m_unavailableURL;
+    private DiscoveryHandler m_discoveryHandler;
+    private ConfigurationHandler configurationHandler;
 
     @BeforeTest
     public void setUpAgain() throws Exception {
 
-        int port = 8882;
-        m_webServer = new TestWebServer(port, "/", "generated");
+        m_webServer = new TestWebServer(PORT, "/", "generated");
         m_webServer.start();
-
-        m_availableURL = new URL("http://localhost:" + port);
+        m_availableURL = new URL("http://localhost:" + PORT);
         m_unavailableURL = new URL("http://localhost:9999");
 
         AgentContext agentContext = addTestMock(AgentContext.class);
+        LogService logService = addTestMock(LogService.class);
+        resetToNice(logService);
         m_discoveryHandler = new DiscoveryHandlerImpl(agentContext);
-
-        ConfigurationHandler configurationHandler = addTestMock(ConfigurationHandler.class);
-        expect(configurationHandler.getMap()).andReturn(configuration).anyTimes();
-
+        configurationHandler = addTestMock(ConfigurationHandler.class);
         ConnectionHandler connectionHandler = new ConnectionHandlerImpl(agentContext);
-
         expect(agentContext.getConfigurationHandler()).andReturn(configurationHandler).anyTimes();
         expect(agentContext.getConnectionHandler()).andReturn(connectionHandler).anyTimes();
+        expect(agentContext.getLogService()).andReturn(logService).anyTimes();
 
         replayTestMocks();
     }
@@ -82,55 +76,84 @@ public class DiscoveryHandlerImplTest ex
 
     @Test
     public void testAvailableURL() throws Exception {
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, m_availableURL.toExternalForm());
+        reset(configurationHandler);
+        expect(configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHTYPE), anyObject(String.class)))
+            .andReturn(null).anyTimes();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn(m_availableURL.toExternalForm()).anyTimes();
+        replay(configurationHandler);
         assertEquals(m_discoveryHandler.getServerUrl(), m_availableURL);
     }
 
     @Test
     public void testUnavailableURL_unavailable() throws Exception {
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, m_unavailableURL.toExternalForm());
+        reset(configurationHandler);
+        expect(configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHTYPE), anyObject(String.class)))
+            .andReturn(null).anyTimes();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn(m_unavailableURL.toExternalForm()).anyTimes();
+        replay(configurationHandler);
         assertNull(m_discoveryHandler.getServerUrl());
     }
 
     @Test
     public void testUnavailableAfterConfigUpdate() throws Exception {
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, m_availableURL.toExternalForm());
+        reset(configurationHandler);
+        expect(configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHTYPE), anyObject(String.class)))
+            .andReturn(null).anyTimes();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn(m_availableURL.toExternalForm()).once();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn(m_unavailableURL.toExternalForm()).once();
+        replay(configurationHandler);
         assertEquals(m_discoveryHandler.getServerUrl(), m_availableURL);
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, m_unavailableURL.toExternalForm());
         assertNull(m_discoveryHandler.getServerUrl());
     }
 
     @Test
     public void testAvailableAfterConfigUpdate() throws Exception {
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, m_unavailableURL.toExternalForm());
+        reset(configurationHandler);
+        expect(configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHTYPE), anyObject(String.class)))
+            .andReturn(null).anyTimes();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn(m_unavailableURL.toExternalForm()).once();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn(m_availableURL.toExternalForm()).once();
+        replay(configurationHandler);
         assertNull(m_discoveryHandler.getServerUrl());
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, m_availableURL.toExternalForm());
         assertEquals(m_discoveryHandler.getServerUrl(), m_availableURL);
     }
 
     @Test
     public void testAvailableAfterUnavailableURL() throws Exception {
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, m_unavailableURL.toExternalForm() + "," + m_availableURL.toExternalForm());
+        reset(configurationHandler);
+        expect(configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHTYPE), anyObject(String.class)))
+            .andReturn(null).anyTimes();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn(m_unavailableURL.toExternalForm() + "," + m_availableURL.toExternalForm()).once();
+        replay(configurationHandler);
         assertEquals(m_discoveryHandler.getServerUrl(), m_availableURL);
     }
 
-    // tmp default in implementation
-    @Test(enabled=false)
-    public void testNoURLConfig() throws Exception {
-        configuration.clear();
-        assertNull(m_discoveryHandler.getServerUrl());
-    }
-
-    // tmp default in implementation
-    @Test(enabled=false)
+    @Test
     public void testEmptyURLConfig() throws Exception {
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, "");
+        reset(configurationHandler);
+        expect(configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHTYPE), anyObject(String.class)))
+            .andReturn(null).anyTimes();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn("").once();
+        replay(configurationHandler);
         assertNull(m_discoveryHandler.getServerUrl());
     }
 
     @Test
     public void testBadURLConfig() throws Exception {
-        configuration.put(DiscoveryHandlerImpl.DISCOVERY_CONFIG_KEY, "fooBar");
+        reset(configurationHandler);
+        expect(configurationHandler.get(eq(ConnectionHandlerImpl.PROP_AUTHTYPE), anyObject(String.class)))
+            .andReturn(null).anyTimes();
+        expect(configurationHandler.get(eq(DiscoveryHandlerImpl.CONFIG_KEY_SERVERURLS), anyObject(String.class)))
+            .andReturn("foobar").once();
+        replay(configurationHandler);
         assertNull(m_discoveryHandler.getServerUrl());
     }
 }

Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/IdentificationhandlerImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/IdentificationhandlerImplTest.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/IdentificationhandlerImplTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/impl/IdentificationhandlerImplTest.java Tue Aug 20 15:48:28 2013
@@ -18,13 +18,14 @@
  */
 package org.apache.ace.agent.impl;
 
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.apache.ace.agent.ConfigurationHandler;
 import org.apache.ace.agent.IdentificationHandler;
 import org.apache.ace.agent.testutil.BaseAgentTest;
@@ -34,16 +35,15 @@ import org.testng.annotations.Test;
 
 public class IdentificationhandlerImplTest extends BaseAgentTest {
 
-    Map<String, String> m_configuration = new HashMap<String, String>();
-    IdentificationHandler m_identificationHandler;
+    private IdentificationHandler m_identificationHandler;
+    private ConfigurationHandler m_configurationHandler;
 
     @BeforeTest
     public void setUpAgain() throws Exception {
         AgentContext agentContext = addTestMock(AgentContext.class);
         m_identificationHandler = new IdentificationHandlerImpl(agentContext);
-        ConfigurationHandler configurationHandler = addTestMock(ConfigurationHandler.class);
-        expect(configurationHandler.getMap()).andReturn(m_configuration).anyTimes();
-        expect(agentContext.getConfigurationHandler()).andReturn(configurationHandler).anyTimes();
+        m_configurationHandler = addTestMock(ConfigurationHandler.class);
+        expect(agentContext.getConfigurationHandler()).andReturn(m_configurationHandler).anyTimes();
         replayTestMocks();
     }
 
@@ -54,28 +54,40 @@ public class IdentificationhandlerImplTe
 
     @Test
     public void testAvailableIdentification() throws Exception {
-        m_configuration.put(IdentificationHandlerImpl.IDENTIFICATION_CONFIG_KEY, "qqq");
-        assertEquals(m_identificationHandler.getIdentification(), "qqq");
+        reset(m_configurationHandler);
+        expect(m_configurationHandler.get(eq(IdentificationHandlerImpl.CONFIG_KEY_IDENTIFICATION), anyObject(String.class)))
+            .andReturn("qqq").once();
+        replay(m_configurationHandler);
+        assertEquals(m_identificationHandler.getAgentId(), "qqq");
     }
 
     @Test
     public void testUpdatedIdentification() throws Exception {
-        m_configuration.put(IdentificationHandlerImpl.IDENTIFICATION_CONFIG_KEY, "qqq");
-        assertEquals(m_identificationHandler.getIdentification(), "qqq");
-        m_configuration.put(IdentificationHandlerImpl.IDENTIFICATION_CONFIG_KEY, "yyy");
-        assertEquals(m_identificationHandler.getIdentification(), "yyy");
+        reset(m_configurationHandler);
+        expect(m_configurationHandler.get(eq(IdentificationHandlerImpl.CONFIG_KEY_IDENTIFICATION), anyObject(String.class)))
+            .andReturn("qqq").once();
+        expect(m_configurationHandler.get(eq(IdentificationHandlerImpl.CONFIG_KEY_IDENTIFICATION), anyObject(String.class)))
+            .andReturn("yyy").once();
+        replay(m_configurationHandler);
+        assertEquals(m_identificationHandler.getAgentId(), "qqq");
+        assertEquals(m_identificationHandler.getAgentId(), "yyy");
     }
 
-    // temp default in implementation
-    @Test(enabled=false)
+    @Test
     public void testNoIdentification() throws Exception {
-        m_configuration.clear();
-        assertNull(m_identificationHandler.getIdentification());
+        reset(m_configurationHandler);
+        expect(m_configurationHandler.get(eq(IdentificationHandlerImpl.CONFIG_KEY_IDENTIFICATION), anyObject(String.class)))
+            .andReturn(null).once();
+        replay(m_configurationHandler);
+        assertNull(m_identificationHandler.getAgentId());
     }
 
     @Test
     public void testEmptyIdentification() throws Exception {
-        m_configuration.put(IdentificationHandlerImpl.IDENTIFICATION_CONFIG_KEY, " ");
-        assertNull(m_identificationHandler.getIdentification());
+        reset(m_configurationHandler);
+        expect(m_configurationHandler.get(eq(IdentificationHandlerImpl.CONFIG_KEY_IDENTIFICATION), anyObject(String.class)))
+            .andReturn(null).once();
+        replay(m_configurationHandler);
+        assertNull(m_identificationHandler.getAgentId());
     }
 }

Modified: ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java?rev=1515849&r1=1515848&r2=1515849&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java (original)
+++ ace/trunk/org.apache.ace.agent/test/org/apache/ace/agent/testutil/BaseAgentTest.java Tue Aug 20 15:48:28 2013
@@ -22,8 +22,10 @@ import static org.easymock.EasyMock.crea
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
+import java.io.File;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.Stack;
 
 public class BaseAgentTest {
 
@@ -48,4 +50,27 @@ public class BaseAgentTest {
     protected void clearTestMocks() {
         m_mocks.clear();
     }
+
+    protected File getWorkDir() {
+        return new File("generated");
+    }
+
+    protected 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();
+                }
+            }
+        }
+    }
 }