Author: amichai
Date: Thu Jun 6 10:20:45 2013
New Revision: 1490228
URL: http://svn.apache.org/r1490228
Log:
DOSGI-161 Fix services not exported due to tracker misuse
Added:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTracker.java
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerListener.java
- copied, changed from r1489675,
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/rsatracker/RemoteServiceAdminLifeCycleListener.java
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/util/
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerTest.java
Removed:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/rsatracker/RemoteServiceAdminLifeCycleListener.java
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/rsatracker/RemoteServiceAdminTracker.java
Modified:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/Activator.java
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/exporter/ExportServiceTest.java
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImportTest.java
Modified:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/Activator.java
URL:
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/Activator.java?rev=1490228&r1=1490227&r2=1490228&view=diff
==============================================================================
---
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/Activator.java
(original)
+++
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/Activator.java
Thu Jun 6 10:20:45 2013
@@ -20,9 +20,10 @@ package org.apache.cxf.dosgi.topologyman
import org.apache.cxf.dosgi.topologymanager.exporter.TopologyManagerExport;
import org.apache.cxf.dosgi.topologymanager.importer.TopologyManagerImport;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTracker;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,26 +31,25 @@ public class Activator implements Bundle
private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
- private TopologyManagerExport topManager;
- private TopologyManagerImport topManagerImport;
-
- private RemoteServiceAdminTracker rsaTracker;
+ private TopologyManagerExport topologyManagerExport;
+ private TopologyManagerImport topologyManagerImport;
+ private SimpleServiceTracker<RemoteServiceAdmin> rsaTracker;
public void start(BundleContext bc) throws Exception {
LOG.debug("TopologyManager: start()");
- rsaTracker = new RemoteServiceAdminTracker(bc);
- topManager = new TopologyManagerExport(bc, rsaTracker);
- topManagerImport = new TopologyManagerImport(bc, rsaTracker);
+ rsaTracker = new SimpleServiceTracker<RemoteServiceAdmin>(bc,
RemoteServiceAdmin.class);
+ topologyManagerExport = new TopologyManagerExport(bc, rsaTracker);
+ topologyManagerImport = new TopologyManagerImport(bc, rsaTracker);
rsaTracker.open();
- topManager.start();
- topManagerImport.start();
+ topologyManagerExport.start();
+ topologyManagerImport.start();
}
public void stop(BundleContext bc) throws Exception {
LOG.debug("TopologyManager: stop()");
- topManager.stop();
- topManagerImport.stop();
+ topologyManagerExport.stop();
+ topologyManagerImport.stop();
rsaTracker.close();
}
}
Modified:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java
URL:
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java?rev=1490228&r1=1490227&r2=1490228&view=diff
==============================================================================
---
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java
(original)
+++
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/exporter/TopologyManagerExport.java
Thu Jun 6 10:20:45 2013
@@ -26,8 +26,8 @@ import java.util.concurrent.LinkedBlocki
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminLifeCycleListener;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTrackerListener;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
@@ -61,33 +61,34 @@ public class TopologyManagerExport {
private final BundleContext bctx;
private final EndpointListenerNotifier epListenerNotifier;
private final ExecutorService execService;
- private final RemoteServiceAdminTracker remoteServiceAdminTracker;
+ private final SimpleServiceTracker<RemoteServiceAdmin>
remoteServiceAdminTracker;
private final ServiceListener serviceListener;
private final EndpointRepository endpointRepo;
- public TopologyManagerExport(BundleContext ctx, RemoteServiceAdminTracker
rsaTracker) {
+ public TopologyManagerExport(BundleContext ctx,
SimpleServiceTracker<RemoteServiceAdmin> rsaTracker) {
this(ctx, rsaTracker, null);
}
- public TopologyManagerExport(BundleContext ctx, RemoteServiceAdminTracker
rsaTracker,
+
+ public TopologyManagerExport(BundleContext ctx,
SimpleServiceTracker<RemoteServiceAdmin> rsaTracker,
EndpointListenerNotifier notif) {
endpointRepo = new EndpointRepository();
- if (notif == null) {
- epListenerNotifier = new EndpointListenerNotifier(ctx,
endpointRepo);
- } else {
- epListenerNotifier = notif;
- }
+ epListenerNotifier = notif == null ? new EndpointListenerNotifier(ctx,
endpointRepo) : notif;
execService = new ThreadPoolExecutor(5, 10, 50, TimeUnit.SECONDS, new
LinkedBlockingQueue<Runnable>());
bctx = ctx;
this.remoteServiceAdminTracker = rsaTracker;
- this.remoteServiceAdminTracker.addListener(new
RemoteServiceAdminLifeCycleListener() {
+ this.remoteServiceAdminTracker.addListener(new
SimpleServiceTrackerListener<RemoteServiceAdmin>() {
public void added(RemoteServiceAdmin rsa) {
+ LOG.debug("RemoteServiceAdmin added: {}, total {}",
+ rsa,
remoteServiceAdminTracker.getAllServices().size());
for (ServiceReference serviceRef :
endpointRepo.getServicesToBeExportedFor(rsa)) {
triggerExport(serviceRef);
}
}
public void removed(RemoteServiceAdmin rsa) {
+ LOG.debug("RemoteServiceAdmin removed: {}, total {}", rsa,
+ remoteServiceAdminTracker.getAllServices().size());
List<EndpointDescription> endpoints =
endpointRepo.removeRemoteServiceAdmin(rsa);
epListenerNotifier.notifyListeners(false, endpoints);
}
@@ -138,8 +139,9 @@ public class TopologyManagerExport {
}
protected void doExportService(final ServiceReference sref) {
- endpointRepo.addService(sref);
- List<RemoteServiceAdmin> rsaList = remoteServiceAdminTracker.getList();
+ LOG.debug("Exporting service");
+ endpointRepo.addService(sref); // mark for future export even if there
are currently no RSAs
+ List<RemoteServiceAdmin> rsaList =
remoteServiceAdminTracker.getAllServices();
if (rsaList.isEmpty()) {
LOG.error("No RemoteServiceAdmin available! Unable to export
service from bundle {}, interfaces: {}",
sref.getBundle().getSymbolicName(),
Modified:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java
URL:
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java?rev=1490228&r1=1490227&r2=1490228&view=diff
==============================================================================
---
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java
(original)
+++
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImport.java
Thu Jun 6 10:20:45 2013
@@ -29,8 +29,8 @@ import java.util.concurrent.LinkedBlocki
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminLifeCycleListener;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTrackerListener;
import org.osgi.framework.BundleContext;
import org.osgi.framework.hooks.service.ListenerHook;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
@@ -56,7 +56,7 @@ public class TopologyManagerImport imple
private final EndpointListenerManager endpointListenerManager;
private final BundleContext bctx;
- private final RemoteServiceAdminTracker remoteServiceAdminTracker;
+ private final SimpleServiceTracker<RemoteServiceAdmin>
remoteServiceAdminTracker;
private final ListenerHookImpl listenerHook;
/**
@@ -87,10 +87,10 @@ public class TopologyManagerImport imple
private final Map<String /* filter */, List<ImportRegistration>>
importedServices
= new HashMap<String, List<ImportRegistration>>();
- public TopologyManagerImport(BundleContext bc, RemoteServiceAdminTracker
rsaTracker) {
+ public TopologyManagerImport(BundleContext bc,
SimpleServiceTracker<RemoteServiceAdmin> rsaTracker) {
bctx = bc;
remoteServiceAdminTracker = rsaTracker;
- remoteServiceAdminTracker.addListener(new
RemoteServiceAdminLifeCycleListener() {
+ remoteServiceAdminTracker.addListener(new
SimpleServiceTrackerListener<RemoteServiceAdmin>() {
public void added(RemoteServiceAdmin rsa) {
triggerImportsForRemoteServiceAdmin(rsa);
@@ -187,7 +187,7 @@ public class TopologyManagerImport imple
}
public void triggerImportsForRemoteServiceAdmin(RemoteServiceAdmin rsa) {
- LOG.debug("New RSA detected trying to import services with it");
+ LOG.debug("New RemoteServiceAdmin {} detected, trying to import
services with it", rsa);
synchronized (importPossibilities) {
for (String filter : importPossibilities.keySet()) {
triggerImport(filter);
@@ -295,7 +295,7 @@ public class TopologyManagerImport imple
* @return import registration of the first successful import
*/
private ImportRegistration importService(EndpointDescription ep) {
- for (RemoteServiceAdmin rsa : remoteServiceAdminTracker.getList()) {
+ for (RemoteServiceAdmin rsa :
remoteServiceAdminTracker.getAllServices()) {
ImportRegistration ir = rsa.importService(ep);
if (ir != null && ir.getException() == null) {
LOG.debug("Service import was successful {}", ir);
Added:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTracker.java
URL:
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTracker.java?rev=1490228&view=auto
==============================================================================
---
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTracker.java
(added)
+++
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTracker.java
Thu Jun 6 10:20:45 2013
@@ -0,0 +1,121 @@
+/**
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * A {@link ServiceTracker} extension that simplifies its usage.
+ * <p>
+ * It enhances {@code ServiceTracker} by adding:
+ * <ul>
+ * <li>Multiple event listeners for service add/remove events
+ * <li>Simpler event callbacks that do not need to deal with getting/ungetting
+ * services, calling super methods or returning service objects
+ * <li>Generics support, which means the callback and {@code getList()} methods
+ * are type-safe and require no casting
+ * <li>A {@link #getAllServices()} method which returns all currently tracked
services;
+ * Unlike {@link ServiceTracker#getServices()}, if it is called from
within a service
+ * {@link SimpleServiceTrackerListener#added added} event handler, the
returned list
+ * will include the newly added service (this is the source of several
bugs when using
+ * the original {@code getServices()})
+ * </ul>
+ *
+ * @param <T> the service interface type
+ */
+public class SimpleServiceTracker<T> extends ServiceTracker {
+
+ // we must use a map with references as keys, so as not to invoke equals
remotely on service objects
+ private ConcurrentMap<ServiceReference, T> services;
+ private List<SimpleServiceTrackerListener<T>> listeners;
+
+ /**
+ * Create a <code>SimpleServiceTracker</code> on the specified class' name.
+ * <p>
+ * Services registered under the specified class' name will be tracked by
+ * this <code>SimpleServiceTracker</code>.
+ *
+ * @param context the {@code BundleContext} against which the tracking is
done
+ * @param clazz the class of the services to be tracked
+ */
+ public SimpleServiceTracker(BundleContext context, Class<T> clazz) {
+ super(context, clazz.getName(), null);
+ this.listeners = new
CopyOnWriteArrayList<SimpleServiceTrackerListener<T>>();
+ this.services = new ConcurrentHashMap<ServiceReference, T>();
+ }
+
+ /**
+ * Adds a listener to be notified of services added or removed.
+ *
+ * @param listener the listener to add
+ */
+ public void addListener(SimpleServiceTrackerListener<T> listener) {
+ listeners.add(listener);
+ }
+
+ @Override
+ public Object addingService(ServiceReference reference) {
+ @SuppressWarnings("unchecked")
+ T service = (T) super.addingService(reference);
+ services.put(reference, service);
+ for (SimpleServiceTrackerListener<T> listener : listeners) {
+ listener.added(service);
+ }
+ return service;
+ }
+
+ @Override
+ public void removedService(ServiceReference reference, Object
serviceObject) {
+ @SuppressWarnings("unchecked")
+ T service = (T) serviceObject;
+ services.remove(reference, service);
+ for (SimpleServiceTrackerListener<T> listener : listeners) {
+ listener.removed(service);
+ }
+ super.removedService(reference, service);
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ services.clear();
+ }
+
+ /**
+ * Returns all currently tracked services.
+ * <p>
+ * Unlike {@link ServiceTracker#getServices()}, if it is called from
within a service
+ * {@link SimpleServiceTrackerListener#added added} event handler, the
returned list
+ * will include the newly added service.
+ *
+ * @return all currently tracked services
+ */
+ @SuppressWarnings("unchecked")
+ public List<T> getAllServices() {
+ return new ArrayList<T>(services.values());
+ }
+}
Copied:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerListener.java
(from r1489675,
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/rsatracker/RemoteServiceAdminLifeCycleListener.java)
URL:
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerListener.java?p2=cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerListener.java&p1=cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/rsatracker/RemoteServiceAdminLifeCycleListener.java&r1=1489675&r2=1490228&rev=1490228&view=diff
==============================================================================
---
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/rsatracker/RemoteServiceAdminLifeCycleListener.java
(original)
+++
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/main/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerListener.java
Thu Jun 6 10:20:45 2013
@@ -16,15 +16,27 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.cxf.dosgi.topologymanager.rsatracker;
-
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
+package org.apache.cxf.dosgi.topologymanager.util;
/**
- * Callback interface to be notified of RemoteServiceAdmin services that are
added or removed
+ * Callback interface for notifications of services that are
+ * added to or removed from tracking by a {@link SimpleServiceTracker}.
+ *
+ * @param <T> the service interface type
*/
-public interface RemoteServiceAdminLifeCycleListener {
+public interface SimpleServiceTrackerListener<T> {
+
+ /**
+ * Called when a new service is added to the tracked services.
+ *
+ * @param service the newly added service
+ */
+ void added(T service);
- void added(RemoteServiceAdmin rsa);
- void removed(RemoteServiceAdmin rsa);
+ /**
+ * Called when a service is removed from the tracked services.
+ *
+ * @param service the removed service
+ */
+ void removed(T service);
}
Modified:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/exporter/ExportServiceTest.java
URL:
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/exporter/ExportServiceTest.java?rev=1490228&r1=1490227&r2=1490228&view=diff
==============================================================================
---
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/exporter/ExportServiceTest.java
(original)
+++
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/exporter/ExportServiceTest.java
Thu Jun 6 10:20:45 2013
@@ -22,8 +22,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminLifeCycleListener;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTrackerListener;
import org.easymock.IAnswer;
import org.easymock.classextension.EasyMock;
import org.easymock.classextension.IMocksControl;
@@ -66,7 +66,7 @@ public class ExportServiceTest {
.expect(bctx.getServiceReferences(EasyMock.<String> anyObject(),
EasyMock.<String> anyObject()))
.andReturn(null).atLeastOnce();
- RemoteServiceAdminTracker rsaTracker = createSingleRsaTracker(c, rsa);
+ SimpleServiceTracker<RemoteServiceAdmin> rsaTracker =
createSingleRsaTracker(c, rsa);
EndpointDescription endpoint = createEndpoint(c);
ExportRegistration exportRegistration = createExportRegistration(c,
endpoint);
@@ -81,9 +81,7 @@ public class ExportServiceTest {
c.replay();
TopologyManagerExport topManager = new TopologyManagerExport(bctx,
rsaTracker, mockEpListenerNotifier) {
- /**
- * To avoid async call
- */
+ // override to perform export from the same thread rather than
asynchronously
@Override
protected void triggerExport(ServiceReference sref) {
doExportService(sref);
@@ -106,11 +104,11 @@ public class ExportServiceTest {
}).once();
}
- private RemoteServiceAdminTracker createSingleRsaTracker(IMocksControl c,
RemoteServiceAdmin rsa) {
- RemoteServiceAdminTracker rsaTracker =
c.createMock(RemoteServiceAdminTracker.class);
- rsaTracker.addListener(EasyMock.<RemoteServiceAdminLifeCycleListener>
anyObject());
+ private SimpleServiceTracker<RemoteServiceAdmin>
createSingleRsaTracker(IMocksControl c, RemoteServiceAdmin rsa) {
+ SimpleServiceTracker<RemoteServiceAdmin> rsaTracker =
c.createMock(SimpleServiceTracker.class);
+ rsaTracker.addListener(EasyMock.<SimpleServiceTrackerListener>
anyObject());
EasyMock.expectLastCall().once();
-
EasyMock.expect(rsaTracker.getList()).andReturn(Collections.singletonList(rsa));
+
EasyMock.expect(rsaTracker.getAllServices()).andReturn(Collections.singletonList(rsa));
return rsaTracker;
}
Modified:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImportTest.java
URL:
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImportTest.java?rev=1490228&r1=1490227&r2=1490228&view=diff
==============================================================================
---
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImportTest.java
(original)
+++
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/importer/TopologyManagerImportTest.java
Thu Jun 6 10:20:45 2013
@@ -23,8 +23,8 @@ import java.util.Dictionary;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminLifeCycleListener;
-import
org.apache.cxf.dosgi.topologymanager.rsatracker.RemoteServiceAdminTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTracker;
+import org.apache.cxf.dosgi.topologymanager.util.SimpleServiceTrackerListener;
import org.easymock.IAnswer;
import org.easymock.IMocksControl;
import org.easymock.classextension.EasyMock;
@@ -50,7 +50,7 @@ public class TopologyManagerImportTest {
final Semaphore sema = new Semaphore(0);
BundleContext bc = c.createMock(BundleContext.class);
- RemoteServiceAdminTracker rsaTracker =
c.createMock(RemoteServiceAdminTracker.class);
+ SimpleServiceTracker<RemoteServiceAdmin> rsaTracker =
c.createMock(SimpleServiceTracker.class);
ServiceRegistration sreg = c.createMock(ServiceRegistration.class);
sreg.unregister();
EasyMock.expectLastCall().once();
@@ -64,8 +64,8 @@ public class TopologyManagerImportTest {
EasyMock.expect(ireg.getException()).andReturn(null).anyTimes();
ImportReference iref = c.createMock(ImportReference.class);
-
rsaTracker.addListener(EasyMock.<RemoteServiceAdminLifeCycleListener>anyObject());
-
EasyMock.expect(rsaTracker.getList()).andReturn(Arrays.asList(rsa)).anyTimes();
+
rsaTracker.addListener(EasyMock.<SimpleServiceTrackerListener>anyObject());
+
EasyMock.expect(rsaTracker.getAllServices()).andReturn(Arrays.asList(rsa)).anyTimes();
EasyMock.expect(rsa.importService(EasyMock.eq(epd))).andAnswer(new
IAnswer<ImportRegistration>() {
public ImportRegistration answer() throws Throwable {
Added:
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerTest.java
URL:
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerTest.java?rev=1490228&view=auto
==============================================================================
---
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerTest.java
(added)
+++
cxf/dosgi/trunk/dsw/cxf-topology-manager/src/test/java/org/apache/cxf/dosgi/topologymanager/util/SimpleServiceTrackerTest.java
Thu Jun 6 10:20:45 2013
@@ -0,0 +1,157 @@
+/**
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import org.easymock.Capture;
+import org.easymock.IAnswer;
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+public class SimpleServiceTrackerTest {
+
+ private ServiceReference createUserServiceBundle(IMocksControl c,
BundleContext context) {
+ final ServiceReference sref = c.createMock(ServiceReference.class);
+ Bundle srefBundle = c.createMock(Bundle.class);
+ expect(srefBundle.getBundleContext()).andReturn(context).anyTimes();
+ expect(sref.getBundle()).andReturn(srefBundle).anyTimes();
+
expect(srefBundle.getSymbolicName()).andReturn("serviceBundleName").anyTimes();
+ return sref;
+ }
+
+ private static <T> void assertEqualsUnordered(Collection<T> c1,
Collection<T> c2) {
+ assertEquals(new HashSet<T>(c1), new HashSet<T>(c2));
+ }
+
+ @Test
+ public void testTracker() throws InvalidSyntaxException {
+ IMocksControl c = org.easymock.classextension.EasyMock.createControl();
+ // create context mock
+ BundleContext context = c.createMock(BundleContext.class);
+ // capture service listener so we can invoke it
+ Capture<ServiceListener> capturedListener = new
Capture<ServiceListener>();
+
context.addServiceListener(EasyMock.<ServiceListener>capture(capturedListener),
(String)anyObject());
+ expectLastCall().once();
+ context.removeServiceListener((ServiceListener)anyObject());
+ expectLastCall().once();
+ // support context.createFilter
+ Filter filter = c.createMock(Filter.class);
+
expect(context.createFilter("(objectClass=org.osgi.service.remoteserviceadmin.RemoteServiceAdmin)"))
+ .andReturn(filter).atLeastOnce();
+ // support context.getServiceReferences based on our list
+ final List<RemoteServiceAdmin> services = new
ArrayList<RemoteServiceAdmin>();
+ final List<ServiceReference> srefs = new ArrayList<ServiceReference>();
+ expect(context.getServiceReferences((String)anyObject(),
eq((String)null))).andAnswer(
+ new IAnswer<ServiceReference[]>() {
+ @Override
+ public ServiceReference[] answer() {
+ return srefs.toArray(new ServiceReference[srefs.size()]);
+ }
+ });
+ // create services
+ ServiceReference sref1 = createUserServiceBundle(c, context);
+ ServiceReference sref2 = createUserServiceBundle(c, context);
+ RemoteServiceAdmin service1 = c.createMock(RemoteServiceAdmin.class);
+ RemoteServiceAdmin service2 = c.createMock(RemoteServiceAdmin.class);
+ expect(context.getService(sref1)).andReturn(service1).atLeastOnce();
+ expect(context.getService(sref2)).andReturn(service2).atLeastOnce();
+ expect(context.ungetService(sref1)).andReturn(false).atLeastOnce();
+ expect(context.ungetService(sref2)).andReturn(false).atLeastOnce();
+
+ replay(context);
+
+ // start tracking
+ final SimpleServiceTracker<RemoteServiceAdmin> tracker =
+ new SimpleServiceTracker<RemoteServiceAdmin>(context,
RemoteServiceAdmin.class);
+ tracker.open();
+ ServiceListener sl = capturedListener.getValue();
+ // add our listener
+ SimpleServiceTrackerListener<RemoteServiceAdmin> listener =
+ new SimpleServiceTrackerListener<RemoteServiceAdmin>() {
+ @Override
+ @SuppressWarnings("unchecked")
+ public void added(RemoteServiceAdmin service) {
+ // prove that original ServiceTracker fails here
+ Object[] trackerServices = tracker.getServices() != null ?
tracker.getServices() : new Object[0];
+ assertFalse(new HashSet(services).equals(new
HashSet(Arrays.asList(trackerServices))));
+ // but we succeed
+ assertEqualsUnordered(services, tracker.getAllServices());
+ }
+
+ @Override
+ public void removed(RemoteServiceAdmin service) {
+ assertEqualsUnordered(services, tracker.getAllServices());
+ }
+ };
+ tracker.addListener(listener);
+
+ // add and remove services and verify that getAllServices() is up to
date
+ srefs.add(sref1);
+ services.add(service1);
+ sl.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref1));
+ assertEqualsUnordered(services, tracker.getAllServices());
+
+ srefs.add(sref2);
+ services.add(service2);
+ sl.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref2));
+ assertEqualsUnordered(services, tracker.getAllServices());
+
+ srefs.remove(sref1);
+ services.remove(service1);
+ sl.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, sref1));
+ assertEqualsUnordered(services, tracker.getAllServices());
+
+ srefs.remove(sref2);
+ services.remove(service2);
+ sl.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, sref2));
+ assertEqualsUnordered(services, tracker.getAllServices());
+
+ srefs.add(sref1);
+ services.add(service1);
+ sl.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref1));
+ services.remove(service1);
+ tracker.close();
+ assertEqualsUnordered(services, tracker.getAllServices());
+
+ verify(context);
+ }
+}