You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by cs...@apache.org on 2016/03/11 20:43:37 UTC
[38/50] [abbrv] aries-rsa git commit: Switch project setup to Aries
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitor.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitor.java b/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitor.java
new file mode 100644
index 0000000..95277d3
--- /dev/null
+++ b/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitor.java
@@ -0,0 +1,262 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper.subscribe;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.dosgi.discovery.zookeeper.util.Utils;
+import org.apache.cxf.dosgi.endpointdesc.EndpointDescriptionParser;
+import org.apache.cxf.dosgi.endpointdesc.PropertiesMapper;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.xmlns.rsa.v1_0.EndpointDescriptionType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Monitors ZooKeeper for changes in published endpoints.
+ * <p>
+ * Specifically, it monitors the node path associated with a given interface class,
+ * whose data is a serialized version of an EndpointDescription, and notifies an
+ * EndpointListener when changes are detected (which can then propagate the
+ * notification to other EndpointListeners with a matching scope).
+ * <p>
+ * Note that the EndpointListener is used here as a decoupling interface for
+ * convenience, and is not necessarily used according to its documented contract.
+ */
+public class InterfaceMonitor implements Watcher, StatCallback {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceMonitor.class);
+
+ private final String znode;
+ private final ZooKeeper zk;
+ private final EndpointListener endpointListener;
+ private final boolean recursive;
+ private volatile boolean closed;
+
+ // This map reference changes, so don't synchronize on it
+ private Map<String, EndpointDescription> nodes = new HashMap<String, EndpointDescription>();
+
+ private EndpointDescriptionParser parser;
+
+ public InterfaceMonitor(ZooKeeper zk, String objClass, EndpointListener endpointListener, String scope) {
+ this.zk = zk;
+ this.znode = Utils.getZooKeeperPath(objClass);
+ this.recursive = objClass == null || objClass.isEmpty();
+ this.endpointListener = endpointListener;
+ this.parser = new EndpointDescriptionParser();
+ LOG.debug("Creating new InterfaceMonitor {} for scope [{}] and objectClass [{}]",
+ new Object[] {recursive ? "(recursive)" : "", scope, objClass});
+ }
+
+ /**
+ * Returns all endpoints that are currently known to this monitor.
+ *
+ * @return all endpoints that are currently known to this monitor
+ */
+ public synchronized List<EndpointDescription> getEndpoints() {
+ return new ArrayList<EndpointDescription>(nodes.values());
+ }
+
+ public void start() {
+ watch();
+ }
+
+ private void watch() {
+ LOG.debug("registering a ZooKeeper.exists({}) callback", znode);
+ zk.exists(znode, this, this, null);
+ }
+
+ /**
+ * Zookeeper Watcher interface callback.
+ */
+ public void process(WatchedEvent event) {
+ LOG.debug("ZooKeeper watcher callback on node {} for event {}", znode, event);
+ processDelta();
+ }
+
+ /**
+ * Zookeeper StatCallback interface callback.
+ */
+ @SuppressWarnings("deprecation")
+ public void processResult(int rc, String path, Object ctx, Stat stat) {
+ LOG.debug("ZooKeeper callback on node: {} code: {}", znode, rc);
+
+ switch (rc) {
+ case Code.Ok:
+ case Code.NoNode:
+ processDelta();
+ return;
+
+ case Code.SessionExpired:
+ case Code.NoAuth:
+ case Code.ConnectionLoss:
+ return;
+
+ default:
+ watch();
+ }
+ }
+
+ private void processDelta() {
+ if (closed) {
+ return;
+ }
+
+ if (zk.getState() != ZooKeeper.States.CONNECTED) {
+ LOG.debug("ZooKeeper connection was already closed! Not processing changed event.");
+ return;
+ }
+
+ try {
+ if (zk.exists(znode, false) != null) {
+ zk.getChildren(znode, this);
+ refreshNodes();
+ } else {
+ LOG.debug("znode {} doesn't exist -> not processing any changes", znode);
+ }
+ } catch (Exception e) {
+ if (zk.getState() != ZooKeeper.States.CONNECTED) {
+ LOG.debug("Error getting Zookeeper data: " + e); // e.g. session expired, handled by ZooKeeperDiscovery
+ } else {
+ LOG.error("Error getting ZooKeeper data.", e);
+ }
+ }
+ }
+
+ public synchronized void close() {
+ closed = true;
+ for (EndpointDescription endpoint : nodes.values()) {
+ endpointListener.endpointRemoved(endpoint, null);
+ }
+ nodes.clear();
+ }
+
+ private synchronized void refreshNodes() {
+ if (closed) {
+ return;
+ }
+ LOG.info("Processing change on node: {}", znode);
+
+ Map<String, EndpointDescription> newNodes = new HashMap<String, EndpointDescription>();
+ Map<String, EndpointDescription> prevNodes = new HashMap<String, EndpointDescription>(nodes);
+ processChildren(znode, newNodes, prevNodes);
+
+ // whatever is left in prevNodes now has been removed from Discovery
+ LOG.debug("processChildren done. Nodes that are missing now and need to be removed: {}", prevNodes.values());
+ for (EndpointDescription endpoint : prevNodes.values()) {
+ endpointListener.endpointRemoved(endpoint, null);
+ }
+ nodes = newNodes;
+ }
+
+ /**
+ * Iterates through all child nodes of the given node and tries to find
+ * endpoints. If the recursive flag is set it also traverses into the child
+ * nodes.
+ *
+ * @return true if an endpoint was found and if the node therefore needs to
+ * be monitored for changes
+ */
+ private boolean processChildren(String zn, Map<String, EndpointDescription> newNodes,
+ Map<String, EndpointDescription> prevNodes) {
+ List<String> children;
+ try {
+ LOG.debug("Processing the children of {}", zn);
+ children = zk.getChildren(zn, false);
+
+ boolean foundANode = false;
+ for (String child : children) {
+ String childZNode = zn + '/' + child;
+ EndpointDescription endpoint = getEndpointDescriptionFromNode(childZNode);
+ if (endpoint != null) {
+ EndpointDescription prevEndpoint = prevNodes.get(child);
+ LOG.info("found new node " + zn + "/[" + child + "] ( []->child ) props: "
+ + endpoint.getProperties().values());
+ newNodes.put(child, endpoint);
+ prevNodes.remove(child);
+ foundANode = true;
+ LOG.debug("Properties: {}", endpoint.getProperties());
+ if (prevEndpoint == null) {
+ // This guy is new
+ endpointListener.endpointAdded(endpoint, null);
+ } else if (!prevEndpoint.getProperties().equals(endpoint.getProperties())) {
+ // TODO
+ }
+ }
+ if (recursive && processChildren(childZNode, newNodes, prevNodes)) {
+ zk.getChildren(childZNode, this);
+ }
+ }
+
+ return foundANode;
+ } catch (KeeperException e) {
+ LOG.error("Problem processing ZooKeeper node", e);
+ } catch (InterruptedException e) {
+ LOG.error("Problem processing ZooKeeper node", e);
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves data from the given node and parses it into an EndpointDescription.
+ *
+ * @param node a node path
+ * @return endpoint found in the node or null if no endpoint was found
+ */
+ private EndpointDescription getEndpointDescriptionFromNode(String node) {
+ try {
+ Stat stat = zk.exists(node, false);
+ if (stat == null || stat.getDataLength() <= 0) {
+ return null;
+ }
+ byte[] data = zk.getData(node, false, null);
+ LOG.debug("Got data for node: {}", node);
+
+ EndpointDescription endpoint = getFirstEnpointDescription(data);
+ if (endpoint != null) {
+ return endpoint;
+ }
+ LOG.warn("No Discovery information found for node: {}", node);
+ } catch (Exception e) {
+ LOG.error("Problem getting EndpointDescription from node " + node, e);
+ }
+ return null;
+ }
+
+ public EndpointDescription getFirstEnpointDescription(byte[] data) {
+ List<EndpointDescriptionType> elements = parser.getEndpointDescriptions(new ByteArrayInputStream(data));
+ if (elements.isEmpty()) {
+ return null;
+ }
+ Map<String, Object> props = new PropertiesMapper().toProps(elements.get(0).getProperty());
+ return new EndpointDescription(props);
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManager.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManager.java b/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManager.java
new file mode 100644
index 0000000..240e5ea
--- /dev/null
+++ b/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManager.java
@@ -0,0 +1,218 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper.subscribe;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.cxf.dosgi.discovery.zookeeper.ZooKeeperDiscovery;
+import org.apache.cxf.dosgi.discovery.zookeeper.util.Utils;
+import org.apache.zookeeper.ZooKeeper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.cxf.dosgi.discovery.local.util.Utils.matchFilter;
+
+/**
+ * Manages the EndpointListeners and the scopes they are interested in.
+ * For each scope with interested EndpointListeners an InterfaceMonitor is created.
+ * The InterfaceMonitor calls back when it detects added or removed external Endpoints.
+ * These events are then forwarded to all interested EndpointListeners.
+ */
+public class InterfaceMonitorManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceMonitorManager.class);
+
+ private final BundleContext bctx;
+ private final ZooKeeper zk;
+ // map of EndpointListeners and the scopes they are interested in
+ private final Map<ServiceReference<EndpointListener>, List<String>> endpointListenerScopes =
+ new HashMap<ServiceReference<EndpointListener>, List<String>>();
+ // map of scopes and their interest data
+ private final Map<String, Interest> interests = new HashMap<String, Interest>();
+
+ protected static class Interest {
+ List<ServiceReference<EndpointListener>> endpointListeners =
+ new CopyOnWriteArrayList<ServiceReference<EndpointListener>>();
+ InterfaceMonitor monitor;
+ }
+
+ public InterfaceMonitorManager(BundleContext bctx, ZooKeeper zk) {
+ this.bctx = bctx;
+ this.zk = zk;
+ }
+
+ public void addInterest(ServiceReference<EndpointListener> endpointListener) {
+ if (isOurOwnEndpointListener(endpointListener)) {
+ LOG.debug("Skipping our own EndpointListener");
+ return;
+ }
+
+ LOG.info("updating EndpointListener interests: {}", endpointListener);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("updated EndpointListener properties: {}", Utils.getProperties(endpointListener));
+ }
+ for (String scope : Utils.getScopes(endpointListener)) {
+ String objClass = Utils.getObjectClass(scope);
+ LOG.debug("Adding interest in scope {}, objectClass {}", scope, objClass);
+ addInterest(endpointListener, scope, objClass);
+ }
+ }
+
+ private static boolean isOurOwnEndpointListener(ServiceReference<EndpointListener> endpointListener) {
+ return Boolean.parseBoolean(String.valueOf(
+ endpointListener.getProperty(ZooKeeperDiscovery.DISCOVERY_ZOOKEEPER_ID)));
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized void addInterest(ServiceReference<EndpointListener> endpointListener,
+ String scope, String objClass) {
+ // get or create interest for given scope and add listener to it
+ Interest interest = interests.get(scope);
+ if (interest == null) {
+ // create interest, add listener and start monitor
+ interest = new Interest();
+ interests.put(scope, interest);
+ interest.endpointListeners.add(endpointListener); // add it before monitor starts so we don't miss events
+ interest.monitor = createInterfaceMonitor(scope, objClass, interest);
+ interest.monitor.start();
+ } else {
+ // interest already exists, so just add listener to it
+ if (!interest.endpointListeners.contains(endpointListener)) {
+ interest.endpointListeners.add(endpointListener);
+ }
+ // notify listener of all known endpoints for given scope
+ // (as EndpointListener contract requires of all added/modified listeners)
+ for (EndpointDescription endpoint : interest.monitor.getEndpoints()) {
+ notifyListeners(endpoint, scope, true, Arrays.asList(endpointListener));
+ }
+ }
+
+ // add scope to listener's scopes list
+ List<String> scopes = endpointListenerScopes.get(endpointListener);
+ if (scopes == null) {
+ scopes = new ArrayList<String>(1);
+ endpointListenerScopes.put(endpointListener, scopes);
+ }
+ if (!scopes.contains(scope)) {
+ scopes.add(scope);
+ }
+ }
+
+ public synchronized void removeInterest(ServiceReference<EndpointListener> endpointListener) {
+ LOG.info("removing EndpointListener interests: {}", endpointListener);
+ List<String> scopes = endpointListenerScopes.get(endpointListener);
+ if (scopes == null) {
+ return;
+ }
+
+ for (String scope : scopes) {
+ Interest interest = interests.get(scope);
+ if (interest != null) {
+ interest.endpointListeners.remove(endpointListener);
+ if (interest.endpointListeners.isEmpty()) {
+ interest.monitor.close();
+ interests.remove(scope);
+ }
+ }
+ }
+ endpointListenerScopes.remove(endpointListener);
+ }
+
+ protected InterfaceMonitor createInterfaceMonitor(final String scope, String objClass, final Interest interest) {
+ // holding this object's lock in the callbacks can lead to a deadlock with InterfaceMonitor
+ EndpointListener endpointListener = new EndpointListener() {
+
+ public void endpointRemoved(EndpointDescription endpoint, String matchedFilter) {
+ notifyListeners(endpoint, scope, false, interest.endpointListeners);
+ }
+
+ public void endpointAdded(EndpointDescription endpoint, String matchedFilter) {
+ notifyListeners(endpoint, scope, true, interest.endpointListeners);
+ }
+ };
+ return new InterfaceMonitor(zk, objClass, endpointListener, scope);
+ }
+
+ private void notifyListeners(EndpointDescription endpoint, String currentScope, boolean isAdded,
+ List<ServiceReference<EndpointListener>> endpointListeners) {
+ for (ServiceReference<EndpointListener> endpointListenerRef : endpointListeners) {
+ EndpointListener service = bctx.getService(endpointListenerRef);
+ try {
+ EndpointListener endpointListener = (EndpointListener)service;
+ LOG.trace("matching {} against {}", endpoint, currentScope);
+ if (matchFilter(bctx, currentScope, endpoint)) {
+ LOG.debug("Matched {} against {}", endpoint, currentScope);
+ notifyListener(endpoint, currentScope, isAdded, endpointListenerRef.getBundle(),
+ endpointListener);
+ }
+ } finally {
+ if (service != null) {
+ bctx.ungetService(endpointListenerRef);
+ }
+ }
+ }
+ }
+
+ private void notifyListener(EndpointDescription endpoint, String currentScope, boolean isAdded,
+ Bundle endpointListenerBundle, EndpointListener endpointListener) {
+ if (endpointListenerBundle == null) {
+ LOG.info("listening service was unregistered, ignoring");
+ } else if (isAdded) {
+ LOG.info("calling EndpointListener.endpointAdded: " + endpointListener + " from bundle "
+ + endpointListenerBundle.getSymbolicName() + " for endpoint: " + endpoint);
+ endpointListener.endpointAdded(endpoint, currentScope);
+ } else {
+ LOG.info("calling EndpointListener.endpointRemoved: " + endpointListener + " from bundle "
+ + endpointListenerBundle.getSymbolicName() + " for endpoint: " + endpoint);
+ endpointListener.endpointRemoved(endpoint, currentScope);
+ }
+ }
+
+ public synchronized void close() {
+ for (Interest interest : interests.values()) {
+ interest.monitor.close();
+ }
+ interests.clear();
+ endpointListenerScopes.clear();
+ }
+
+ /**
+ * Only for test case!
+ */
+ protected synchronized Map<String, Interest> getInterests() {
+ return interests;
+ }
+
+ /**
+ * Only for test case!
+ */
+ protected synchronized Map<ServiceReference<EndpointListener>, List<String>> getEndpointListenerScopes() {
+ return endpointListenerScopes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java b/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java
new file mode 100644
index 0000000..5fcb111
--- /dev/null
+++ b/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.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;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+
+public final class Utils {
+
+ static final String PATH_PREFIX = "/osgi/service_registry";
+ static final Pattern OBJECTCLASS_PATTERN = Pattern.compile(".*\\(objectClass=([^)]+)\\).*");
+
+ private Utils() {
+ // never constructed
+ }
+
+ public static String getZooKeeperPath(String name) {
+ return name == null || name.isEmpty() ? PATH_PREFIX : PATH_PREFIX + '/' + name.replace('.', '/');
+ }
+
+ /**
+ * Returns the value of a "string+" property as an array of strings.
+ * <p>
+ * A "string+" property can have a value which is either a string,
+ * an array of strings, or a collection of strings.
+ * <p>
+ * If the given value is not of one of the valid types, or is null,
+ * an empty array is returned.
+ *
+ * @param property a "string+" property value
+ * @return the property value as an array of strings, or an empty array
+ */
+ public static String[] getStringPlusProperty(Object property) {
+ if (property instanceof String) {
+ return new String[] {(String)property};
+ } else if (property instanceof String[]) {
+ return (String[])property;
+ } else if (property instanceof Collection) {
+ try {
+ @SuppressWarnings("unchecked")
+ Collection<String> strings = (Collection<String>)property;
+ return strings.toArray(new String[strings.size()]);
+ } catch (ArrayStoreException ase) {
+ // ignore collections with wrong type
+ }
+ }
+ return new String[0];
+ }
+
+ /**
+ * Removes nulls and empty strings from the given string array.
+ *
+ * @param strings an array of strings
+ * @return a new array containing the non-null and non-empty
+ * elements of the original array in the same order
+ */
+ public static String[] removeEmpty(String[] strings) {
+ String[] result = new String[strings.length];
+ int copied = 0;
+ for (String s : strings) {
+ if (s != null && !s.isEmpty()) {
+ result[copied++] = s;
+ }
+ }
+ return copied == result.length ? result : Arrays.copyOf(result, copied);
+ }
+
+ public static String[] getScopes(ServiceReference<?> sref) {
+ return removeEmpty(getStringPlusProperty(sref.getProperty(EndpointListener.ENDPOINT_LISTENER_SCOPE)));
+ }
+
+ // copied from the DSW OSGiUtils class
+ public static String getUUID(BundleContext bc) {
+ synchronized ("org.osgi.framework.uuid") {
+ String uuid = bc.getProperty("org.osgi.framework.uuid");
+ if (uuid == null) {
+ uuid = UUID.randomUUID().toString();
+ System.setProperty("org.osgi.framework.uuid", uuid);
+ }
+ return uuid;
+ }
+ }
+
+ /**
+ * 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);
+ }
+ }
+
+ /**
+ * 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) {
+ Matcher m = OBJECTCLASS_PATTERN.matcher(scope);
+ return m.matches() ? m.group(1) : null;
+ }
+
+ /**
+ * Returns a service's properties as a map.
+ *
+ * @param serviceReference a service reference
+ * @return the service's properties as a map
+ */
+ public static Map<String, Object> getProperties(ServiceReference<?> serviceReference) {
+ String[] keys = serviceReference.getPropertyKeys();
+ Map<String, Object> props = new HashMap<String, Object>(keys.length);
+ for (String key : keys) {
+ Object val = serviceReference.getProperty(key);
+ props.put(key, val);
+ }
+ return props;
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/DiscoveryDriverTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/DiscoveryDriverTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/DiscoveryDriverTest.java
new file mode 100644
index 0000000..84470c2
--- /dev/null
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/DiscoveryDriverTest.java
@@ -0,0 +1,135 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper;
+
+import junit.framework.TestCase;
+
+public class DiscoveryDriverTest extends TestCase {
+
+ public void testDUMMY() {
+ assertTrue(true);
+ }
+
+// public void testDiscoveryDriver() throws Exception {
+// BundleContext bc = getDefaultBundleContext();
+// Dictionary<String, String> props = getDefaultProps();
+//
+// final StringBuilder sb = new StringBuilder();
+// DiscoveryDriver dd = new DiscoveryDriver(bc, props) {
+// @Override
+// ZooKeeper createZooKeeper() throws IOException {
+// sb.append(zkHost + ":" + zkPort);
+// ZooKeeper zk = EasyMock.createMock(ZooKeeper.class);
+// EasyMock.replay(zk);
+// return zk;
+// }
+// };
+// EasyMock.verify(bc);
+// assertEquals("somehost:1910", sb.toString());
+//
+// EasyMock.verify(dd.zooKeeper);
+// EasyMock.reset(dd.zooKeeper);
+// dd.zooKeeper.close();
+// EasyMock.expectLastCall();
+// EasyMock.replay(dd.zooKeeper);
+//
+// ServiceTracker st1 = EasyMock.createMock(ServiceTracker.class);
+// st1.close();
+// EasyMock.expectLastCall();
+// EasyMock.replay(st1);
+// ServiceTracker st2 = EasyMock.createMock(ServiceTracker.class);
+// st2.close();
+// EasyMock.expectLastCall();
+// EasyMock.replay(st2);
+//
+// dd.lookupTracker = st1;
+// dd.publicationTracker = st2;
+//
+// dd.destroy();
+// }
+//
+// private void expectServiceTrackerCalls(BundleContext bc, String objectClass)
+// throws InvalidSyntaxException {
+// Filter filter = EasyMock.createNiceMock(Filter.class);
+// EasyMock.replay(filter);
+//
+// EasyMock.expect(bc.createFilter("(objectClass=" + objectClass + ")"))
+// .andReturn(filter).anyTimes();
+// bc.addServiceListener((ServiceListener) EasyMock.anyObject(),
+// EasyMock.eq("(objectClass=" + objectClass + ")"));
+// EasyMock.expectLastCall().anyTimes();
+// EasyMock.expect(bc.getServiceReferences(objectClass, null))
+// .andReturn(new ServiceReference [0]).anyTimes();
+// }
+//
+// public void testProcessEvent() throws Exception {
+// DiscoveryDriver db = new DiscoveryDriver(getDefaultBundleContext(), getDefaultProps()) {
+// @Override
+// ZooKeeper createZooKeeper() throws IOException {
+// return null;
+// }
+// };
+//
+// FindInZooKeeperCustomizer fc = new FindInZooKeeperCustomizer(null, null);
+// List<InterfaceMonitor> l1 = new ArrayList<InterfaceMonitor>();
+// InterfaceMonitor dm1a = EasyMock.createMock(InterfaceMonitor.class);
+// dm1a.process();
+// EasyMock.expectLastCall();
+// EasyMock.replay(dm1a);
+// InterfaceMonitor dm1b = EasyMock.createMock(InterfaceMonitor.class);
+// dm1b.process();
+// EasyMock.expectLastCall();
+// EasyMock.replay(dm1b);
+// l1.add(dm1a);
+// l1.add(dm1b);
+//
+// List<InterfaceMonitor> l2 = new ArrayList<InterfaceMonitor>();
+// InterfaceMonitor dm2 = EasyMock.createMock(InterfaceMonitor.class);
+// dm2.process();
+// EasyMock.expectLastCall();
+// EasyMock.replay(dm2);
+// l2.add(dm2);
+//
+// fc.watchers.put(EasyMock.createMock(DiscoveredServiceTracker.class), l1);
+// fc.watchers.put(EasyMock.createMock(DiscoveredServiceTracker.class), l2);
+//
+// db.finderCustomizer = fc;
+// db.process(null);
+//
+// EasyMock.verify(dm1a);
+// EasyMock.verify(dm1b);
+// EasyMock.verify(dm2);
+// }
+//
+// private BundleContext getDefaultBundleContext() throws InvalidSyntaxException {
+// BundleContext bc = EasyMock.createMock(BundleContext.class);
+// expectServiceTrackerCalls(bc, ServicePublication.class.getName());
+// expectServiceTrackerCalls(bc, DiscoveredServiceTracker.class.getName());
+// EasyMock.replay(bc);
+// return bc;
+// }
+//
+// private Dictionary<String, String> getDefaultProps() {
+// Dictionary<String, String> props = new Hashtable<String, String>();
+// props.put("zookeeper.host", "somehost");
+// props.put("zookeeper.port", "1910");
+// props.put("zookeeper.timeout", "1500");
+// return props;
+// }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/FindInZooKeeperCustomizerTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/FindInZooKeeperCustomizerTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/FindInZooKeeperCustomizerTest.java
new file mode 100644
index 0000000..cb2180b
--- /dev/null
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/FindInZooKeeperCustomizerTest.java
@@ -0,0 +1,301 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper;
+
+import junit.framework.TestCase;
+
+public class FindInZooKeeperCustomizerTest extends TestCase {
+
+ public void testDUMMY() {
+ assertTrue(true);
+ }
+
+// public void testAddingServiceInterface() {
+// DiscoveredServiceTracker dst = new DiscoveredServiceTracker() {
+// public void serviceChanged(DiscoveredServiceNotification dsn) {}
+// };
+//
+// ServiceReference sr = EasyMock.createMock(ServiceReference.class);
+// EasyMock.expect(sr.getProperty(DiscoveredServiceTracker.INTERFACE_MATCH_CRITERIA))
+// .andReturn(Collections.singleton(String.class.getName()));
+// EasyMock.expect(sr.getProperty(DiscoveredServiceTracker.FILTER_MATCH_CRITERIA))
+// .andReturn(null);
+// EasyMock.replay(sr);
+//
+// DiscoveredServiceTracker dst2 = new DiscoveredServiceTracker() {
+// public void serviceChanged(DiscoveredServiceNotification dsn) {}
+// };
+//
+// ServiceReference sr2 = EasyMock.createMock(ServiceReference.class);
+// EasyMock.expect(sr2.getProperty(DiscoveredServiceTracker.INTERFACE_MATCH_CRITERIA))
+// .andReturn(Arrays.asList(Integer.class.getName(), Comparable.class.getName()));
+// EasyMock.expect(sr2.getProperty(DiscoveredServiceTracker.FILTER_MATCH_CRITERIA))
+// .andReturn(null);
+// EasyMock.replay(sr2);
+//
+// BundleContext bc = EasyMock.createMock(BundleContext.class);
+// EasyMock.expect(bc.getService(sr)).andReturn(dst);
+// EasyMock.expect(bc.getService(sr2)).andReturn(dst2);
+// EasyMock.replay(bc);
+//
+// ZooKeeper zk = EasyMock.createMock(ZooKeeper.class);
+// zkExpectExists(zk, String.class.getName());
+// zkExpectExists(zk, Integer.class.getName());
+// zkExpectExists(zk, Comparable.class.getName());
+// EasyMock.expectLastCall();
+// EasyMock.replay(zk);
+//
+// FindInZooKeeperCustomizer fc = new FindInZooKeeperCustomizer(bc, zk);
+//
+// // ---------------------------------------------------------------
+// // Test the addingService APIs
+// // ---------------------------------------------------------------
+//
+// assertEquals("Precondition failed", 0, fc.watchers.size());
+// fc.addingService(sr);
+// assertEquals(1, fc.watchers.size());
+//
+// DiscoveredServiceTracker key = fc.watchers.keySet().iterator().next();
+// assertSame(dst, key);
+// List<InterfaceMonitor> dmList = fc.watchers.get(key);
+// assertEquals(1, dmList.size());
+// InterfaceMonitor dm = dmList.iterator().next();
+// assertNotNull(dm.listener);
+// assertSame(zk, dm.zookeeper);
+// assertEquals(Utils.getZooKeeperPath(String.class.getName()), dm.znode);
+//
+// assertEquals("Precondition failed", 1, fc.watchers.size());
+// fc.addingService(sr2);
+// assertEquals(2, fc.watchers.size());
+//
+// assertTrue(fc.watchers.containsKey(dst));
+// assertTrue(fc.watchers.containsKey(dst2));
+// assertEquals(dmList, fc.watchers.get(dst));
+// List<InterfaceMonitor> dmList2 = fc.watchers.get(dst2);
+// assertEquals(2, dmList2.size());
+//
+// Set<String> actual = new HashSet<String>();
+// for (InterfaceMonitor im : dmList2) {
+// actual.add(im.znode);
+// }
+// Set<String> expected = new HashSet<String>(Arrays.asList(
+// Utils.getZooKeeperPath(Integer.class.getName()),
+// Utils.getZooKeeperPath(Comparable.class.getName())));
+// assertEquals(expected, actual);
+//
+// EasyMock.verify(zk);
+//
+// // ---------------------------------------------------------------
+// // Test the modifiedService APIs
+// // ---------------------------------------------------------------
+// EasyMock.reset(zk);
+// zkExpectExists(zk, List.class.getName());
+// EasyMock.replay(zk);
+//
+// EasyMock.reset(sr);
+// EasyMock.expect(sr.getProperty(DiscoveredServiceTracker.INTERFACE_MATCH_CRITERIA))
+// .andReturn(Collections.singleton(List.class.getName()));
+// EasyMock.expect(sr.getProperty(DiscoveredServiceTracker.FILTER_MATCH_CRITERIA))
+// .andReturn(null);
+// EasyMock.replay(sr);
+//
+// assertEquals("Precondition failed", 2, fc.watchers.size());
+// fc.modifiedService(sr, dst);
+// assertEquals("Precondition failed", 2, fc.watchers.size());
+//
+// assertTrue(fc.watchers.containsKey(dst));
+// assertTrue(fc.watchers.containsKey(dst2));
+// assertEquals(dmList2, fc.watchers.get(dst2));
+// List<InterfaceMonitor> dmList3 = fc.watchers.get(dst);
+// assertEquals(1, dmList3.size());
+// assertEquals(Utils.getZooKeeperPath(List.class.getName()), dmList3.iterator().next().znode);
+//
+// EasyMock.verify(zk);
+//
+// // ---------------------------------------------------------------
+// // Test the removedService APIs
+// // ---------------------------------------------------------------
+// EasyMock.reset(zk);
+// EasyMock.replay(zk);
+//
+// assertEquals("Precondition failed", 2, fc.watchers.size());
+// fc.removedService(sr2, dst2);
+// assertEquals("Precondition failed", 1, fc.watchers.size());
+//
+// assertEquals(dmList3, fc.watchers.get(dst));
+// assertNull(fc.watchers.get(dst2));
+//
+// EasyMock.verify(zk);
+// }
+//
+// public void testAddingServiceFilter() {
+// DiscoveredServiceTracker dst = new DiscoveredServiceTracker() {
+// public void serviceChanged(DiscoveredServiceNotification dsn) {}
+// };
+//
+// ServiceReference sr = EasyMock.createMock(ServiceReference.class);
+// EasyMock.expect(sr.getProperty(DiscoveredServiceTracker.INTERFACE_MATCH_CRITERIA))
+// .andReturn(null);
+// Set<String> stringFilter = Collections.singleton("(objectClass=java.lang.String)");
+// EasyMock.expect(sr.getProperty(DiscoveredServiceTracker.FILTER_MATCH_CRITERIA))
+// .andReturn(stringFilter);
+// EasyMock.replay(sr);
+//
+// DiscoveredServiceTracker dst2 = new DiscoveredServiceTracker() {
+// public void serviceChanged(DiscoveredServiceNotification dsn) {}
+// };
+//
+// ServiceReference sr2 = EasyMock.createMock(ServiceReference.class);
+// EasyMock.expect(sr2.getProperty(DiscoveredServiceTracker.INTERFACE_MATCH_CRITERIA))
+// .andReturn(null);
+// List<String> combinedFilter =
+// Arrays.asList("(objectClass=java.lang.Integer)", "(objectClass=java.lang.Comparable)");
+// EasyMock.expect(sr2.getProperty(DiscoveredServiceTracker.FILTER_MATCH_CRITERIA))
+// .andReturn(combinedFilter);
+// EasyMock.replay(sr2);
+//
+// BundleContext bc = EasyMock.createMock(BundleContext.class);
+// EasyMock.expect(bc.getService(sr)).andReturn(dst);
+// EasyMock.expect(bc.getService(sr2)).andReturn(dst2);
+// EasyMock.replay(bc);
+//
+// ZooKeeper zk = EasyMock.createMock(ZooKeeper.class);
+// zkExpectExists(zk, String.class.getName());
+// zkExpectExists(zk, Integer.class.getName());
+// zkExpectExists(zk, Comparable.class.getName());
+// EasyMock.expectLastCall();
+// EasyMock.replay(zk);
+//
+// FindInZooKeeperCustomizer fc = new FindInZooKeeperCustomizer(bc, zk);
+//
+// // ---------------------------------------------------------------
+// // Test the addingService APIs
+// // ---------------------------------------------------------------
+//
+// assertEquals("Precondition failed", 0, fc.watchers.size());
+// fc.addingService(sr);
+// assertEquals(1, fc.watchers.size());
+//
+// DiscoveredServiceTracker key = fc.watchers.keySet().iterator().next();
+// assertSame(dst, key);
+// List<InterfaceMonitor> dmList = fc.watchers.get(key);
+// assertEquals(1, dmList.size());
+// InterfaceMonitor dm = dmList.iterator().next();
+// assertNotNull(dm.listener);
+// assertSame(zk, dm.zookeeper);
+// assertEquals(Utils.getZooKeeperPath(String.class.getName()), dm.znode);
+//
+// assertEquals("Precondition failed", 1, fc.watchers.size());
+// fc.addingService(sr2);
+// assertEquals(2, fc.watchers.size());
+//
+// assertTrue(fc.watchers.containsKey(dst));
+// assertTrue(fc.watchers.containsKey(dst2));
+// assertEquals(dmList, fc.watchers.get(dst));
+// List<InterfaceMonitor> dmList2 = fc.watchers.get(dst2);
+// assertEquals(2, dmList2.size());
+// Set<String> actual = new HashSet<String>();
+// for (InterfaceMonitor im : dmList2) {
+// actual.add(im.znode);
+// }
+// Set<String> expected = new HashSet<String>(Arrays.asList(
+// Utils.getZooKeeperPath(Integer.class.getName()),
+// Utils.getZooKeeperPath(Comparable.class.getName())));
+// assertEquals(expected, actual);
+//
+// EasyMock.verify(zk);
+//
+// // ---------------------------------------------------------------
+// // Test the modifiedService APIs
+// // ---------------------------------------------------------------
+// EasyMock.reset(zk);
+// zkExpectExists(zk, List.class.getName());
+// EasyMock.replay(zk);
+//
+// EasyMock.reset(sr);
+// Set<String> listFilter = Collections.singleton("(objectClass=java.util.List)");
+// EasyMock.expect(sr.getProperty(DiscoveredServiceTracker.INTERFACE_MATCH_CRITERIA))
+// .andReturn(null);
+// EasyMock.expect(sr.getProperty(DiscoveredServiceTracker.FILTER_MATCH_CRITERIA))
+// .andReturn(listFilter);
+// EasyMock.replay(sr);
+//
+// assertEquals("Precondition failed", 2, fc.watchers.size());
+// fc.modifiedService(sr, dst);
+// assertEquals("Precondition failed", 2, fc.watchers.size());
+//
+// assertTrue(fc.watchers.containsKey(dst));
+// assertTrue(fc.watchers.containsKey(dst2));
+// assertEquals(dmList2, fc.watchers.get(dst2));
+// List<InterfaceMonitor> dmList3 = fc.watchers.get(dst);
+// assertEquals(1, dmList3.size());
+// assertEquals(Utils.getZooKeeperPath(List.class.getName()), dmList3.iterator().next().znode);
+//
+// EasyMock.verify(zk);
+//
+// // ---------------------------------------------------------------
+// // Test the removedService APIs
+// // ---------------------------------------------------------------
+// EasyMock.reset(zk);
+// EasyMock.replay(zk);
+//
+// assertEquals("Precondition failed", 2, fc.watchers.size());
+// fc.removedService(sr2, dst2);
+// assertEquals("Precondition failed", 1, fc.watchers.size());
+//
+// assertEquals(dmList3, fc.watchers.get(dst));
+// assertNull(fc.watchers.get(dst2));
+//
+// EasyMock.verify(zk);
+// }
+//
+// public void testGetInterfacesFromFilter() {
+// testGetInterfacesFromFilter("objectClass=org.apache_2.Some$FunnyClass",
+// "org.apache_2.Some$FunnyClass");
+// testGetInterfacesFromFilter("(&(a=b)(objectClass = org.acme.Q)",
+// "org.acme.Q");
+// testGetInterfacesFromFilter("(&(objectClassIdentifier=b)(objectClass = org.acme.Q)",
+// "org.acme.Q");
+// testGetInterfacesFromFilter("(|(OBJECTCLASS= X )(objectclass = Y)",
+// "X", "Y");
+// testGetInterfacesFromFilter(new String[] {"(objectClass=X)", "(objectClass=Y)"},
+// "X", "Y");
+// }
+//
+// private void testGetInterfacesFromFilter(String filter, String ... interfaces) {
+// testGetInterfacesFromFilter(new String[] {filter}, interfaces);
+// }
+//
+// private void testGetInterfacesFromFilter(String[] filters, String ... interfaces) {
+// FindInZooKeeperCustomizer.getInterfacesFromFilter(Arrays.asList(filters));
+// }
+//
+// private void zkExpectExists(ZooKeeper zk, String className) {
+// zk.exists(EasyMock.eq(Utils.getZooKeeperPath(className)),
+// (Watcher) EasyMock.anyObject(),
+// (StatCallback) EasyMock.anyObject(), EasyMock.isNull());
+// EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+// public Object answer() throws Throwable {
+// assertEquals(EasyMock.getCurrentArguments()[1],
+// EasyMock.getCurrentArguments()[2]);
+// return null;
+// }
+// });
+// }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/InterfaceDataMonitorListenerImplTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/InterfaceDataMonitorListenerImplTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/InterfaceDataMonitorListenerImplTest.java
new file mode 100644
index 0000000..53b6139
--- /dev/null
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/InterfaceDataMonitorListenerImplTest.java
@@ -0,0 +1,183 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper;
+
+import junit.framework.TestCase;
+
+public class InterfaceDataMonitorListenerImplTest extends TestCase {
+
+ public void testDUMMY() {
+ assertTrue(true);
+ }
+
+// public void testChange() throws Exception {
+// final List<DiscoveredServiceNotification> dsnCallbacks = new ArrayList<DiscoveredServiceNotification>();
+// DiscoveredServiceTracker dst = new DiscoveredServiceTracker() {
+// public void serviceChanged(DiscoveredServiceNotification dsn) {
+// dsnCallbacks.add(dsn);
+// }
+// };
+//
+// //----------------------------------------------------------------
+// // Test DiscoveredServiceNotification.AVAILABLE
+// //----------------------------------------------------------------
+// Properties initial = new Properties();
+// initial.put("a", "b");
+// initial.put(ServicePublication.ENDPOINT_LOCATION, "http://somehost:12345/some/context");
+// ByteArrayOutputStream propBytes = new ByteArrayOutputStream();
+// initial.store(propBytes, "");
+//
+// ZooKeeper zk = EasyMock.createMock(ZooKeeper.class);
+// EasyMock.expect(zk.getChildren(Utils.getZooKeeperPath(String.class.getName()), false))
+// .andReturn(Arrays.asList("x#y#z"));
+// EasyMock.expect(zk.getData(Utils.getZooKeeperPath(String.class.getName()) + "/x#y#z", false, null))
+// .andReturn(propBytes.toByteArray());
+// EasyMock.replay(zk);
+//
+// InterfaceDataMonitorListenerImpl dml = new InterfaceDataMonitorListenerImpl(zk, String.class.getName(), dst);
+//
+// assertEquals("Precondition failed", 0, dsnCallbacks.size());
+// dml.change();
+// assertEquals(1, dsnCallbacks.size());
+// DiscoveredServiceNotification dsn = dsnCallbacks.iterator().next();
+// assertEquals(Collections.singleton(String.class.getName()), dsn.getInterfaces());
+// assertEquals(DiscoveredServiceNotification.AVAILABLE, dsn.getType());
+// assertEquals(0, dsn.getFilters().size());
+// ServiceEndpointDescription sed = dsn.getServiceEndpointDescription();
+// assertEquals(Collections.singleton(String.class.getName()), sed.getProvidedInterfaces());
+//
+// Properties expected = new Properties();
+// expected.load(new ByteArrayInputStream(propBytes.toByteArray()));
+// expected.put("service.exported.configs", "org.apache.cxf.ws");
+// expected.put("org.apache.cxf.ws.address", "http://somehost:12345/some/context");
+//
+// assertEquals(expected, sed.getProperties());
+// EasyMock.verify(zk);
+//
+// // Again with the same data
+// EasyMock.reset(zk);
+// EasyMock.expect(zk.getChildren(Utils.getZooKeeperPath(String.class.getName()), false))
+// .andReturn(Arrays.asList("x#y#z"));
+// EasyMock.expect(zk.getData(Utils.getZooKeeperPath(String.class.getName()) + "/x#y#z", false, null))
+// .andReturn(propBytes.toByteArray());
+// EasyMock.replay(zk);
+//
+// dsnCallbacks.clear();
+// assertEquals("Precondition failed", 0, dsnCallbacks.size());
+// dml.change();
+// assertEquals(0, dsnCallbacks.size());
+//
+// EasyMock.verify(zk);
+// //----------------------------------------------------------------
+// // Test DiscoveredServiceNotification.MODIFIED
+// //----------------------------------------------------------------
+// Properties modified = new Properties();
+// modified.put("c", "d");
+// modified.put(ServicePublication.ENDPOINT_LOCATION, "http://somehost:999/some/context");
+// modified.put("service.exported.configs", "org.apache.cxf.rs");
+// ByteArrayOutputStream modBytes = new ByteArrayOutputStream();
+// modified.store(modBytes, "");
+//
+// EasyMock.reset(zk);
+// EasyMock.expect(zk.getChildren(Utils.getZooKeeperPath(String.class.getName()), false))
+// .andReturn(Arrays.asList("x#y#z"));
+// EasyMock.expect(zk.getData(Utils.getZooKeeperPath(String.class.getName()) + "/x#y#z", false, null))
+// .andReturn(modBytes.toByteArray());
+// EasyMock.replay(zk);
+//
+// dsnCallbacks.clear();
+// assertEquals("Precondition failed", 0, dsnCallbacks.size());
+// dml.change();
+// assertEquals(1, dsnCallbacks.size());
+// DiscoveredServiceNotification dsn2 = dsnCallbacks.iterator().next();
+// assertEquals(Collections.singleton(String.class.getName()), dsn2.getInterfaces());
+// assertEquals(DiscoveredServiceNotification.MODIFIED, dsn2.getType());
+// assertEquals(0, dsn2.getFilters().size());
+// ServiceEndpointDescription sed2 = dsn2.getServiceEndpointDescription();
+// assertEquals(Collections.singleton(String.class.getName()), sed2.getProvidedInterfaces());
+// assertEquals(modified, sed2.getProperties());
+//
+// EasyMock.verify(zk);
+//
+// //----------------------------------------------------------------
+// // Test DiscoveredServiceNotification.MODIFIED2
+// //----------------------------------------------------------------
+// Properties modified2 = new Properties();
+// modified2.put("c", "d2");
+// modified2.put(ServicePublication.ENDPOINT_LOCATION, "http://somehost:112/some/context");
+// modified2.put("service.exported.configs", "org.apache.cxf.ws");
+// modified2.put("org.apache.cxf.ws.address", "http://somewhereelse/123");
+// ByteArrayOutputStream modBytes2 = new ByteArrayOutputStream();
+// modified2.store(modBytes2, "");
+//
+// EasyMock.reset(zk);
+// EasyMock.expect(zk.getChildren(Utils.getZooKeeperPath(String.class.getName()), false))
+// .andReturn(Arrays.asList("x#y#z"));
+// EasyMock.expect(zk.getData(Utils.getZooKeeperPath(String.class.getName()) + "/x#y#z", false, null))
+// .andReturn(modBytes2.toByteArray());
+// EasyMock.replay(zk);
+//
+// dsnCallbacks.clear();
+// assertEquals("Precondition failed", 0, dsnCallbacks.size());
+// dml.change();
+// assertEquals(1, dsnCallbacks.size());
+// DiscoveredServiceNotification dsn3 = dsnCallbacks.iterator().next();
+// assertEquals(Collections.singleton(String.class.getName()), dsn3.getInterfaces());
+// assertEquals(DiscoveredServiceNotification.MODIFIED, dsn3.getType());
+// assertEquals(0, dsn3.getFilters().size());
+// ServiceEndpointDescription sed3 = dsn3.getServiceEndpointDescription();
+// assertEquals(Collections.singleton(String.class.getName()), sed3.getProvidedInterfaces());
+// assertEquals(modified2, sed3.getProperties());
+//
+// EasyMock.verify(zk);
+// //----------------------------------------------------------------
+// // Test DiscoveredServiceNotification.UNAVAILABLE
+// //----------------------------------------------------------------
+// EasyMock.reset(zk);
+// EasyMock.expect(zk.getChildren(Utils.getZooKeeperPath(String.class.getName()), false))
+// .andReturn(Collections.<String>emptyList());
+// EasyMock.replay(zk);
+//
+// dsnCallbacks.clear();
+// assertEquals("Precondition failed", 0, dsnCallbacks.size());
+// dml.change();
+// assertEquals(1, dsnCallbacks.size());
+// DiscoveredServiceNotification dsn4 = dsnCallbacks.iterator().next();
+// assertEquals(Collections.singleton(String.class.getName()), dsn4.getInterfaces());
+// assertEquals(DiscoveredServiceNotification.UNAVAILABLE, dsn4.getType());
+// assertEquals(0, dsn4.getFilters().size());
+// ServiceEndpointDescription sed4 = dsn4.getServiceEndpointDescription();
+// assertEquals(Collections.singleton(String.class.getName()), sed4.getProvidedInterfaces());
+// assertEquals(modified2, sed4.getProperties());
+//
+// EasyMock.verify(zk);
+//
+// // Try the same again...
+// EasyMock.reset(zk);
+// EasyMock.expect(zk.getChildren(Utils.getZooKeeperPath(String.class.getName()), false))
+// .andReturn(Collections.<String>emptyList());
+// EasyMock.replay(zk);
+//
+// dsnCallbacks.clear();
+// assertEquals("Precondition failed", 0, dsnCallbacks.size());
+// dml.change();
+// assertEquals("Should not receive a callback again...", 0, dsnCallbacks.size());
+// EasyMock.verify(zk);
+// }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java
new file mode 100644
index 0000000..e63b805
--- /dev/null
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper.publish;
+
+import java.util.Dictionary;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.zookeeper.ZooKeeper;
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+
+public class PublishingEndpointListenerFactoryTest extends TestCase {
+
+ @SuppressWarnings("unchecked")
+ public void testScope() {
+ IMocksControl c = EasyMock.createNiceControl();
+
+ BundleContext ctx = c.createMock(BundleContext.class);
+ ZooKeeper zk = c.createMock(ZooKeeper.class);
+ @SuppressWarnings("rawtypes")
+ ServiceRegistration sreg = c.createMock(ServiceRegistration.class);
+
+ PublishingEndpointListenerFactory eplf = new PublishingEndpointListenerFactory(zk, ctx);
+
+ EasyMock.expect(ctx.registerService(EasyMock.eq(EndpointListener.class.getName()), EasyMock.eq(eplf),
+ (Dictionary<String, String>)EasyMock.anyObject())).andReturn(sreg).once();
+
+ EasyMock.expect(ctx.getProperty(EasyMock.eq("org.osgi.framework.uuid"))).andReturn("myUUID").anyTimes();
+
+ c.replay();
+ eplf.start();
+ c.verify();
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testServiceFactory() {
+ IMocksControl c = EasyMock.createNiceControl();
+
+ BundleContext ctx = c.createMock(BundleContext.class);
+ ZooKeeper zk = c.createMock(ZooKeeper.class);
+ @SuppressWarnings("rawtypes")
+ ServiceRegistration sreg = c.createMock(ServiceRegistration.class);
+
+ PublishingEndpointListenerFactory eplf = new PublishingEndpointListenerFactory(zk, ctx);
+
+ EasyMock.expect(ctx.registerService(EasyMock.eq(EndpointListener.class.getName()), EasyMock.eq(eplf),
+ (Dictionary<String, String>)EasyMock.anyObject())).andReturn(sreg).once();
+
+ EasyMock.expect(ctx.getProperty(EasyMock.eq("org.osgi.framework.uuid"))).andReturn("myUUID").anyTimes();
+
+ PublishingEndpointListener eli = c.createMock(PublishingEndpointListener.class);
+ eli.close();
+ EasyMock.expectLastCall().once();
+
+ c.replay();
+ eplf.start();
+
+ PublishingEndpointListener service = eplf.getService(null, null);
+ assertNotNull(service);
+ assertTrue(service instanceof EndpointListener);
+
+ List<PublishingEndpointListener> listeners = eplf.getListeners();
+ assertEquals(1, listeners.size());
+ assertEquals(service, listeners.get(0));
+
+ eplf.ungetService(null, null, service);
+ listeners = eplf.getListeners();
+ assertEquals(0, listeners.size());
+
+ eplf.ungetService(null, null, eli); // no call to close
+ listeners.add(eli);
+ eplf.ungetService(null, null, eli); // call to close
+ listeners = eplf.getListeners();
+ assertEquals(0, listeners.size());
+
+ c.verify();
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java
new file mode 100644
index 0000000..aa1b68e
--- /dev/null
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java
@@ -0,0 +1,201 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper.publish;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.cxf.dosgi.endpointdesc.EndpointDescriptionParser;
+import org.apache.cxf.dosgi.endpointdesc.PropertiesMapper;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.easymock.IAnswer;
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+import org.osgi.xmlns.rsa.v1_0.EndpointDescriptionType;
+import org.osgi.xmlns.rsa.v1_0.PropertyType;
+
+public class PublishingEndpointListenerTest extends TestCase {
+
+ public void testEndpointRemovalAdding() throws KeeperException, InterruptedException {
+ IMocksControl c = EasyMock.createNiceControl();
+
+ BundleContext ctx = c.createMock(BundleContext.class);
+ ZooKeeper zk = c.createMock(ZooKeeper.class);
+
+ String path = "/osgi/service_registry/myClass/google.de#80##test";
+ EasyMock.expect(zk.create(EasyMock.eq(path),
+ (byte[])EasyMock.anyObject(), EasyMock.eq(Ids.OPEN_ACL_UNSAFE),
+ EasyMock.eq(CreateMode.EPHEMERAL))).andReturn("").once();
+
+ zk.delete(EasyMock.eq("/osgi/service_registry/myClass/google.de#80##test"), EasyMock.eq(-1));
+ EasyMock.expectLastCall().once();
+
+ c.replay();
+
+ PublishingEndpointListener eli = new PublishingEndpointListener(zk, ctx);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(Constants.OBJECTCLASS, new String[] {
+ "myClass"
+ });
+ props.put(RemoteConstants.ENDPOINT_ID, "http://google.de:80/test");
+ props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "myConfig");
+
+ EndpointDescription endpoint = new EndpointDescription(props);
+
+ eli.endpointAdded(endpoint, null);
+ eli.endpointAdded(endpoint, null); // should do nothing
+
+ eli.endpointRemoved(endpoint, null);
+ eli.endpointRemoved(endpoint, null); // should do nothing
+
+ c.verify();
+ }
+
+ public void testDiscoveryPlugin() throws Exception {
+ DiscoveryPlugin plugin1 = new DiscoveryPlugin() {
+ public String process(Map<String, Object> mutableProperties, String endpointKey) {
+ String eid = (String) mutableProperties.get("endpoint.id");
+ mutableProperties.put("endpoint.id", eid + "/appended");
+ return endpointKey;
+ }
+ };
+ @SuppressWarnings("unchecked")
+ ServiceReference<DiscoveryPlugin> sr1 = EasyMock.createMock(ServiceReference.class);
+
+ DiscoveryPlugin plugin2 = new DiscoveryPlugin() {
+ public String process(Map<String, Object> mutableProperties, String endpointKey) {
+ mutableProperties.put("foo", "bar");
+ return endpointKey.replaceAll("localhost", "some.machine");
+ }
+ };
+ @SuppressWarnings("unchecked")
+ ServiceReference<DiscoveryPlugin> sr2 = EasyMock.createMock(ServiceReference.class);
+
+ BundleContext ctx = EasyMock.createMock(BundleContext.class);
+ EasyMock.expect(ctx.createFilter(EasyMock.isA(String.class))).andAnswer(new IAnswer<Filter>() {
+ public Filter answer() throws Throwable {
+ return FrameworkUtil.createFilter((String) EasyMock.getCurrentArguments()[0]);
+ }
+ }).anyTimes();
+ ctx.addServiceListener(EasyMock.isA(ServiceListener.class),
+ EasyMock.eq("(objectClass=" + DiscoveryPlugin.class.getName() + ")"));
+ EasyMock.expect(ctx.getService(sr1)).andReturn(plugin1).anyTimes();
+ EasyMock.expect(ctx.getService(sr2)).andReturn(plugin2).anyTimes();
+ EasyMock.expect(ctx.getServiceReferences(DiscoveryPlugin.class.getName(), null))
+ .andReturn(new ServiceReference[]{sr1, sr2}).anyTimes();
+ EasyMock.replay(ctx);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(Constants.OBJECTCLASS, new String[] {"org.foo.myClass"});
+ props.put(RemoteConstants.ENDPOINT_ID, "http://localhost:9876/test");
+ props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "myConfig");
+ EndpointDescription endpoint = new EndpointDescription(props);
+
+ Map<String, Object> expectedProps = new HashMap<String, Object>(props);
+ expectedProps.put("endpoint.id", "http://localhost:9876/test/appended");
+ expectedProps.put("foo", "bar");
+ expectedProps.put("service.imported", "true");
+
+ final ZooKeeper zk = EasyMock.createNiceMock(ZooKeeper.class);
+ String expectedFullPath = "/osgi/service_registry/org/foo/myClass/some.machine#9876##test";
+
+ List<PropertyType> props2 = new PropertiesMapper().fromProps(expectedProps);
+ EndpointDescriptionType epd = new EndpointDescriptionType();
+ epd.getProperty().addAll(props2);
+ byte[] data = new EndpointDescriptionParser().getData(epd);
+ EasyMock.expect(zk.create(
+ EasyMock.eq(expectedFullPath),
+ EasyMock.aryEq(data),
+ EasyMock.eq(Ids.OPEN_ACL_UNSAFE),
+ EasyMock.eq(CreateMode.EPHEMERAL))).andReturn("");
+ EasyMock.replay(zk);
+
+ PublishingEndpointListener eli = new PublishingEndpointListener(zk, ctx);
+
+ List<EndpointDescription> endpoints = getEndpoints(eli);
+ assertEquals("Precondition", 0, endpoints.size());
+ eli.endpointAdded(endpoint, null);
+ assertEquals(1, endpoints.size());
+
+ //TODO enable
+ //EasyMock.verify(zk);
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<EndpointDescription> getEndpoints(PublishingEndpointListener eli) throws Exception {
+ Field field = eli.getClass().getDeclaredField("endpoints");
+ field.setAccessible(true);
+ return (List<EndpointDescription>) field.get(eli);
+ }
+
+ public void testClose() throws KeeperException, InterruptedException {
+ IMocksControl c = EasyMock.createNiceControl();
+
+ BundleContext ctx = c.createMock(BundleContext.class);
+ ZooKeeper zk = c.createMock(ZooKeeper.class);
+
+ String path = "/osgi/service_registry/myClass/google.de#80##test";
+ EasyMock.expect(zk.create(EasyMock.eq(path),
+ (byte[])EasyMock.anyObject(), EasyMock.eq(Ids.OPEN_ACL_UNSAFE),
+ EasyMock.eq(CreateMode.EPHEMERAL))).andReturn("").once();
+
+ zk.delete(EasyMock.eq("/osgi/service_registry/myClass/google.de#80##test"), EasyMock.eq(-1));
+ EasyMock.expectLastCall().once();
+
+ c.replay();
+
+ PublishingEndpointListener eli = new PublishingEndpointListener(zk, ctx);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(Constants.OBJECTCLASS, new String[] {
+ "myClass"
+ });
+ props.put(RemoteConstants.ENDPOINT_ID, "http://google.de:80/test");
+ props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "myConfig");
+
+ EndpointDescription endpoint = new EndpointDescription(props);
+
+ eli.endpointAdded(endpoint, null);
+
+ eli.close(); // should result in zk.delete(...)
+
+ c.verify();
+ }
+
+ public void testGetKey() throws Exception {
+ assertEquals("somehost#9090##org#example#TestEndpoint",
+ PublishingEndpointListener.getKey("http://somehost:9090/org/example/TestEndpoint"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
new file mode 100644
index 0000000..7d6f67f
--- /dev/null
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
@@ -0,0 +1,139 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper.subscribe;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.zookeeper.ZooKeeper;
+import org.easymock.IAnswer;
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+
+import static org.junit.Assert.assertEquals;
+
+public class InterfaceMonitorManagerTest {
+
+ @Test
+ public void testEndpointListenerTrackerCustomizer() {
+ IMocksControl c = EasyMock.createNiceControl();
+
+ BundleContext ctx = c.createMock(BundleContext.class);
+ ZooKeeper zk = c.createMock(ZooKeeper.class);
+
+ @SuppressWarnings("unchecked")
+ ServiceReference<EndpointListener> sref = c.createMock(ServiceReference.class);
+ @SuppressWarnings("unchecked")
+ ServiceReference<EndpointListener> sref2 = c.createMock(ServiceReference.class);
+
+ final Map<String, ?> p = new HashMap<String, Object>();
+
+ EasyMock.expect(sref.getPropertyKeys()).andAnswer(new IAnswer<String[]>() {
+ public String[] answer() throws Throwable {
+ return p.keySet().toArray(new String[p.size()]);
+ }
+ }).anyTimes();
+
+ EasyMock.expect(sref.getProperty((String)EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ String key = (String)(EasyMock.getCurrentArguments()[0]);
+ return p.get(key);
+ }
+ }).anyTimes();
+
+ EasyMock.expect(sref2.getPropertyKeys()).andAnswer(new IAnswer<String[]>() {
+ public String[] answer() throws Throwable {
+ return p.keySet().toArray(new String[p.size()]);
+ }
+ }).anyTimes();
+
+ EasyMock.expect(sref2.getProperty((String)EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ String key = (String)(EasyMock.getCurrentArguments()[0]);
+ return p.get(key);
+ }
+ }).anyTimes();
+
+ final List<IMocksControl> controls = new ArrayList<IMocksControl>();
+
+ InterfaceMonitorManager eltc = new InterfaceMonitorManager(ctx, zk);
+
+ c.replay();
+
+ // sref has no scope -> nothing should happen
+
+ assertEquals(0, eltc.getEndpointListenerScopes().size());
+ assertEquals(0, eltc.getInterests().size());
+
+ //p.put(EndpointListener.ENDPOINT_LISTENER_SCOPE, );
+
+ eltc.addInterest(sref, "(objectClass=mine)", "mine");
+
+ assertEquals(1, eltc.getEndpointListenerScopes().size());
+ assertEquals(1, eltc.getEndpointListenerScopes().get(sref).size());
+ assertEquals("(objectClass=mine)", eltc.getEndpointListenerScopes().get(sref).get(0));
+ assertEquals(1, eltc.getInterests().size());
+
+ eltc.addInterest(sref, "(objectClass=mine)", "mine");
+
+ assertEquals(1, eltc.getEndpointListenerScopes().size());
+ assertEquals(1, eltc.getEndpointListenerScopes().get(sref).size());
+ assertEquals("(objectClass=mine)", eltc.getEndpointListenerScopes().get(sref).get(0));
+ assertEquals(1, eltc.getInterests().size());
+
+ eltc.addInterest(sref2, "(objectClass=mine)", "mine");
+
+ assertEquals(2, eltc.getEndpointListenerScopes().size());
+ assertEquals(1, eltc.getEndpointListenerScopes().get(sref).size());
+ assertEquals(1, eltc.getEndpointListenerScopes().get(sref2).size());
+ assertEquals("(objectClass=mine)", eltc.getEndpointListenerScopes().get(sref).get(0));
+ assertEquals("(objectClass=mine)", eltc.getEndpointListenerScopes().get(sref2).get(0));
+ assertEquals(1, eltc.getInterests().size());
+
+ eltc.removeInterest(sref);
+
+ assertEquals(1, eltc.getEndpointListenerScopes().size());
+ assertEquals(1, eltc.getEndpointListenerScopes().get(sref2).size());
+ assertEquals("(objectClass=mine)", eltc.getEndpointListenerScopes().get(sref2).get(0));
+ assertEquals(1, eltc.getInterests().size());
+
+ eltc.removeInterest(sref);
+
+ assertEquals(1, eltc.getEndpointListenerScopes().size());
+ assertEquals(1, eltc.getEndpointListenerScopes().get(sref2).size());
+ assertEquals("(objectClass=mine)", eltc.getEndpointListenerScopes().get(sref2).get(0));
+ assertEquals(1, eltc.getInterests().size());
+
+ eltc.removeInterest(sref2);
+
+ assertEquals(0, eltc.getEndpointListenerScopes().size());
+ assertEquals(0, eltc.getInterests().size());
+
+ c.verify();
+ for (IMocksControl control : controls) {
+ control.verify();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
new file mode 100644
index 0000000..67afb16
--- /dev/null
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper.subscribe;
+
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+import org.apache.cxf.dosgi.discovery.zookeeper.util.Utils;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+
+public class InterfaceMonitorTest extends TestCase {
+
+ public void testInterfaceMonitor() throws KeeperException, InterruptedException {
+ IMocksControl c = EasyMock.createControl();
+
+ ZooKeeper zk = c.createMock(ZooKeeper.class);
+ expect(zk.getState()).andReturn(ZooKeeper.States.CONNECTED).anyTimes();
+
+ String scope = "(myProp=test)";
+ String interf = "es.schaaf.test";
+ String node = Utils.getZooKeeperPath(interf);
+
+ EndpointListener endpointListener = c.createMock(EndpointListener.class);
+ InterfaceMonitor im = new InterfaceMonitor(zk, interf, endpointListener, scope);
+ zk.exists(eq(node), eq(im), eq(im), EasyMock.anyObject());
+ EasyMock.expectLastCall().once();
+
+ expect(zk.exists(eq(node), eq(false))).andReturn(new Stat()).anyTimes();
+ expect(zk.getChildren(eq(node), eq(false))).andReturn(Collections.<String> emptyList()).once();
+ expect(zk.getChildren(eq(node), eq(im))).andReturn(Collections.<String> emptyList()).once();
+
+ c.replay();
+ im.start();
+ // simulate a zk callback
+ WatchedEvent we = new WatchedEvent(EventType.NodeCreated, KeeperState.SyncConnected, node);
+ im.process(we);
+ c.verify();
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d73a3a7f/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java
new file mode 100644
index 0000000..08c830c
--- /dev/null
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java
@@ -0,0 +1,110 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.dosgi.discovery.zookeeper.util;
+
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+
+public class UtilsTest extends TestCase {
+
+ public void testGetZooKeeperPath() {
+ assertEquals(Utils.PATH_PREFIX + '/' + "org/example/Test",
+ Utils.getZooKeeperPath("org.example.Test"));
+
+ // used for the recursive discovery
+ assertEquals(Utils.PATH_PREFIX, Utils.getZooKeeperPath(null));
+ assertEquals(Utils.PATH_PREFIX, Utils.getZooKeeperPath(""));
+ }
+
+ public void testGetStringPlusProperty() {
+ String[] out = Utils.getStringPlusProperty("MyString");
+ assertEquals(1, out.length);
+ assertEquals("MyString", out[0]);
+
+ out = Utils.getStringPlusProperty(new String[]{"MyString"});
+ assertEquals(1, out.length);
+ assertEquals("MyString", out[0]);
+
+ out = Utils.getStringPlusProperty(Arrays.asList("MyString"));
+ assertEquals(1, out.length);
+ assertEquals("MyString", out[0]);
+
+ out = Utils.getStringPlusProperty(Arrays.asList(1));
+ assertEquals(0, out.length);
+
+ out = Utils.getStringPlusProperty(new Object());
+ assertEquals(0, out.length);
+
+ out = Utils.getStringPlusProperty(null);
+ assertEquals(0, out.length);
+ }
+
+ public void testRemoveEmpty() {
+ String[] out = Utils.removeEmpty(new String[0]);
+ assertEquals(0, out.length);
+
+ out = Utils.removeEmpty(new String[]{null});
+ assertEquals(0, out.length);
+
+ out = Utils.removeEmpty(new String[]{""});
+ assertEquals(0, out.length);
+
+ out = Utils.removeEmpty(new String[]{"hi"});
+ assertEquals(1, out.length);
+ assertEquals("hi", out[0]);
+
+ out = Utils.removeEmpty(new String[]{"", "hi", null});
+ assertEquals(1, out.length);
+ assertEquals("hi", out[0]);
+
+ out = Utils.removeEmpty(new String[]{"hi", null, "", ""});
+ assertEquals(1, out.length);
+ assertEquals("hi", out[0]);
+
+ out = Utils.removeEmpty(new String[]{"", "hi", null, "", "", "bye", null});
+ assertEquals(2, out.length);
+ assertEquals("hi", out[0]);
+ assertEquals("bye", out[1]);
+ }
+
+ public void testGetScopes() {
+ IMocksControl c = EasyMock.createNiceControl();
+
+ String[] scopes = new String[]{"myScope=test", ""};
+
+ @SuppressWarnings("unchecked")
+ ServiceReference<EndpointListener> sref = c.createMock(ServiceReference.class);
+ EasyMock.expect(sref.getProperty(EasyMock.eq(EndpointListener.ENDPOINT_LISTENER_SCOPE)))
+ .andReturn(scopes).anyTimes();
+
+ c.replay();
+
+ String[] ret = Utils.getScopes(sref);
+
+ c.verify();
+ assertEquals(1, ret.length);
+ assertEquals(scopes[0], ret[0]);
+ }
+}