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]); + } +}
