Repository: cxf-dosgi Updated Branches: refs/heads/master 3ddd9f034 -> 7b8225d57
DOSGI-215 Organize and Optimize ManagedService implementations Project: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/commit/7b8225d5 Tree: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/tree/7b8225d5 Diff: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/diff/7b8225d5 Branch: refs/heads/master Commit: 7b8225d579b059d0084c5c9d39a8e729fc7e1c7f Parents: 3ddd9f0 Author: Amichai Rothman <[email protected]> Authored: Sun Mar 16 22:16:04 2014 +0200 Committer: Amichai Rothman <[email protected]> Committed: Sun Mar 16 22:19:17 2014 +0200 ---------------------------------------------------------------------- .../discovery/zookeeper/ZooKeeperDiscovery.java | 39 ++++++++---- .../dosgi/discovery/zookeeper/util/Utils.java | 37 +++++++++-- .../zookeeper/server/ZookeeperStarter.java | 22 ++++--- .../org/apache/cxf/dosgi/dsw/Activator.java | 67 ++++++++++++-------- .../org/apache/cxf/dosgi/dsw/util/Utils.java | 21 ++++-- 5 files changed, 122 insertions(+), 64 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/7b8225d5/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/ZooKeeperDiscovery.java ---------------------------------------------------------------------- diff --git a/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/ZooKeeperDiscovery.java b/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/ZooKeeperDiscovery.java index 191ced2..33e2da4 100644 --- a/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/ZooKeeperDiscovery.java +++ b/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/ZooKeeperDiscovery.java @@ -51,23 +51,34 @@ public class ZooKeeperDiscovery implements Watcher, ManagedService { private boolean closed; private boolean started; - private Dictionary<String , ?> curConfiguration; + private Dictionary<String, ?> curConfiguration; public ZooKeeperDiscovery(BundleContext bctx) { this.bctx = bctx; - this.curConfiguration = null; } + private void setDefaults(Dictionary<String, String> configuration) { + Utils.setDefault(configuration, "zookeeper.host", "localhost"); + Utils.setDefault(configuration, "zookeeper.port", "2181"); + Utils.setDefault(configuration, "zookeeper.timeout", "3000"); + } + + @SuppressWarnings("unchecked") public synchronized void updated(Dictionary<String, ?> configuration) throws ConfigurationException { LOG.debug("Received configuration update for Zookeeper Discovery: {}", configuration); - - stop(false); - - if (configuration == null) { - return; + if (configuration != null) { + setDefaults((Dictionary<String, String>)configuration); + } + // make changes only if config actually changed, to prevent unnecessary ZooKeeper reconnections + if (!Utils.toMap(configuration).equals(Utils.toMap(curConfiguration))) { + stop(false); + curConfiguration = configuration; + // config is null if it doesn't exist, is being deleted or has not yet been loaded + // in which case we just stop running + if (configuration != null) { + createZooKeeper(configuration); + } } - curConfiguration = configuration; - createZooKeeper(configuration); } private synchronized void start() { @@ -83,7 +94,7 @@ public class ZooKeeperDiscovery implements Watcher, ManagedService { endpointListenerFactory = new PublishingEndpointListenerFactory(zk, bctx); endpointListenerFactory.start(); imManager = new InterfaceMonitorManager(bctx, zk); - endpointListenerTracker = new EndpointListenerTracker(bctx, imManager); + endpointListenerTracker = new EndpointListenerTracker(bctx, imManager); endpointListenerTracker.open(); started = true; } @@ -112,13 +123,13 @@ public class ZooKeeperDiscovery implements Watcher, ManagedService { } } - private synchronized void createZooKeeper(Dictionary<String, ?> props) { + private synchronized void createZooKeeper(Dictionary<String, ?> configuration) { if (closed) { return; } - String host = Utils.getProp(props, "zookeeper.host", "localhost"); - String port = Utils.getProp(props, "zookeeper.port", "2181"); - int timeout = Utils.getProp(props, "zookeeper.timeout", 3000); + String host = configuration.get("zookeeper.host").toString(); + String port = configuration.get("zookeeper.port").toString(); + int timeout = Integer.parseInt(configuration.get("zookeeper.timeout").toString()); LOG.debug("ZooKeeper configuration: connecting to {}:{} with timeout {}", new Object[]{host, port, timeout}); try { http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/7b8225d5/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java ---------------------------------------------------------------------- diff --git a/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java b/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java index 121546e..5fcb111 100644 --- a/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java +++ b/discovery/distributed/cxf-discovery/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java @@ -21,6 +21,7 @@ package org.apache.cxf.dosgi.discovery.zookeeper.util; import java.util.Arrays; import java.util.Collection; import java.util.Dictionary; +import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -107,14 +108,38 @@ public final class Utils { } } - public static <K, V> String getProp(Dictionary<K, V> props, String key, String def) { - V val = props.get(key); - return val == null ? def : val.toString(); + /** + * Puts the given key-value pair in the given dictionary if the key does not + * already exist in it or if its existing value is null. + * + * @param dict a dictionary + * @param key the key + * @param value the default value to set + */ + public static void setDefault(Dictionary<String, String> dict, String key, String value) { + if (dict.get(key) == null) { + dict.put(key, value); + } } - public static <K, V> int getProp(Dictionary<K, V> props, String key, int def) { - V val = props.get(key); - return val == null ? def : Integer.parseInt(val.toString()); + /** + * Converts the given Dictionary to a Map. + * + * @param dict a dictionary + * @param <K> the key type + * @param <V> the value type + * @return the converted map, or an empty map if the given dictionary is null + */ + public static <K, V> Map<K, V> toMap(Dictionary<K, V> dict) { + Map<K, V> map = new HashMap<K, V>(); + if (dict != null) { + Enumeration<K> keys = dict.keys(); + while (keys.hasMoreElements()) { + K key = keys.nextElement(); + map.put(key, dict.get(key)); + } + } + return map; } public static String getObjectClass(String scope) { http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/7b8225d5/discovery/distributed/zookeeper-server/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/server/ZookeeperStarter.java ---------------------------------------------------------------------- diff --git a/discovery/distributed/zookeeper-server/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/server/ZookeeperStarter.java b/discovery/distributed/zookeeper-server/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/server/ZookeeperStarter.java index 4bf772a..69baf15 100644 --- a/discovery/distributed/zookeeper-server/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/server/ZookeeperStarter.java +++ b/discovery/distributed/zookeeper-server/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/server/ZookeeperStarter.java @@ -72,17 +72,19 @@ public class ZookeeperStarter implements org.osgi.service.cm.ManagedService { @SuppressWarnings("unchecked") public synchronized void updated(Dictionary<String, ?> dict) throws ConfigurationException { + LOG.debug("Received configuration update for Zookeeper Server: " + dict); shutdown(); - if (dict == null) { - return; - } - try { - setDefaults((Dictionary<String, String>)dict); - QuorumPeerConfig config = parseConfig(dict); - startFromConfig(config); - LOG.info("Applied configuration update: " + dict); - } catch (Exception th) { - LOG.error("Problem applying configuration update: " + dict, th); + // config is null if it doesn't exist, is being deleted or has not yet been loaded + // in which case we just stop running + if (dict != null) { + try { + setDefaults((Dictionary<String, String>) dict); + QuorumPeerConfig config = parseConfig(dict); + startFromConfig(config); + LOG.info("Applied configuration update: " + dict); + } catch (Exception th) { + LOG.error("Problem applying configuration update: " + dict, th); + } } } http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/7b8225d5/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java index 470ecc3..fa4a570 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java @@ -20,6 +20,7 @@ package org.apache.cxf.dosgi.dsw; import java.util.ArrayList; import java.util.Dictionary; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -62,16 +63,22 @@ public class Activator implements ManagedService, BundleActivator { private HttpServiceManager httpServiceManager; private BundleContext bc; private BundleListener bundleListener; + private Map<String, Object> curConfiguration; public void start(BundleContext bundlecontext) throws Exception { LOG.debug("RemoteServiceAdmin Implementation is starting up"); this.bc = bundlecontext; // Disable the fast infoset as it's not compatible (yet) with OSGi System.setProperty("org.apache.cxf.nofastinfoset", "true"); - init(new Hashtable<String, Object>()); + curConfiguration = getDefaultConfig(); + init(curConfiguration); registerManagedService(bc); } + private Map<String, Object> getDefaultConfig() { + return new HashMap<String, Object>(); + } + private synchronized void init(Map<String, Object> config) { String httpBase = (String) config.get(org.apache.cxf.dosgi.dsw.Constants.HTTP_BASE); String cxfServletAlias = (String) config.get(org.apache.cxf.dosgi.dsw.Constants.CXF_SERVLET_ALIAS); @@ -98,6 +105,30 @@ public class Activator implements ManagedService, BundleActivator { decoratorReg = bc.registerService(ServiceDecorator.class.getName(), serviceDecorator, null); } + private synchronized void uninit() { + if (decoratorReg != null) { + decoratorReg.unregister(); + decoratorReg = null; + } + if (bundleListener != null) { + bc.removeBundleListener(bundleListener); + bundleListener = null; + } + if (rsaFactoryReg != null) { + // This also triggers the unimport and unexport of the remote services + rsaFactoryReg.unregister(); + rsaFactoryReg = null; + } + if (httpServiceManager != null) { + httpServiceManager.close(); + httpServiceManager = null; + } + if (intentTracker != null) { + intentTracker.close(); + intentTracker = null; + } + } + // The CT sometimes uses the first element returned to register a service, but // does not provide any additional configuration. // Return the configuration type that works without additional configuration as the first in the list. @@ -120,16 +151,7 @@ public class Activator implements ManagedService, BundleActivator { public void stop(BundleContext context) throws Exception { LOG.debug("RemoteServiceAdmin Implementation is shutting down now"); - bc.removeBundleListener(bundleListener); - intentTracker.close(); - // This also triggers the unimport and unexport of the remote services - rsaFactoryReg.unregister(); - decoratorReg.unregister(); - httpServiceManager.close(); - httpServiceManager = null; - intentTracker = null; - rsaFactoryReg = null; - decoratorReg = null; + uninit(); shutdownCXFBus(); } @@ -147,22 +169,13 @@ public class Activator implements ManagedService, BundleActivator { @SuppressWarnings({ "rawtypes", "unchecked" }) public synchronized void updated(Dictionary config) throws ConfigurationException { LOG.debug("RemoteServiceAdmin Implementation configuration is updated with {}", config); - if (config != null) { - try { - bc.removeBundleListener(bundleListener); - intentTracker.close(); - // This also triggers the unimport and unexport of the remote services - rsaFactoryReg.unregister(); - decoratorReg.unregister(); - httpServiceManager.close(); - httpServiceManager = null; - intentTracker = null; - rsaFactoryReg = null; - decoratorReg = null; - } catch (Exception e) { - LOG.error(e.getMessage(), e); - } - init(Utils.toMap(config)); + // config is null if it doesn't exist, is being deleted or has not yet been loaded + // in which case we run with defaults (just like we do manually when bundle is first started) + Map<String, Object> configMap = config == null ? getDefaultConfig() : Utils.toMap(config); + if (!configMap.equals(curConfiguration)) { // only if something actually changed + curConfiguration = configMap; + uninit(); + init(configMap); } } http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/7b8225d5/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/Utils.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/Utils.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/Utils.java index a101d21..83347b5 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/Utils.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/Utils.java @@ -73,15 +73,22 @@ public final class Utils { return null; } + /** + * Converts the given Dictionary to a Map. + * + * @param dict a dictionary + * @param <K> the key type + * @param <V> the value type + * @return the converted map, or an empty map if the given dictionary is null + */ public static <K, V> Map<K, V> toMap(Dictionary<K, V> dict) { Map<K, V> map = new HashMap<K, V>(); - if (dict == null) { - return map; - } - Enumeration<K> keys = dict.keys(); - while (keys.hasMoreElements()) { - K key = keys.nextElement(); - map.put(key, dict.get(key)); + if (dict != null) { + Enumeration<K> keys = dict.keys(); + while (keys.hasMoreElements()) { + K key = keys.nextElement(); + map.put(key, dict.get(key)); + } } return map; }
