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:42 UTC
[43/50] [abbrv] aries-rsa git commit: Switching to aries package names
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/EndpointRepository.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/EndpointRepository.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/EndpointRepository.java
deleted file mode 100644
index 2a7bab3..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/EndpointRepository.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * 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.topologymanager.exporter;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Holds all endpoints that are exported by a TopologyManager. For each ServiceReference that is exported a
- * map is maintained which contains information on the endpoints for each RemoteAdminService that created the
- * endpoints.
- */
-@SuppressWarnings("rawtypes")
-public class EndpointRepository {
-
- private static final Logger LOG = LoggerFactory.getLogger(EndpointRepository.class);
-
- private final Map<ServiceReference, Map<RemoteServiceAdmin, Collection<EndpointDescription>>> exportedServices
- = new LinkedHashMap<ServiceReference, Map<RemoteServiceAdmin, Collection<EndpointDescription>>>();
-
- private EndpointListener notifier;
-
- public void setNotifier(EndpointListener notifier) {
- this.notifier = notifier;
- }
-
-
- /**
- * Remove all services exported by the given rsa.
- *
- * @param rsa the RemoteServiceAdmin to remove
- * @return list of removed endpoints
- */
- public synchronized List<EndpointDescription> removeRemoteServiceAdmin(RemoteServiceAdmin rsa) {
- LOG.debug("RemoteServiceAdmin removed: {}", rsa.getClass().getName());
- List<EndpointDescription> removedEndpoints = new ArrayList<EndpointDescription>();
- for (Map<RemoteServiceAdmin, Collection<EndpointDescription>> exports : exportedServices.values()) {
- Collection<EndpointDescription> endpoints = exports.get(rsa);
- if (endpoints != null) {
- removedEndpoints.addAll(endpoints);
- exports.remove(rsa);
- }
- }
- endpointsRemoved(removedEndpoints);
- return removedEndpoints;
- }
-
- public synchronized void removeService(ServiceReference sref) {
- List<EndpointDescription> removedEndpoints = new ArrayList<EndpointDescription>();
- Map<RemoteServiceAdmin, Collection<EndpointDescription>> rsaToEndpoints = exportedServices.get(sref);
- if (rsaToEndpoints != null) {
- for (Collection<EndpointDescription> endpoints : rsaToEndpoints.values()) {
- removedEndpoints.addAll(endpoints);
- }
- exportedServices.remove(sref);
- }
- endpointsRemoved(removedEndpoints);
- }
-
- public synchronized void addService(ServiceReference sref) {
- if (!exportedServices.containsKey(sref)) {
- LOG.info("Marking service from bundle {} for export", sref.getBundle().getSymbolicName());
- exportedServices.put(sref, new LinkedHashMap<RemoteServiceAdmin, Collection<EndpointDescription>>());
- }
- }
-
- public synchronized void addEndpoints(ServiceReference sref, RemoteServiceAdmin rsa,
- List<EndpointDescription> endpoints) {
- addService(sref);
- Map<RemoteServiceAdmin, Collection<EndpointDescription>> exports = exportedServices.get(sref);
- exports.put(rsa, endpoints);
- endpointsAdded(endpoints);
- }
-
- synchronized boolean isAlreadyExportedForRsa(ServiceReference sref, RemoteServiceAdmin rsa) {
- Map<RemoteServiceAdmin, Collection<EndpointDescription>> exports = exportedServices.get(sref);
- return exports != null && exports.containsKey(rsa);
- }
-
- public synchronized Collection<EndpointDescription> getAllEndpoints() {
- List<EndpointDescription> allEndpoints = new ArrayList<EndpointDescription>();
- for (Map<RemoteServiceAdmin, Collection<EndpointDescription>> exports : exportedServices.values()) {
- for (Collection<EndpointDescription> endpoints : exports.values()) {
- allEndpoints.addAll(endpoints);
- }
- }
- return allEndpoints;
- }
-
- public synchronized Set<ServiceReference> getServicesToBeExportedFor(RemoteServiceAdmin rsa) {
- Set<ServiceReference> servicesToBeExported = new HashSet<ServiceReference>();
- for (Map.Entry<ServiceReference, Map<RemoteServiceAdmin, Collection<EndpointDescription>>> entry
- : exportedServices.entrySet()) {
- if (!entry.getValue().containsKey(rsa)) {
- servicesToBeExported.add(entry.getKey());
- }
- }
- return servicesToBeExported;
- }
-
- private void endpointsAdded(List<EndpointDescription> endpoints) {
- for (EndpointDescription epd : endpoints) {
- notifier.endpointAdded(epd, null);
- }
- }
-
- private void endpointsRemoved(List<EndpointDescription> endpoints) {
- for (EndpointDescription epd : endpoints) {
- notifier.endpointRemoved(epd, null);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/StringPlus.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/StringPlus.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/StringPlus.java
deleted file mode 100644
index 1198154..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/StringPlus.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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.topologymanager.exporter;
-
-import java.util.Collection;
-
-public final class StringPlus {
-
- private StringPlus() {
- }
-
- /**
- * 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[] parse(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];
- }
-
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java
deleted file mode 100644
index ad3736c..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * 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.topologymanager.exporter;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-import org.apache.cxf.dosgi.dsw.api.ExportPolicy;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.ExportReference;
-import org.osgi.service.remoteserviceadmin.ExportRegistration;
-import org.osgi.service.remoteserviceadmin.RemoteConstants;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Manages exported endpoints of DOSGi services and notifies EndpointListeners of changes.
- *
- * <li> Tracks local RemoteServiceAdmin instances by using a ServiceTracker
- * <li> Uses a ServiceListener to track local OSGi services
- * <li> When a service is published that is supported by DOSGi the
- * known RemoteServiceAdmins are instructed to export the service and
- * the EndpointListeners are notified
- * <li> When a service is unpublished the EndpointListeners are notified.
- * The endpoints are not closed as the ExportRegistration takes care of this
- */
-public class TopologyManagerExport implements ServiceListener {
- private static final Logger LOG = LoggerFactory.getLogger(TopologyManagerExport.class);
-
- private final Executor execService;
- private final EndpointRepository endpointRepo;
- private ExportPolicy policy;
- private final Set<RemoteServiceAdmin> rsaSet;
-
-
- public TopologyManagerExport(final EndpointRepository endpointRepo, Executor executor, ExportPolicy policy) {
- this.endpointRepo = endpointRepo;
- this.policy = policy;
- this.rsaSet = new HashSet<RemoteServiceAdmin>();
- this.execService = executor;
- }
-
- // track all service registrations so we can export any services that are configured to be exported
- // ServiceListener events may be delivered out of order, concurrently, re-entrant, etc. (see spec or docs)
- public void serviceChanged(ServiceEvent event) {
- ServiceReference<?> sref = event.getServiceReference();
- if (event.getType() == ServiceEvent.REGISTERED) {
- LOG.debug("Received REGISTERED ServiceEvent: {}", event);
- export(sref);
- } else if (event.getType() == ServiceEvent.UNREGISTERING) {
- LOG.debug("Received UNREGISTERING ServiceEvent: {}", event);
- endpointRepo.removeService(sref);
- }
- }
-
- public void add(RemoteServiceAdmin rsa) {
- rsaSet.add(rsa);
- for (ServiceReference<?> serviceRef : endpointRepo.getServicesToBeExportedFor(rsa)) {
- export(serviceRef);
- }
- };
-
- public void remove(RemoteServiceAdmin rsa) {
- rsaSet.remove(rsa);
- endpointRepo.removeRemoteServiceAdmin(rsa);
- };
-
- private void export(final ServiceReference<?> sref) {
- execService.execute(new Runnable() {
- public void run() {
- doExport(sref);
- }
- });
- }
-
- private void doExport(final ServiceReference<?> sref) {
- Map<String, ?> addProps = policy.additionalParameters(sref);
- if (!shouldExport(sref, addProps)) {
- LOG.debug("Skipping service {}", sref);
- return;
- }
- LOG.debug("Exporting service {}", sref);
- endpointRepo.addService(sref); // mark for future export even if there are currently no RSAs
- if (rsaSet.size() == 0) {
- LOG.error("No RemoteServiceAdmin available! Unable to export service from bundle {}, interfaces: {}",
- getSymbolicName(sref.getBundle()),
- sref.getProperty(org.osgi.framework.Constants.OBJECTCLASS));
- return;
- }
-
- for (RemoteServiceAdmin remoteServiceAdmin : rsaSet) {
- LOG.info("TopologyManager: handling remoteServiceAdmin " + remoteServiceAdmin);
- if (endpointRepo.isAlreadyExportedForRsa(sref, remoteServiceAdmin)) {
- // already handled by this remoteServiceAdmin
- LOG.debug("already handled by this remoteServiceAdmin -> skipping");
- } else {
-
- exportServiceUsingRemoteServiceAdmin(sref, remoteServiceAdmin, addProps);
- }
- }
- }
-
- private boolean shouldExport(ServiceReference<?> sref, Map<String, ?> addProps) {
- String exported = (String)sref.getProperty(RemoteConstants.SERVICE_EXPORTED_INTERFACES);
- String addExported = (String)addProps.get(RemoteConstants.SERVICE_EXPORTED_INTERFACES);
- String effectiveExported = addExported != null ? addExported : exported;
- return (effectiveExported != null) && !effectiveExported.isEmpty();
- }
-
- private Object getSymbolicName(Bundle bundle) {
- return bundle == null ? null : bundle.getSymbolicName();
- }
-
- private void exportServiceUsingRemoteServiceAdmin(final ServiceReference<?> sref,
- final RemoteServiceAdmin remoteServiceAdmin,
- Map<String, ?> addProps) {
- // abort if the service was unregistered by the time we got here
- // (we check again at the end, but this optimization saves unnecessary heavy processing)
- if (sref.getBundle() == null) {
- LOG.info("TopologyManager: export aborted for {} since it was unregistered", sref);
- endpointRepo.removeService(sref);
- return;
- }
- // do the export
- LOG.debug("exporting {}...", sref);
- // TODO: additional parameter Map?
- Collection<ExportRegistration> exportRegs = remoteServiceAdmin.exportService(sref, addProps);
- // process successful/failed registrations
- List<EndpointDescription> endpoints = new ArrayList<EndpointDescription>();
- for (ExportRegistration reg : exportRegs) {
- if (reg.getException() == null) {
- EndpointDescription endpoint = getExportedEndpoint(reg);
- LOG.info("TopologyManager: export succeeded for {}, endpoint ", sref, endpoint);
- endpoints.add(endpoint);
- } else {
- LOG.error("TopologyManager: export failed for {}", sref);
- reg.close();
- }
- }
- // abort export if service was unregistered in the meanwhile (since we have a race
- // with the unregister event which may have already been handled, so we'll miss it)
- if (sref.getBundle() == null) {
- LOG.info("TopologyManager: export reverted for {} since service was unregistered", sref);
- endpointRepo.removeService(sref);
- for (ExportRegistration reg : exportRegs) {
- reg.close();
- }
- return;
- }
- // add the new exported endpoints
- if (!endpoints.isEmpty()) {
- LOG.info("TopologyManager: export successful for {}, endpoints: {}", sref, endpoints);
- endpointRepo.addEndpoints(sref, remoteServiceAdmin, endpoints);
- }
- }
-
- /**
- * Retrieves an exported Endpoint (while safely handling nulls).
- *
- * @param exReg an export registration
- * @return exported Endpoint or null if not present
- */
- private EndpointDescription getExportedEndpoint(ExportRegistration exReg) {
- ExportReference ref = (exReg == null) ? null : exReg.getExportReference();
- return (ref == null) ? null : ref.getExportedEndpoint();
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/EndpointListenerManager.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/EndpointListenerManager.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/EndpointListenerManager.java
deleted file mode 100644
index 7812e52..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/EndpointListenerManager.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * 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.topologymanager.importer;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Manages an EndpointListener and adjusts its scope according to requested service filters.
- */
-public class EndpointListenerManager {
-
- private static final Logger LOG = LoggerFactory.getLogger(EndpointListenerManager.class);
-
- private final BundleContext bctx;
- private volatile ServiceRegistration<EndpointListener> serviceRegistration;
- private final List<String> filters = new ArrayList<String>();
- private final EndpointListener endpointListener;
-
- public EndpointListenerManager(BundleContext bc, EndpointListener endpointListener) {
- this.bctx = bc;
- this.endpointListener = endpointListener;
- }
-
- protected void start() {
- serviceRegistration = bctx.registerService(EndpointListener.class, endpointListener,
- getRegistrationProperties());
- }
-
- public void stop() {
- if (serviceRegistration != null) {
- serviceRegistration.unregister();
- }
- }
-
- protected void extendScope(String filter) {
- if (filter == null) {
- return;
- }
- LOG.debug("EndpointListener: extending scope by {}", filter);
- synchronized (filters) {
- filters.add(filter);
- }
- updateRegistration();
- }
-
- protected void reduceScope(String filter) {
- if (filter == null) {
- return;
- }
- LOG.debug("EndpointListener: reducing scope by {}", filter);
- synchronized (filters) {
- filters.remove(filter);
- }
- updateRegistration();
- }
-
- private Dictionary<String, Object> getRegistrationProperties() {
- Dictionary<String, Object> p = new Hashtable<String, Object>();
-
- synchronized (filters) {
- LOG.debug("Current filter: {}", filters);
- p.put(EndpointListener.ENDPOINT_LISTENER_SCOPE, new ArrayList<String>(filters));
- }
-
- return p;
- }
-
- private void updateRegistration() {
- if (serviceRegistration != null) {
- serviceRegistration.setProperties(getRegistrationProperties());
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/FilterHelper.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/FilterHelper.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/FilterHelper.java
deleted file mode 100644
index 3739f16..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/FilterHelper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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.topologymanager.importer;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.osgi.framework.Constants;
-
-public final class FilterHelper {
- private static final String OBJECTCLASS_EXPRESSION = ".*\\(" + Constants.OBJECTCLASS + "=([a-zA-Z_0-9.]+)\\).*";
- private static final Pattern OBJECTCLASS_PATTERN = Pattern.compile(OBJECTCLASS_EXPRESSION);
-
- private FilterHelper() {
- // prevent instantiation
- }
-
- public static String getObjectClass(String filter) {
- if (filter != null) {
- Matcher matcher = OBJECTCLASS_PATTERN.matcher(filter);
- if (matcher.matches() && matcher.groupCount() >= 1) {
- return matcher.group(1);
- }
- }
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ListenerHookImpl.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ListenerHookImpl.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ListenerHookImpl.java
deleted file mode 100644
index 03ec9da..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ListenerHookImpl.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * 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.topologymanager.importer;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.hooks.service.ListenerHook;
-import org.osgi.service.remoteserviceadmin.RemoteConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Listens for service listeners and informs ServiceInterestListener about added and removed interest
- * in services
- */
-public class ListenerHookImpl implements ListenerHook {
-
- private static final Logger LOG = LoggerFactory.getLogger(ListenerHookImpl.class);
-
- // From the old impl.
- private static final Set<String> SYSTEM_PACKAGES;
- static {
- SYSTEM_PACKAGES = new HashSet<String>();
- SYSTEM_PACKAGES.add("org.osgi.service");
- SYSTEM_PACKAGES.add("org.apache.felix");
- SYSTEM_PACKAGES.add("org.ops4j.pax.logging");
- SYSTEM_PACKAGES.add("ch.ethz.iks.slp");
- SYSTEM_PACKAGES.add("org.ungoverned.osgi.service");
- SYSTEM_PACKAGES.add("org.springframework.osgi.context.event.OsgiBundleApplicationContextListener");
- SYSTEM_PACKAGES.add("java.net.ContentHandler");
- }
-
- private final BundleContext bctx;
- private final ServiceInterestListener serviceInterestListener;
- private final String frameworkUUID;
-
- public ListenerHookImpl(BundleContext bc, ServiceInterestListener serviceInterestListener) {
- this.bctx = bc;
- this.frameworkUUID = bctx.getProperty(Constants.FRAMEWORK_UUID);
- this.serviceInterestListener = serviceInterestListener;
- }
-
- @Override
- public void added(Collection<ListenerInfo> listeners) {
- LOG.debug("added listeners {}", listeners);
- for (ListenerInfo listenerInfo : listeners) {
- LOG.debug("Filter {}", listenerInfo.getFilter());
-
- String className = FilterHelper.getObjectClass(listenerInfo.getFilter());
-
- if (listenerInfo.getBundleContext().equals(bctx)) {
- LOG.debug("ListenerHookImpl: skipping request from myself");
- continue;
- }
-
- if (listenerInfo.getFilter() == null) {
- LOG.debug("skipping empty filter");
- continue;
- }
-
- if (isClassExcluded(className)) {
- LOG.debug("Skipping import request for excluded class [{}]", className);
- continue;
- }
- String exFilter = extendFilter(listenerInfo.getFilter());
- serviceInterestListener.addServiceInterest(exFilter);
- }
- }
-
- @Override
- public void removed(Collection<ListenerInfo> listeners) {
- LOG.debug("removed listeners {}", listeners);
-
- for (ListenerInfo listenerInfo : listeners) {
- LOG.debug("Filter {}", listenerInfo.getFilter());
-
- // TODO: determine if service was handled?
- String exFilter = extendFilter(listenerInfo.getFilter());
- serviceInterestListener.removeServiceInterest(exFilter);
- }
- }
-
- private static boolean isClassExcluded(String className) {
- if (className == null) {
- return true;
- }
-
- for (String p : SYSTEM_PACKAGES) {
- if (className.startsWith(p)) {
- return true;
- }
- }
- return false;
- }
-
- String extendFilter(String filter) {
- return "(&" + filter + "(!(" + RemoteConstants.ENDPOINT_FRAMEWORK_UUID + "=" + frameworkUUID + ")))";
- }
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/RSATracker.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/RSATracker.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/RSATracker.java
deleted file mode 100644
index 56e98e8..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/RSATracker.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 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.topologymanager.importer;
-
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
-
-public interface RSATracker {
- void added(RemoteServiceAdmin rsa);
- void removed(RemoteServiceAdmin rsa);
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ReferenceCounter.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ReferenceCounter.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ReferenceCounter.java
deleted file mode 100644
index 6ecff31..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ReferenceCounter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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.topologymanager.importer;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * Manages a reference count per key.
- *
- * @param <K> the key type
- */
-public class ReferenceCounter<K> {
-
- private final ConcurrentMap<K, Integer> counts = new ConcurrentHashMap<K, Integer>();
-
- /**
- * Increases the reference count for the given key,
- * or sets it to 1 if the key has no existing count.
- *
- * @param key a key
- * @return the updated reference count
- */
- public int add(K key) {
- while (true) {
- Integer count = counts.get(key);
- if (count == null) {
- if (counts.putIfAbsent(key, 1) == null) {
- return 1;
- }
- } else if (counts.replace(key, count, count + 1)) {
- return count + 1;
- }
- }
- }
-
- /**
- * Decreases the reference count for the given key,
- * and removes it if it reaches 0.
- * If the key has no existing count, -1 is returned.
- *
- * @param key a key
- * @return the updated reference count, or -1 if the key has no existing count
- */
- public int remove(K key) {
- while (true) {
- Integer count = counts.get(key);
- if (count == null) {
- return -1;
- }
- if (count == 1) {
- if (counts.remove(key, 1)) {
- return 0;
- }
- } else if (counts.replace(key, count, count - 1)) {
- return count - 1;
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ServiceInterestListener.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ServiceInterestListener.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ServiceInterestListener.java
deleted file mode 100644
index f4db92e..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/ServiceInterestListener.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 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.topologymanager.importer;
-
-public interface ServiceInterestListener {
-
- void addServiceInterest(String filter);
-
- void removeServiceInterest(String filter);
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java b/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java
deleted file mode 100644
index 30fe4c2..0000000
--- a/topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/**
- * 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.topologymanager.importer;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.hooks.service.ListenerHook;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
-import org.osgi.service.remoteserviceadmin.ImportReference;
-import org.osgi.service.remoteserviceadmin.ImportRegistration;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdminListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Listens for remote endpoints using the EndpointListener interface and the EndpointListenerManager.
- * Listens for local service interests using the ListenerHookImpl that calls back through the
- * ServiceInterestListener interface.
- * Manages local creation and destruction of service imports using the available RemoteServiceAdmin services.
- */
-public class TopologyManagerImport implements EndpointListener, RemoteServiceAdminListener, ServiceInterestListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(TopologyManagerImport.class);
- private ExecutorService execService;
-
- private final EndpointListenerManager endpointListenerManager;
- private final BundleContext bctx;
- private Set<RemoteServiceAdmin> rsaSet;
- private final ListenerHookImpl listenerHook;
-
- /**
- * If set to false only one service is imported for each import interest even it multiple services are
- * available. If set to true, all available services are imported.
- *
- * TODO: Make this available as a configuration option
- */
- private boolean importAllAvailable = true;
-
- /**
- * Contains an instance of the Class Import Interest for each distinct import request. If the same filter
- * is requested multiple times the existing instance of the Object increments an internal reference
- * counter. If an interest is removed, the related ServiceInterest object is used to reduce the reference
- * counter until it reaches zero. in this case the interest is removed.
- */
- private final ReferenceCounter<String> importInterestsCounter = new ReferenceCounter<String>();
-
- /**
- * List of Endpoints by matched filter that were reported by the EndpointListener and can be imported
- */
- private final Map<String /* filter */, List<EndpointDescription>> importPossibilities
- = new HashMap<String, List<EndpointDescription>>();
-
- /**
- * List of already imported Endpoints by their matched filter
- */
- private final Map<String /* filter */, List<ImportRegistration>> importedServices
- = new HashMap<String, List<ImportRegistration>>();
-
-
- public TopologyManagerImport(BundleContext bc) {
- this.rsaSet = new HashSet<RemoteServiceAdmin>();
- bctx = bc;
- endpointListenerManager = new EndpointListenerManager(bctx, this);
- execService = new ThreadPoolExecutor(5, 10, 50, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
- listenerHook = new ListenerHookImpl(bc, this);
- }
-
- public void start() {
- bctx.registerService(RemoteServiceAdminListener.class, this, null);
- bctx.registerService(ListenerHook.class, listenerHook, null);
- endpointListenerManager.start();
- }
-
- public void stop() {
- endpointListenerManager.stop();
- execService.shutdown();
- // this is called from Activator.stop(), which implicitly unregisters our registered services
- }
-
- /* (non-Javadoc)
- * @see org.apache.cxf.dosgi.topologymanager.ServiceInterestListener#addServiceInterest(java.lang.String)
- */
- public void addServiceInterest(String filter) {
- if (importInterestsCounter.add(filter) == 1) {
- endpointListenerManager.extendScope(filter);
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.cxf.dosgi.topologymanager.ServiceInterestListener#removeServiceInterest(java.lang.String)
- */
- public void removeServiceInterest(String filter) {
- if (importInterestsCounter.remove(filter) == 0) {
- LOG.debug("last reference to import interest is gone -> removing interest filter: {}", filter);
- endpointListenerManager.reduceScope(filter);
- synchronized (importedServices) {
- List<ImportRegistration> irs = importedServices.remove(filter);
- if (irs != null) {
- for (ImportRegistration ir : irs) {
- ir.close();
- }
- }
- }
- }
- }
-
- public void endpointAdded(EndpointDescription endpoint, String filter) {
- if (filter == null) {
- LOG.error("Endpoint is not handled because no matching filter was provided!");
- return;
- }
- LOG.debug("importable service added for filter {}, endpoint {}", filter, endpoint);
- addImportPossibility(endpoint, filter);
- triggerImport(filter);
- }
-
- public void endpointRemoved(EndpointDescription endpoint, String filter) {
- LOG.debug("EndpointRemoved {}", endpoint);
- removeImportPossibility(endpoint, filter);
- triggerImport(filter);
- }
-
- private void addImportPossibility(EndpointDescription endpoint, String filter) {
- synchronized (importPossibilities) {
- List<EndpointDescription> endpoints = importPossibilities.get(filter);
- if (endpoints == null) {
- endpoints = new ArrayList<EndpointDescription>();
- importPossibilities.put(filter, endpoints);
- }
- // prevent adding the same endpoint multiple times, which can happen sometimes,
- // and which causes imports to remain available even when services are actually down
- if (!endpoints.contains(endpoint)) {
- endpoints.add(endpoint);
- }
- }
- }
-
- private void removeImportPossibility(EndpointDescription endpoint, String filter) {
- synchronized (importPossibilities) {
- List<EndpointDescription> endpoints = importPossibilities.get(filter);
- if (endpoints != null) {
- endpoints.remove(endpoint);
- if (endpoints.isEmpty()) {
- importPossibilities.remove(filter);
- }
- }
- }
- }
-
- public void add(RemoteServiceAdmin rsa) {
- rsaSet.add(rsa);
- synchronized (importPossibilities) {
- for (String filter : importPossibilities.keySet()) {
- triggerImport(filter);
- }
- }
- }
-
- public void remove(RemoteServiceAdmin rsa) {
- rsaSet.remove(rsa);
- }
-
-
- private void triggerImport(final String filter) {
- LOG.debug("Import of a service for filter {} was queued", filter);
-
- execService.execute(new Runnable() {
- public void run() {
- try {
- unexportNotAvailableServices(filter);
- importServices(filter);
- } catch (Exception e) {
- LOG.error(e.getMessage(), e);
- }
- // Notify EndpointListeners? NO!
- }
- });
- }
-
- private void unexportNotAvailableServices(String filter) {
- synchronized (importedServices) {
- List<ImportRegistration> importRegistrations = importedServices.get(filter);
- if (importRegistrations != null) {
- // iterate over a copy
- for (ImportRegistration ir : new ArrayList<ImportRegistration>(importRegistrations)) {
- EndpointDescription endpoint = ir.getImportReference().getImportedEndpoint();
- if (!isImportPossibilityAvailable(endpoint, filter)) {
- removeImport(ir, null); // also unexports the service
- }
- }
- }
- }
- }
-
- private boolean isImportPossibilityAvailable(EndpointDescription endpoint, String filter) {
- synchronized (importPossibilities) {
- List<EndpointDescription> endpoints = importPossibilities.get(filter);
- return endpoints != null && endpoints.contains(endpoint);
- }
- }
-
- // return a copy to prevent sync issues
- private List<EndpointDescription> getImportPossibilitiesCopy(String filter) {
- synchronized (importPossibilities) {
- List<EndpointDescription> possibilities = importPossibilities.get(filter);
- return possibilities == null
- ? Collections.<EndpointDescription>emptyList()
- : new ArrayList<EndpointDescription>(possibilities);
- }
- }
-
- private void importServices(String filter) {
- synchronized (importedServices) {
- List<ImportRegistration> importRegistrations = importedServices.get(filter);
- for (EndpointDescription endpoint : getImportPossibilitiesCopy(filter)) {
- // TODO but optional: if the service is already imported and the endpoint is still
- // in the list of possible imports check if a "better" endpoint is now in the list
- if (!alreadyImported(endpoint, importRegistrations)) {
- // service not imported yet -> import it now
- ImportRegistration ir = importService(endpoint);
- if (ir != null) {
- // import was successful
- if (importRegistrations == null) {
- importRegistrations = new ArrayList<ImportRegistration>();
- importedServices.put(filter, importRegistrations);
- }
- importRegistrations.add(ir);
- if (!importAllAvailable) {
- return;
- }
- }
- }
- }
- }
- }
-
- private boolean alreadyImported(EndpointDescription endpoint, List<ImportRegistration> importRegistrations) {
- if (importRegistrations != null) {
- for (ImportRegistration ir : importRegistrations) {
- if (endpoint.equals(ir.getImportReference().getImportedEndpoint())) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Tries to import the service with each rsa until one import is successful
- *
- * @param endpoint endpoint to import
- * @return import registration of the first successful import
- */
- private ImportRegistration importService(EndpointDescription endpoint) {
- for (RemoteServiceAdmin rsa : rsaSet) {
- ImportRegistration ir = rsa.importService(endpoint);
- if (ir != null) {
- if (ir.getException() == null) {
- LOG.debug("Service import was successful {}", ir);
- return ir;
- } else {
- LOG.info("Error importing service " + endpoint, ir.getException());
- }
- }
- }
- return null;
- }
-
- /**
- * Remove and close (unexport) the given import. The import is specified either
- * by its ImportRegistration or by its ImportReference (only one of them must
- * be specified).
- * <p>
- * If this method is called from within iterations on the underlying data structure,
- * the iterations must be made on copies of the structures rather than the original
- * references in order to prevent ConcurrentModificationExceptions.
- *
- * @param reg the import registration to remove
- * @param ref the import reference to remove
- */
- private void removeImport(ImportRegistration reg, ImportReference ref) {
- // this method may be called recursively by calling ImportRegistration.close()
- // and receiving a RemoteServiceAdminEvent for its unregistration, which results
- // in a ConcurrentModificationException. We avoid this by closing the registrations
- // only after data structure manipulation is done, and being re-entrant.
- synchronized (importedServices) {
- List<ImportRegistration> removed = new ArrayList<ImportRegistration>();
- for (Iterator<List<ImportRegistration>> it1 = importedServices.values().iterator(); it1.hasNext();) {
- Collection<ImportRegistration> irs = it1.next();
- for (Iterator<ImportRegistration> it2 = irs.iterator(); it2.hasNext();) {
- ImportRegistration ir = it2.next();
- if (ir.equals(reg) || ir.getImportReference().equals(ref)) {
- removed.add(ir);
- it2.remove();
- }
- }
- if (irs.isEmpty()) {
- it1.remove();
- }
- }
- for (ImportRegistration ir : removed) {
- ir.close();
- }
- }
- }
-
- public void remoteAdminEvent(RemoteServiceAdminEvent event) {
- if (event.getType() == RemoteServiceAdminEvent.IMPORT_UNREGISTRATION) {
- removeImport(null, event.getImportReference());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/ActivatorTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/ActivatorTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/ActivatorTest.java
new file mode 100644
index 0000000..e4b1bbd
--- /dev/null
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/ActivatorTest.java
@@ -0,0 +1,68 @@
+/**
+ * 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.aries.rsa.topologymanager;
+
+import org.apache.aries.rsa.topologymanager.exporter.DefaultExportPolicy;
+import org.apache.aries.rsa.topologymanager.exporter.TopologyManagerExport;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.easymock.IMocksControl;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+public class ActivatorTest {
+
+ @Test
+ public void testStart() throws Exception {
+ IMocksControl c = EasyMock.createNiceControl();
+ BundleContext context = c.createMock(BundleContext.class);
+ EasyMock.expect(context.getProperty(Constants.FRAMEWORK_UUID)).andReturn("myid");
+ context.addServiceListener(EasyMock.isA(TopologyManagerExport.class));
+ EasyMock.expectLastCall();
+ final Capture<String> filter = EasyMock.newCapture();
+ EasyMock.expect(context.createFilter(EasyMock.capture(filter)))
+ .andAnswer(new IAnswer<Filter>() {
+ public Filter answer() throws Throwable {
+ return FrameworkUtil.createFilter(filter.getValue());
+ }
+ }).times(2);
+ ServiceReference<?> sref = c.createMock(ServiceReference.class);
+ Bundle bundle = c.createMock(Bundle.class);
+ EasyMock.expect(sref.getBundle()).andReturn(bundle).anyTimes();
+ EasyMock.expect(context.getServiceReferences((String)null, Activator.DOSGI_SERVICES))
+ .andReturn(new ServiceReference[]{sref});
+
+ c.replay();
+ Activator activator = new Activator();
+ activator.doStart(context, new DefaultExportPolicy());
+ c.verify();
+
+ c.reset();
+ c.replay();
+ activator.doStop(context);
+ c.verify();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java
new file mode 100644
index 0000000..6d7959a
--- /dev/null
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifierTest.java
@@ -0,0 +1,160 @@
+/**
+ * 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.aries.rsa.topologymanager.exporter;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+
+@SuppressWarnings({
+ "rawtypes", "unchecked"
+ })
+public class EndpointListenerNotifierTest {
+
+ @Test
+ public void testNotifyListener() throws InvalidSyntaxException {
+ EndpointDescription endpoint1 = createEndpoint("myClass");
+ EndpointDescription endpoint2 = createEndpoint("notMyClass");
+
+ // Expect listener to be called for endpoint1 but not for endpoint2
+ EndpointListener epl = listenerExpects(endpoint1, "(objectClass=myClass)");
+
+ EndpointRepository exportRepository = new EndpointRepository();
+ EndpointListenerNotifier tm = new EndpointListenerNotifier(exportRepository);
+
+ EasyMock.replay(epl);
+ Set<Filter> filters = new HashSet<Filter>();
+ filters.add(FrameworkUtil.createFilter("(objectClass=myClass)"));
+ tm.add(epl, filters);
+ tm.endpointAdded(endpoint1, null);
+ tm.endpointAdded(endpoint2, null);
+ tm.endpointRemoved(endpoint1, null);
+ tm.endpointRemoved(endpoint2, null);
+ EasyMock.verify(epl);
+ }
+
+ private EndpointListener listenerExpects(EndpointDescription endpoint, String filter) {
+ EndpointListener epl = EasyMock.createStrictMock(EndpointListener.class);
+ epl.endpointAdded(EasyMock.eq(endpoint), EasyMock.eq(filter));
+ EasyMock.expectLastCall().once();
+ epl.endpointRemoved(EasyMock.eq(endpoint), EasyMock.eq(filter));
+ EasyMock.expectLastCall().once();
+ return epl;
+ }
+
+ @Test
+ public void testNotifyListeners() throws InvalidSyntaxException {
+ EndpointDescription endpoint1 = createEndpoint("myClass");
+
+ EndpointListener epl = EasyMock.createStrictMock(EndpointListener.class);
+ epl.endpointAdded(EasyMock.eq(endpoint1), EasyMock.eq("(objectClass=myClass)"));
+ EasyMock.expectLastCall().once();
+ epl.endpointRemoved(EasyMock.eq(endpoint1), EasyMock.eq("(objectClass=myClass)"));
+ EasyMock.expectLastCall().once();
+
+ EndpointRepository exportRepository = new EndpointRepository();
+ EndpointListenerNotifier tm = new EndpointListenerNotifier(exportRepository);
+
+ EasyMock.replay(epl);
+ Set<Filter> filters = new HashSet<Filter>();
+ filters.add(FrameworkUtil.createFilter("(objectClass=myClass)"));
+ tm.add(epl, filters);
+ tm.endpointAdded(endpoint1, null);
+ tm.endpointRemoved(endpoint1, null);
+ tm.remove(epl);
+ EasyMock.verify(epl);
+ }
+
+ public EndpointDescription createEndpoint(String iface) {
+ Map<String, Object> props = new Hashtable<String, Object>();
+ props.put("objectClass", new String[]{iface});
+ props.put(RemoteConstants.ENDPOINT_ID, iface);
+ props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "any");
+ return new EndpointDescription(props);
+ }
+
+ @Test
+ public void testNormalizeScopeForSingleString() {
+ ServiceReference sr = createListenerServiceWithFilter("(myProp=A)");
+ Set<Filter> res = EndpointListenerNotifier.getFiltersFromEndpointListenerScope(sr);
+ assertEquals(1, res.size());
+ Filter filter = res.iterator().next();
+ filterMatches(filter);
+ }
+
+ @Test
+ public void testNormalizeScopeForStringArray() {
+ String[] filters = {"(myProp=A)", "(otherProp=B)"};
+ ServiceReference sr = createListenerServiceWithFilter(filters);
+ Set<Filter> res = EndpointListenerNotifier.getFiltersFromEndpointListenerScope(sr);
+ assertEquals(filters.length, res.size());
+ Iterator<Filter> it = res.iterator();
+ Filter filter1 = it.next();
+ Filter filter2 = it.next();
+ Dictionary<String, String> props = new Hashtable();
+ props.put("myProp", "A");
+ assertThat(filter1.match(props) || filter2.match(props), is(true));
+ }
+
+ @Test
+ public void testNormalizeScopeForCollection() {
+ Collection<String> collection = Arrays.asList("(myProp=A)", "(otherProp=B)");
+ ServiceReference sr = createListenerServiceWithFilter(collection);
+ Set<Filter> res = EndpointListenerNotifier.getFiltersFromEndpointListenerScope(sr);
+ Iterator<Filter> it = res.iterator();
+ Filter filter1 = it.next();
+ Filter filter2 = it.next();
+ Dictionary<String, String> props = new Hashtable();
+ props.put("myProp", "A");
+ Assert.assertThat(filter1.match(props) || filter2.match(props), is(true));
+ }
+
+ private void filterMatches(Filter filter) {
+ Dictionary<String, String> props = new Hashtable();
+ props.put("myProp", "A");
+ Assert.assertTrue("Filter should match", filter.match(props));
+ }
+
+ private ServiceReference createListenerServiceWithFilter(Object filters) {
+ ServiceReference sr = EasyMock.createMock(ServiceReference.class);
+ EasyMock.expect(sr.getProperty(EndpointListener.ENDPOINT_LISTENER_SCOPE)).andReturn(filters);
+ EasyMock.replay(sr);
+ return sr;
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepositoryTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepositoryTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepositoryTest.java
new file mode 100644
index 0000000..59f1859
--- /dev/null
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepositoryTest.java
@@ -0,0 +1,82 @@
+/**
+ * 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.aries.rsa.topologymanager.exporter;
+
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
+
+public class EndpointRepositoryTest {
+
+ @Test
+ public void testAddRemove() throws InvalidSyntaxException {
+ EndpointDescription ep1 = createEndpoint("my");
+
+ IMocksControl c = EasyMock.createControl();
+ ServiceReference<?> sref = createService(c);
+ RemoteServiceAdmin rsa = c.createMock(RemoteServiceAdmin.class);
+ EndpointListener notifier = c.createMock(EndpointListener.class);
+
+ notifier.endpointAdded(ep1, null);
+ EasyMock.expectLastCall();
+
+ c.replay();
+ EndpointRepository repo = new EndpointRepository();
+ repo.setNotifier(notifier);
+ List<EndpointDescription> endpoints = Arrays.asList(ep1);
+ repo.addEndpoints(sref, rsa, endpoints);
+ c.verify();
+
+ c.reset();
+ notifier.endpointRemoved(ep1, null);
+ EasyMock.expectLastCall();
+
+ c.replay();
+ repo.removeRemoteServiceAdmin(rsa);
+ c.verify();
+ }
+
+ private ServiceReference<?> createService(IMocksControl c) {
+ ServiceReference<?> sref = c.createMock(ServiceReference.class);
+ Bundle bundle = c.createMock(Bundle.class);
+ EasyMock.expect(bundle.getSymbolicName()).andReturn("myBundle");
+ EasyMock.expect(sref.getBundle()).andReturn(bundle);
+ return sref;
+ }
+
+ public EndpointDescription createEndpoint(String iface) {
+ Map<String, Object> props = new Hashtable<String, Object>();
+ props.put("objectClass", new String[]{iface});
+ props.put(RemoteConstants.ENDPOINT_ID, iface);
+ props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "any");
+ return new EndpointDescription(props);
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java
new file mode 100644
index 0000000..4c9d28f
--- /dev/null
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/TopologyManagerExportTest.java
@@ -0,0 +1,153 @@
+/**
+ * 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.aries.rsa.topologymanager.exporter;
+
+import static org.easymock.EasyMock.expectLastCall;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+import org.apache.aries.rsa.spi.ExportPolicy;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.ExportReference;
+import org.osgi.service.remoteserviceadmin.ExportRegistration;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class TopologyManagerExportTest {
+
+ /**
+ * This tests if the topology manager handles a service marked to be exported correctly by exporting it to
+ * an available RemoteServiceAdmin and notifying an EndpointListener afterwards.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testServiceExportUnexport() throws Exception {
+ IMocksControl c = EasyMock.createControl();
+ RemoteServiceAdmin rsa = c.createMock(RemoteServiceAdmin.class);
+ final EndpointListener notifier = c.createMock(EndpointListener.class);
+ final ServiceReference sref = createUserService(c);
+ EndpointDescription epd = createEndpoint();
+ expectServiceExported(c, rsa, notifier, sref, epd);
+
+ c.replay();
+ EndpointRepository endpointRepo = new EndpointRepository();
+ endpointRepo.setNotifier(notifier);
+ Executor executor = syncExecutor();
+ ExportPolicy policy = new DefaultExportPolicy();
+ TopologyManagerExport exportManager = new TopologyManagerExport(endpointRepo, executor, policy);
+ exportManager.add(rsa);
+ exportManager.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref));
+ c.verify();
+
+ c.reset();
+ notifier.endpointRemoved(epd, null);
+ expectLastCall().once();
+ c.replay();
+ exportManager.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, sref));
+ c.verify();
+
+ c.reset();
+ c.replay();
+ exportManager.serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED, sref));
+ c.verify();
+
+ c.reset();
+ c.replay();
+ exportManager.remove(rsa);
+ c.verify();
+ }
+
+ @Test
+ public void testExportExisting() throws Exception {
+ IMocksControl c = EasyMock.createControl();
+ RemoteServiceAdmin rsa = c.createMock(RemoteServiceAdmin.class);
+ final EndpointListenerNotifier mockEpListenerNotifier = c.createMock(EndpointListenerNotifier.class);
+ final ServiceReference sref = createUserService(c);
+ expectServiceExported(c, rsa, mockEpListenerNotifier, sref, createEndpoint());
+ c.replay();
+
+ EndpointRepository endpointRepo = new EndpointRepository();
+ endpointRepo.setNotifier(mockEpListenerNotifier);
+ ExportPolicy policy = new DefaultExportPolicy();
+ TopologyManagerExport exportManager = new TopologyManagerExport(endpointRepo, syncExecutor(), policy);
+ exportManager.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref));
+ exportManager.add(rsa);
+ c.verify();
+ }
+
+ private void expectServiceExported(IMocksControl c, RemoteServiceAdmin rsa,
+ final EndpointListener listener,
+ final ServiceReference sref, EndpointDescription epd) {
+ ExportRegistration exportRegistration = createExportRegistration(c, epd);
+ EasyMock.expect(rsa.exportService(EasyMock.same(sref), (Map<String, Object>)EasyMock.anyObject()))
+ .andReturn(Collections.singletonList(exportRegistration)).once();
+ listener.endpointAdded(epd, null);
+ EasyMock.expectLastCall().once();
+ }
+
+ private Executor syncExecutor() {
+ return new Executor() {
+ @Override
+ public void execute(Runnable command) {
+ command.run();
+ }
+ };
+ }
+
+ private ExportRegistration createExportRegistration(IMocksControl c, EndpointDescription endpoint) {
+ ExportRegistration exportRegistration = c.createMock(ExportRegistration.class);
+ ExportReference exportReference = c.createMock(ExportReference.class);
+ EasyMock.expect(exportRegistration.getExportReference()).andReturn(exportReference).anyTimes();
+ EasyMock.expect(exportRegistration.getException()).andReturn(null).anyTimes();
+ EasyMock.expect(exportReference.getExportedEndpoint()).andReturn(endpoint).anyTimes();
+ return exportRegistration;
+ }
+
+ private EndpointDescription createEndpoint() {
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(RemoteConstants.ENDPOINT_ID, "1");
+ props.put(Constants.OBJECTCLASS, new String[] {"abc"});
+ props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "cxf");
+ return new EndpointDescription(props);
+ }
+
+ private ServiceReference createUserService(IMocksControl c) {
+ final ServiceReference sref = c.createMock(ServiceReference.class);
+ EasyMock.expect(sref.getProperty(EasyMock.same(RemoteConstants.SERVICE_EXPORTED_INTERFACES)))
+ .andReturn("*").anyTimes();
+ Bundle srefBundle = c.createMock(Bundle.class);
+ EasyMock.expect(sref.getBundle()).andReturn(srefBundle).atLeastOnce();
+ EasyMock.expect(sref.getProperty("objectClass")).andReturn("org.My").anyTimes();
+ EasyMock.expect(srefBundle.getSymbolicName()).andReturn("serviceBundleName").atLeastOnce();
+ return sref;
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/EndpointListenerImplTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/EndpointListenerImplTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/EndpointListenerImplTest.java
new file mode 100644
index 0000000..4e8e6b4
--- /dev/null
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/EndpointListenerImplTest.java
@@ -0,0 +1,113 @@
+/**
+ * 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.aries.rsa.topologymanager.importer;
+
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.aries.rsa.topologymanager.importer.EndpointListenerManager;
+import org.apache.aries.rsa.topologymanager.importer.TopologyManagerImport;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.easymock.IMocksControl;
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+
+public class EndpointListenerImplTest extends Assert {
+
+ int testCase;
+
+ @SuppressWarnings({
+ "rawtypes", "unchecked"
+ })
+ @Test
+ public void testScopeChange() {
+ IMocksControl c = EasyMock.createNiceControl();
+ BundleContext bc = c.createMock(BundleContext.class);
+ TopologyManagerImport tm = c.createMock(TopologyManagerImport.class);
+ ServiceRegistration sr = c.createMock(ServiceRegistration.class);
+
+ // expect Listener registration
+ EasyMock.expect(bc.registerService(EasyMock.anyObject(Class.class),
+ EasyMock.anyObject(),
+ (Dictionary)EasyMock.anyObject())).andReturn(sr).atLeastOnce();
+
+ sr.setProperties((Dictionary)EasyMock.anyObject());
+
+ // expect property changes based on later calls
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+
+ public Object answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ Dictionary props = (Dictionary)args[0];
+ List<String> scope = (List<String>)props.get(EndpointListener.ENDPOINT_LISTENER_SCOPE);
+ switch (testCase) {
+ case 1:
+ assertEquals(1, scope.size());
+ assertEquals("(a=b)", scope.get(0));
+ break;
+ case 2:
+ assertEquals(0, scope.size());
+ break;
+ case 3:
+ assertEquals("adding entry to empty list failed", 1, scope.size());
+ assertEquals("(a=b)", scope.get(0));
+ break;
+ case 4:
+ assertEquals("adding second entry failed", 2, scope.size());
+ assertNotNull(scope.contains("(a=b)"));
+ assertNotNull(scope.contains("(c=d)"));
+ break;
+ case 5:
+ assertEquals("remove failed", 1, scope.size());
+ assertEquals("(c=d)", scope.get(0));
+ break;
+ default:
+ assertTrue("This should not happen!", false);
+ }
+ return null;
+ }
+ }).atLeastOnce();
+
+ c.replay();
+
+ EndpointListenerManager endpointListener = new EndpointListenerManager(bc, tm);
+
+ endpointListener.start();
+
+ testCase = 1;
+ endpointListener.extendScope("(a=b)");
+ testCase = 2;
+ endpointListener.reduceScope("(a=b)");
+
+ testCase = 3;
+ endpointListener.extendScope("(a=b)");
+ testCase = 4;
+ endpointListener.extendScope("(c=d)");
+ testCase = 5;
+ endpointListener.reduceScope("(a=b)");
+
+ endpointListener.stop();
+
+ c.verify();
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImplTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImplTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImplTest.java
new file mode 100644
index 0000000..efd9202
--- /dev/null
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImplTest.java
@@ -0,0 +1,91 @@
+/**
+ * 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.aries.rsa.topologymanager.importer;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.aries.rsa.topologymanager.importer.ListenerHookImpl;
+import org.apache.aries.rsa.topologymanager.importer.ServiceInterestListener;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.hooks.service.ListenerHook.ListenerInfo;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ListenerHookImplTest {
+
+ @Test
+ public void testExtendFilter() throws InvalidSyntaxException {
+ String filter = "(a=b)";
+ BundleContext bc = createBundleContext();
+ filter = new ListenerHookImpl(bc, null).extendFilter(filter);
+
+ Filter f = FrameworkUtil.createFilter(filter);
+
+ Dictionary<String, String> m = new Hashtable<String, String>();
+ m.put("a", "b");
+ assertTrue(filter + " filter must match as uuid is missing", f.match(m));
+ m.put(RemoteConstants.ENDPOINT_FRAMEWORK_UUID, "MyUUID");
+ assertFalse(filter + " filter must NOT match as uuid is the local one", f.match(m));
+ }
+
+ @Test
+ public void testAddedRemoved() throws InvalidSyntaxException {
+ IMocksControl c = EasyMock.createControl();
+ String filter = "(objectClass=My)";
+ BundleContext bc = createBundleContext();
+ BundleContext listenerBc = createBundleContext();
+ ServiceInterestListener serviceInterestListener = c.createMock(ServiceInterestListener.class);
+ ListenerHookImpl listenerHook = new ListenerHookImpl(bc, serviceInterestListener);
+
+ ListenerInfo listener = c.createMock(ListenerInfo.class);
+ EasyMock.expect(listener.getBundleContext()).andReturn(listenerBc);
+ EasyMock.expect(listener.getFilter()).andReturn(filter).atLeastOnce();
+
+ // Main assertions
+ serviceInterestListener.addServiceInterest(listenerHook.extendFilter(filter));
+ EasyMock.expectLastCall();
+ serviceInterestListener.removeServiceInterest(listenerHook.extendFilter(filter));
+ EasyMock.expectLastCall();
+
+ Collection<ListenerInfo> listeners = Collections.singletonList(listener);
+
+ c.replay();
+ listenerHook.added(listeners);
+ listenerHook.removed(listeners);
+ c.verify();
+ }
+
+ private BundleContext createBundleContext() {
+ BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+ EasyMock.expect(bc.getProperty(EasyMock.eq("org.osgi.framework.uuid"))).andReturn("MyUUID").atLeastOnce();
+ EasyMock.replay(bc);
+ return bc;
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/ReferenceCounterTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/ReferenceCounterTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/ReferenceCounterTest.java
new file mode 100644
index 0000000..9b58288
--- /dev/null
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/ReferenceCounterTest.java
@@ -0,0 +1,44 @@
+/**
+ * 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.aries.rsa.topologymanager.importer;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.aries.rsa.topologymanager.importer.ReferenceCounter;
+
+public class ReferenceCounterTest {
+
+ @Test
+ public void testCounter() {
+ ReferenceCounter<String> counter = new ReferenceCounter<String>();
+ assertEquals(-1, counter.remove("a"));
+ assertEquals(-1, counter.remove("a"));
+ assertEquals(1, counter.add("a"));
+ assertEquals(2, counter.add("a"));
+ assertEquals(3, counter.add("a"));
+ assertEquals(2, counter.remove("a"));
+ assertEquals(1, counter.remove("a"));
+ assertEquals(2, counter.add("a"));
+ assertEquals(1, counter.remove("a"));
+ assertEquals(0, counter.remove("a"));
+ assertEquals(-1, counter.remove("a"));
+ }
+}