cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From amic...@apache.org
Subject svn commit: r1490228 - in /cxf/dosgi/trunk/dsw/cxf-topology-manager/src: main/java/org/apache/cxf/dosgi/topologymanager/ main/java/org/apache/cxf/dosgi/topologymanager/exporter/ main/java/org/apache/cxf/dosgi/topologymanager/importer/ main/java/org/apa...
Date Thu, 06 Jun 2013 10:20:46 GMT
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);
+    }
+}



Mime
View raw message