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 2018/01/31 10:46:03 UTC

[1/2] aries-rsa git commit: [ARIES-1763] Support both EndpointListener and EndpointEventListener in TopologyManager export

Repository: aries-rsa
Updated Branches:
  refs/heads/master 2693bb8ff -> d6b354daf


[ARIES-1763] Support both EndpointListener and EndpointEventListener in TopologyManager export


Project: http://git-wip-us.apache.org/repos/asf/aries-rsa/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-rsa/commit/3f77941e
Tree: http://git-wip-us.apache.org/repos/asf/aries-rsa/tree/3f77941e
Diff: http://git-wip-us.apache.org/repos/asf/aries-rsa/diff/3f77941e

Branch: refs/heads/master
Commit: 3f77941e114ed174ed9dd0775a46924a063e7375
Parents: 2693bb8
Author: Christian Schneider <cs...@adobe.com>
Authored: Tue Jan 30 18:12:26 2018 +0100
Committer: Christian Schneider <cs...@adobe.com>
Committed: Tue Jan 30 18:12:26 2018 +0100

----------------------------------------------------------------------
 .../aries/rsa/topologymanager/Activator.java    | 37 +++++++-
 .../exporter/EndpointListenerAdapter.java       | 70 +++++++++++++++
 .../exporter/EndpointListenerNotifier.java      | 84 +++++++++---------
 .../exporter/EndpointRepository.java            | 13 +--
 .../importer/TopologyManagerImport.java         | 14 +--
 .../exporter/EndpointListenerNotifierTest.java  | 25 +++---
 .../exporter/EndpointRepositoryTest.java        | 24 ++---
 .../RecordingEndpointEventListener.java         | 48 ++++++++++
 .../exporter/TopologyManagerExportTest.java     | 92 ++++++++------------
 .../importer/TopologyManagerImportTest.java     |  1 +
 10 files changed, 274 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java
index 97378a8..e67b5a1 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/Activator.java
@@ -38,6 +38,7 @@ import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
 import org.osgi.service.remoteserviceadmin.EndpointListener;
 import org.osgi.service.remoteserviceadmin.RemoteConstants;
 import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
@@ -46,6 +47,7 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@SuppressWarnings("deprecation")
 public class Activator implements BundleActivator {
     public static final String RSA_EXPORT_POLICY_FILTER = "rsa.export.policy.filter";
     static final String DOSGI_SERVICES = "(" + RemoteConstants.SERVICE_EXPORTED_INTERFACES + "=*)";
@@ -56,9 +58,11 @@ public class Activator implements BundleActivator {
     private EndpointListenerNotifier notifier;
     private ServiceTracker<RemoteServiceAdmin, RemoteServiceAdmin> rsaTracker;
     private ThreadPoolExecutor exportExecutor;
+    
     private ServiceTracker<EndpointListener, EndpointListener> epListenerTracker;
     private ServiceTracker<ExportPolicy, ExportPolicy> policyTracker;
     private EndpointListenerManager endpointListenerManager;
+    private EndpointEventListenerTracker epeListenerTracker;
 
     public void start(final BundleContext bc) throws Exception {
         Dictionary<String, String> props = new Hashtable<String, String>();
@@ -101,6 +105,7 @@ public class Activator implements BundleActivator {
         EndpointRepository endpointRepo = new EndpointRepository();
         notifier = new EndpointListenerNotifier(endpointRepo);
         epListenerTracker = new EndpointListenerTracker(bc);
+        epeListenerTracker = new EndpointEventListenerTracker(bc);
         endpointRepo.setNotifier(notifier);
         exportExecutor = new ThreadPoolExecutor(5, 10, 50, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
         exportManager = new TopologyManagerExport(endpointRepo, exportExecutor, policy);
@@ -111,6 +116,7 @@ public class Activator implements BundleActivator {
         bc.addServiceListener(exportManager);
         rsaTracker.open();
         epListenerTracker.open();
+        epeListenerTracker.open();
         exportExistingServices(bc);
         importManager.start();
     }
@@ -152,7 +158,7 @@ public class Activator implements BundleActivator {
         @Override
         public EndpointListener addingService(ServiceReference<EndpointListener> reference) {
             EndpointListener listener = super.addingService(reference);
-            notifier.add(listener, EndpointListenerNotifier.getFiltersFromEndpointListenerScope(reference));
+            notifier.add(listener, EndpointListenerNotifier.filtersFromEL(reference));
             return listener;
         }
 
@@ -160,7 +166,7 @@ public class Activator implements BundleActivator {
         public void modifiedService(ServiceReference<EndpointListener> reference,
                                     EndpointListener listener) {
             super.modifiedService(reference, listener);
-            notifier.add(listener, EndpointListenerNotifier.getFiltersFromEndpointListenerScope(reference));
+            notifier.add(listener, EndpointListenerNotifier.filtersFromEL(reference));
         }
 
         @Override
@@ -170,6 +176,33 @@ public class Activator implements BundleActivator {
             super.removedService(reference, listener);
         }
     }
+    
+    private final class EndpointEventListenerTracker extends ServiceTracker<EndpointEventListener, EndpointEventListener> {
+        private EndpointEventListenerTracker(BundleContext context) {
+            super(context, EndpointEventListener.class, null);
+        }
+
+        @Override
+        public EndpointEventListener addingService(ServiceReference<EndpointEventListener> reference) {
+            EndpointEventListener listener = super.addingService(reference);
+            notifier.add(listener, EndpointListenerNotifier.filtersFromEEL(reference));
+            return listener;
+        }
+
+        @Override
+        public void modifiedService(ServiceReference<EndpointEventListener> reference,
+                EndpointEventListener listener) {
+            super.modifiedService(reference, listener);
+            notifier.add(listener, EndpointListenerNotifier.filtersFromEEL(reference));
+        }
+
+        @Override
+        public void removedService(ServiceReference<EndpointEventListener> reference,
+                EndpointEventListener listener) {
+            notifier.remove(listener);
+            super.removedService(reference, listener);
+        }
+    }
 
     private final class RSATracker extends ServiceTracker<RemoteServiceAdmin, RemoteServiceAdmin> {
         private RSATracker(BundleContext context, Class<RemoteServiceAdmin> clazz,

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerAdapter.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerAdapter.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerAdapter.java
new file mode 100644
index 0000000..0e0e1cc
--- /dev/null
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerAdapter.java
@@ -0,0 +1,70 @@
+/**
+ * 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 org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.EndpointEvent;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
+import org.osgi.service.remoteserviceadmin.EndpointListener;
+
+/**
+ * Wraps on old style EndpointListener into the new
+ * EndpointEventListener interface
+ */
+@SuppressWarnings("deprecation")
+class EndpointListenerAdapter implements EndpointEventListener {
+    private EndpointListener epl;
+
+    public EndpointListenerAdapter(EndpointListener epl) {
+        this.epl = epl;
+    }
+
+    @Override
+    public void endpointChanged(EndpointEvent event, String filter) {
+        EndpointDescription endpoint = event.getEndpoint();
+        switch (event.getType()) {
+        case EndpointEvent.ADDED:
+            epl.endpointAdded(endpoint, filter);
+            break;
+        case EndpointEvent.REMOVED:
+            epl.endpointRemoved(endpoint, filter);
+            break;
+        case EndpointEvent.MODIFIED:
+            epl.endpointRemoved(endpoint, filter);
+            epl.endpointAdded(endpoint, filter);
+            break;
+        case EndpointEvent.MODIFIED_ENDMATCH:
+            epl.endpointRemoved(endpoint, filter);
+            break;
+        }
+    }
+    
+    /**
+     * Checks for equality of the adapted EndpointListener
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof EndpointListenerAdapter) {
+            EndpointListenerAdapter ela = (EndpointListenerAdapter)obj;
+            return epl.equals(ela.epl);
+        } else {
+            return super.equals(obj);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java
index 18a8ea2..7864bb4 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointListenerNotifier.java
@@ -32,6 +32,8 @@ 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.EndpointEvent;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
 import org.osgi.service.remoteserviceadmin.EndpointListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,20 +41,29 @@ import org.slf4j.LoggerFactory;
 /**
  * Tracks EndpointListeners and allows to notify them of endpoints.
  */
-public class EndpointListenerNotifier implements EndpointListener {
+@SuppressWarnings("deprecation")
+public class EndpointListenerNotifier implements EndpointEventListener {
     private static final Logger LOG = LoggerFactory.getLogger(EndpointListenerNotifier.class);
-    private enum NotifyType { ADDED, REMOVED };
-    private Map<EndpointListener, Set<Filter>> listeners;
+    private Map<EndpointEventListener, Set<Filter>> listeners;
     private EndpointRepository endpointRepo;
 
     public EndpointListenerNotifier(final EndpointRepository endpointRepo) {
         this.endpointRepo = endpointRepo;
-        this.listeners = new ConcurrentHashMap<EndpointListener, Set<Filter>>();
+        this.listeners = new ConcurrentHashMap<EndpointEventListener, Set<Filter>>();
+    }
+   
+    public static Set<Filter> filtersFromEL(ServiceReference<EndpointListener> sref) {
+        List<String> scopes = StringPlus.normalize(sref.getProperty(EndpointListener.ENDPOINT_LISTENER_SCOPE));
+        return getFilterSet(scopes);
     }
     
-    public static Set<Filter> getFiltersFromEndpointListenerScope(ServiceReference<EndpointListener> sref) {
+    public static Set<Filter> filtersFromEEL(ServiceReference<EndpointEventListener> sref) {
+        List<String> scopes = StringPlus.normalize(sref.getProperty(EndpointEventListener.ENDPOINT_LISTENER_SCOPE));
+        return getFilterSet(scopes);
+    }
+
+    private static Set<Filter> getFilterSet(List<String> scopes) {
         Set<Filter> filters = new HashSet<Filter>();
-        List<String> scopes = StringPlus.normalize(sref.getProperty(EndpointListener.ENDPOINT_LISTENER_SCOPE));
         for (String scope : scopes) {
             try {
                 filters.add(FrameworkUtil.createFilter(scope));
@@ -65,37 +76,42 @@ public class EndpointListenerNotifier implements EndpointListener {
 
     public void add(EndpointListener ep, Set<Filter> filters) {
         LOG.debug("new EndpointListener detected");
-        listeners.put(ep, filters);
+        EndpointListenerAdapter adapter = new EndpointListenerAdapter(ep);
+        listeners.put(adapter, filters);
         for (EndpointDescription endpoint : endpointRepo.getAllEndpoints()) {
-            notifyListener(NotifyType.ADDED, ep, filters, endpoint);
+            EndpointEvent event = new EndpointEvent(EndpointEvent.ADDED, endpoint);
+            notifyListener(event, adapter, filters);
         }
     }
     
     public void remove(EndpointListener ep) {
         LOG.debug("EndpointListener modified");
-        listeners.remove(ep);
+        EndpointListenerAdapter adapter = new EndpointListenerAdapter(ep);
+        listeners.remove(adapter);
     }
     
-    @Override
-    public void endpointAdded(EndpointDescription endpoint, String matchedFilter) {
-        notifyListeners(NotifyType.ADDED, endpoint);
+    public void add(EndpointEventListener ep, Set<Filter> filters) {
+        LOG.debug("new EndpointListener detected");
+        listeners.put(ep, filters);
+        for (EndpointDescription endpoint : endpointRepo.getAllEndpoints()) {
+            EndpointEvent event = new EndpointEvent(EndpointEvent.ADDED, endpoint);
+            notifyListener(event, ep, filters);
+        }
     }
-
-    @Override
-    public void endpointRemoved(EndpointDescription endpoint, String matchedFilter) {
-        LOG.info("endpoint " + endpoint);
-        notifyListeners(NotifyType.REMOVED, endpoint);
+    
+    public void remove(EndpointEventListener ep) {
+        LOG.debug("EndpointListener modified");
+        listeners.remove(ep);
     }
-
+    
     /**
-     * Notifies all endpoint listeners about endpoints being added or removed.
-     *
-     * @param added specifies whether endpoints were added (true) or removed (false)
-     * @param endpoints the endpoints the listeners should be notified about
+     * NOTICE: filter will be ignored
      */
-    private void notifyListeners(NotifyType type, EndpointDescription endpoint) {
-        for (EndpointListener listener : listeners.keySet()) {
-            notifyListener(type, listener, listeners.get(listener), endpoint);
+    @Override
+    public void endpointChanged(EndpointEvent event, String filter) {
+        for (EndpointEventListener listener : listeners.keySet()) {
+            Set<Filter> filters = listeners.get(listener);
+            notifyListener(event, listener, filters);
         }
     }
 
@@ -106,21 +122,10 @@ public class EndpointListenerNotifier implements EndpointListener {
      * @param endpointListenerRef the ServiceReference of an EndpointListener to notify
      * @param endpoints the endpoints the listener should be notified about
      */
-    private void notifyListener(NotifyType type, EndpointListener listener, Set<Filter> filters, 
-                        EndpointDescription endpoint) {
-        if (endpoint == null) {
-            throw new NullPointerException("Endpoint should not be null");
-            //LOG.warn("Endpoint should not be null");
-            //return;
-        }
-        LOG.debug("Endpoint {}", type);
-        Set<Filter> matchingFilters = getMatchingFilters(filters, endpoint);
+    private void notifyListener(EndpointEvent event, EndpointEventListener listener, Set<Filter> filters) {
+        Set<Filter> matchingFilters = getMatchingFilters(filters, event.getEndpoint());
         for (Filter filter : matchingFilters) {
-            if (type == NotifyType.ADDED) {
-                listener.endpointAdded(endpoint, filter.toString());
-            } else {
-                listener.endpointRemoved(endpoint, filter.toString());
-            }
+            listener.endpointChanged(event, filter.toString());
         }
     }
     
@@ -140,5 +145,4 @@ public class EndpointListenerNotifier implements EndpointListener {
         }
         return matchingFilters;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java
index 5bebe4e..b02cbba 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/exporter/EndpointRepository.java
@@ -29,7 +29,8 @@ import java.util.Set;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.EndpointEvent;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
 import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,9 +48,9 @@ public class EndpointRepository {
     private final Map<ServiceReference, Map<RemoteServiceAdmin, Collection<EndpointDescription>>> exportedServices
         = new LinkedHashMap<ServiceReference, Map<RemoteServiceAdmin, Collection<EndpointDescription>>>();
 
-    private EndpointListener notifier;
+    private EndpointEventListener notifier;
     
-    public void setNotifier(EndpointListener notifier) {
+    public void setNotifier(EndpointEventListener notifier) {
         this.notifier = notifier;
     }
     
@@ -132,13 +133,15 @@ public class EndpointRepository {
 
     private void endpointsAdded(List<EndpointDescription> endpoints) {
         for (EndpointDescription epd : endpoints) {
-            notifier.endpointAdded(epd, null);
+            EndpointEvent event = new EndpointEvent(EndpointEvent.ADDED, epd);
+            notifier.endpointChanged(event, null);
         }
     }
     
     private void endpointsRemoved(List<EndpointDescription> endpoints) {
         for (EndpointDescription epd : endpoints) {
-            notifier.endpointRemoved(epd, null);
+            EndpointEvent event = new EndpointEvent(EndpointEvent.REMOVED, epd);
+            notifier.endpointChanged(event, null);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java
index 5129223..44746c8 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java
@@ -79,6 +79,10 @@ public class TopologyManagerImport implements EndpointEventListener, RemoteServi
     public void stop() {
         stopped = true;
         execService.shutdown();
+        try {
+            execService.awaitTermination(10, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+        }
         closeAllImports();
     }
 
@@ -92,7 +96,7 @@ public class TopologyManagerImport implements EndpointEventListener, RemoteServi
     public void add(RemoteServiceAdmin rsa) {
         rsaSet.add(rsa);
         for (String filter : importPossibilities.keySet()) {
-            triggerSyncImports(filter);
+            triggerSyncronizeImports(filter);
         }
     }
     
@@ -107,18 +111,18 @@ public class TopologyManagerImport implements EndpointEventListener, RemoteServi
         }
     }
 
-    private void triggerSyncImports(final String filter) {
+    private void triggerSyncronizeImports(final String filter) {
         LOG.debug("Import of a service for filter {} was queued", filter);
         if (!rsaSet.isEmpty()) {
             execService.execute(new Runnable() {
                 public void run() {
-                    syncImports(filter);
+                    syncronizeImports(filter);
                 }
             });
         }
     }
     
-    private void syncImports(final String filter) {
+    private void syncronizeImports(final String filter) {
         try {
             unImportForGoneEndpoints(filter);
             importServices(filter);
@@ -226,7 +230,7 @@ public class TopologyManagerImport implements EndpointEventListener, RemoteServi
                 importPossibilities.remove(filter, endpoint);
                 break;
         }
-        triggerSyncImports(filter);
+        triggerSyncronizeImports(filter);
     }
     
 }

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/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
index 6d7959a..ccbeecf 100644
--- 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
@@ -39,11 +39,12 @@ 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.EndpointEvent;
 import org.osgi.service.remoteserviceadmin.EndpointListener;
 import org.osgi.service.remoteserviceadmin.RemoteConstants;
 
 @SuppressWarnings({
-    "rawtypes", "unchecked"
+    "rawtypes", "unchecked", "deprecation"
    })
 public class EndpointListenerNotifierTest {
 
@@ -56,16 +57,16 @@ public class EndpointListenerNotifierTest {
         EndpointListener epl = listenerExpects(endpoint1, "(objectClass=myClass)");
 
         EndpointRepository exportRepository = new EndpointRepository();
-        EndpointListenerNotifier tm = new EndpointListenerNotifier(exportRepository);
+        EndpointListenerNotifier notifier = 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);
+        notifier.add(epl, filters);
+        notifier.endpointChanged(new EndpointEvent(EndpointEvent.ADDED, endpoint1), null);
+        notifier.endpointChanged(new EndpointEvent(EndpointEvent.ADDED, endpoint2), null);
+        notifier.endpointChanged(new EndpointEvent(EndpointEvent.REMOVED, endpoint1), null);
+        notifier.endpointChanged(new EndpointEvent(EndpointEvent.REMOVED, endpoint2), null);
         EasyMock.verify(epl);
     }
 
@@ -95,8 +96,8 @@ public class EndpointListenerNotifierTest {
         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.endpointChanged(new EndpointEvent(EndpointEvent.ADDED, endpoint1), null);
+        tm.endpointChanged(new EndpointEvent(EndpointEvent.REMOVED, endpoint1), null);
         tm.remove(epl);
         EasyMock.verify(epl);
     }
@@ -112,7 +113,7 @@ public class EndpointListenerNotifierTest {
     @Test
     public void testNormalizeScopeForSingleString() {
         ServiceReference sr = createListenerServiceWithFilter("(myProp=A)");
-        Set<Filter> res = EndpointListenerNotifier.getFiltersFromEndpointListenerScope(sr);
+        Set<Filter> res = EndpointListenerNotifier.filtersFromEL(sr);
         assertEquals(1, res.size());
         Filter filter = res.iterator().next();
         filterMatches(filter);
@@ -122,7 +123,7 @@ public class EndpointListenerNotifierTest {
     public void testNormalizeScopeForStringArray() {
         String[] filters = {"(myProp=A)", "(otherProp=B)"};
         ServiceReference sr = createListenerServiceWithFilter(filters); 
-        Set<Filter> res = EndpointListenerNotifier.getFiltersFromEndpointListenerScope(sr);
+        Set<Filter> res = EndpointListenerNotifier.filtersFromEL(sr);
         assertEquals(filters.length, res.size());
         Iterator<Filter> it = res.iterator();
         Filter filter1 = it.next();
@@ -136,7 +137,7 @@ public class EndpointListenerNotifierTest {
     public void testNormalizeScopeForCollection() {
         Collection<String> collection = Arrays.asList("(myProp=A)", "(otherProp=B)");
         ServiceReference sr = createListenerServiceWithFilter(collection);
-        Set<Filter> res = EndpointListenerNotifier.getFiltersFromEndpointListenerScope(sr);
+        Set<Filter> res = EndpointListenerNotifier.filtersFromEL(sr);
         Iterator<Filter> it = res.iterator();
         Filter filter1 = it.next();
         Filter filter2 = it.next();

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/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
index 59f1859..1b4941c 100644
--- 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
@@ -20,7 +20,6 @@ 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;
@@ -30,7 +29,7 @@ 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.EndpointEvent;
 import org.osgi.service.remoteserviceadmin.RemoteConstants;
 import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
 
@@ -43,27 +42,18 @@ public class EndpointRepositoryTest {
         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();
+        RecordingEndpointEventListener notifier = new RecordingEndpointEventListener();
         
         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.addEndpoints(sref, rsa, Arrays.asList(ep1));
         repo.removeRemoteServiceAdmin(rsa);
         c.verify();
-    }
 
+        notifier.matches(new EndpointEvent(EndpointEvent.ADDED, ep1), new EndpointEvent(EndpointEvent.REMOVED, ep1));
+    }
+    
     private ServiceReference<?> createService(IMocksControl c) {
         ServiceReference<?> sref = c.createMock(ServiceReference.class);
         Bundle bundle = c.createMock(Bundle.class);
@@ -79,4 +69,6 @@ public class EndpointRepositoryTest {
         props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "any");
         return new EndpointDescription(props);
     }
+    
+    
 }

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/RecordingEndpointEventListener.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/RecordingEndpointEventListener.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/RecordingEndpointEventListener.java
new file mode 100644
index 0000000..f17cbd0
--- /dev/null
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/exporter/RecordingEndpointEventListener.java
@@ -0,0 +1,48 @@
+/**
+ * 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.Matchers.equalTo;
+import static org.hamcrest.Matchers.samePropertyValuesAs;
+import static org.junit.Assert.assertThat;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.osgi.service.remoteserviceadmin.EndpointEvent;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
+
+class RecordingEndpointEventListener implements EndpointEventListener {
+    List<EndpointEvent> events = new ArrayList<>();
+
+    @Override
+    public void endpointChanged(EndpointEvent event, String filter) {
+        events.add(event);
+    }
+    
+    public void matches(EndpointEvent ... endpointEvents) {
+        assertThat("Incorrect number of events received", events.size(), equalTo(endpointEvents.length));
+        Iterator<EndpointEvent> it = events.iterator();
+        for (EndpointEvent event : endpointEvents) {
+            assertThat(it.next(), samePropertyValuesAs(event));
+        }
+    }
+     
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/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
index 2307566..af070d6 100644
--- 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
@@ -18,8 +18,6 @@
  */
 package org.apache.aries.rsa.topologymanager.exporter;
 
-import static org.easymock.EasyMock.expectLastCall;
-
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -30,13 +28,14 @@ import java.util.concurrent.Executor;
 import org.apache.aries.rsa.spi.ExportPolicy;
 import org.easymock.EasyMock;
 import org.easymock.IMocksControl;
+import org.junit.Before;
 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.EndpointEvent;
 import org.osgi.service.remoteserviceadmin.ExportReference;
 import org.osgi.service.remoteserviceadmin.ExportRegistration;
 import org.osgi.service.remoteserviceadmin.RemoteConstants;
@@ -44,6 +43,26 @@ import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
 
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class TopologyManagerExportTest {
+    
+    private IMocksControl c;
+    private RemoteServiceAdmin rsa;
+    private RecordingEndpointEventListener notifier;
+    private EndpointDescription epd;
+    private EndpointRepository endpointRepo;
+    private TopologyManagerExport exportManager;
+
+    @Before
+    public void start() {
+        c = EasyMock.createControl();
+        rsa = c.createMock(RemoteServiceAdmin.class);
+        notifier = new RecordingEndpointEventListener();
+        epd = createEndpoint();
+        endpointRepo = new EndpointRepository();
+        endpointRepo.setNotifier(notifier);
+        Executor executor = syncExecutor();
+        ExportPolicy policy = new DefaultExportPolicy();
+        exportManager = new TopologyManagerExport(endpointRepo, executor, policy);
+    }
 
     /**
      * This tests if the topology manager handles a service marked to be exported correctly by exporting it to
@@ -53,52 +72,31 @@ public class TopologyManagerExportTest {
      */
     @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);
+        ServiceReference sref = createUserService(c);
+        expectServiceExported(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();
+        notifier.matches(
+                new EndpointEvent(EndpointEvent.ADDED, epd),
+                new EndpointEvent(EndpointEvent.REMOVED, epd)
+                );
+
     }
 
     @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());
+        ServiceReference sref = createUserService(c);
+        expectServiceExported(sref, epd);
+        
         c.replay();
-
         EndpointRepository endpointRepo = new EndpointRepository();
-        endpointRepo.setNotifier(mockEpListenerNotifier);
+        endpointRepo.setNotifier(notifier);
         ExportPolicy policy = new DefaultExportPolicy();
         TopologyManagerExport exportManager = new TopologyManagerExport(endpointRepo, syncExecutor(), policy);
         exportManager.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref));
@@ -108,18 +106,11 @@ public class TopologyManagerExportTest {
 
     @Test
     public void testExportExistingMultipleInterfaces() throws Exception {
-        IMocksControl c = EasyMock.createControl();
-        RemoteServiceAdmin rsa = c.createMock(RemoteServiceAdmin.class);
-        final EndpointListenerNotifier mockEpListenerNotifier = c.createMock(EndpointListenerNotifier.class);
         List<String> exportedInterfaces = Arrays.asList("a.b.C","foo.Bar");
         final ServiceReference sref = createUserService(c, exportedInterfaces);
-        expectServiceExported(c, rsa, mockEpListenerNotifier, sref, createEndpoint());
-        c.replay();
+        expectServiceExported(sref, createEndpoint());
 
-        EndpointRepository endpointRepo = new EndpointRepository();
-        endpointRepo.setNotifier(mockEpListenerNotifier);
-        ExportPolicy policy = new DefaultExportPolicy();
-        TopologyManagerExport exportManager = new TopologyManagerExport(endpointRepo, syncExecutor(), policy);
+        c.replay();
         exportManager.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, sref));
         exportManager.add(rsa);
         c.verify();
@@ -127,15 +118,10 @@ public class TopologyManagerExportTest {
 
     @Test
     public void testExportExistingNoExportedInterfaces() throws Exception {
-        IMocksControl c = EasyMock.createControl();
-        RemoteServiceAdmin rsa = c.createMock(RemoteServiceAdmin.class);
-        final EndpointListenerNotifier mockEpListenerNotifier = c.createMock(EndpointListenerNotifier.class);
         String exportedInterfaces = "";
         final ServiceReference sref = createUserService(c, exportedInterfaces);
         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));
@@ -143,14 +129,12 @@ public class TopologyManagerExportTest {
         c.verify();
     }
 
-    private void expectServiceExported(IMocksControl c, RemoteServiceAdmin rsa,
-                                       final EndpointListener listener,
-                                       final ServiceReference sref, EndpointDescription epd) {
+    private void expectServiceExported(
+            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() {

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/3f77941e/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImportTest.java
----------------------------------------------------------------------
diff --git a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImportTest.java b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImportTest.java
index b5b8759..e93be3b 100644
--- a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImportTest.java
+++ b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImportTest.java
@@ -54,6 +54,7 @@ public class TopologyManagerImportTest {
                 return ir;
             }
         }).once();
+        
         ir.close();
         EasyMock.expectLastCall();
         c.replay();


[2/2] aries-rsa git commit: [ARIES-1763] Simplify RemoteServiceAdmin tests

Posted by cs...@apache.org.
[ARIES-1763] Simplify RemoteServiceAdmin tests


Project: http://git-wip-us.apache.org/repos/asf/aries-rsa/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-rsa/commit/d6b354da
Tree: http://git-wip-us.apache.org/repos/asf/aries-rsa/tree/d6b354da
Diff: http://git-wip-us.apache.org/repos/asf/aries-rsa/diff/d6b354da

Branch: refs/heads/master
Commit: d6b354daffd46ae0d2b8f745ae90ff2631f69c06
Parents: 3f77941
Author: Christian Schneider <cs...@adobe.com>
Authored: Wed Jan 31 11:44:51 2018 +0100
Committer: Christian Schneider <cs...@adobe.com>
Committed: Wed Jan 31 11:44:51 2018 +0100

----------------------------------------------------------------------
 parent/pom.xml                                  |   5 +
 .../rsa/core/DistributionProviderTracker.java   |   7 +-
 .../aries/rsa/core/ExportRegistrationImpl.java  |   2 +
 .../org/apache/aries/rsa/core/PackageUtil.java  |  10 +-
 .../aries/rsa/core/RemoteServiceAdminCore.java  |  30 +-
 .../aries/rsa/core/event/EventProducer.java     |   2 +-
 .../aries/rsa/core/OverlayPropertiesTest.java   | 164 +++++
 .../rsa/core/RemoteServiceAdminCoreTest.java    | 627 ++++++-------------
 8 files changed, 392 insertions(+), 455 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d6b354da/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 3d46cd3..43a4c07 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -75,6 +75,11 @@
             <artifactId>easymockclassextension</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+             <groupId>org.hamcrest</groupId>
+              <artifactId>hamcrest-all</artifactId>
+              <version>1.3</version>
+        </dependency>
     </dependencies>
 
     <dependencyManagement>

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d6b354da/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java b/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
index 79b1b51..b208b40 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
@@ -24,6 +24,7 @@ import static org.osgi.service.remoteserviceadmin.RemoteConstants.REMOTE_INTENTS
 import java.util.Dictionary;
 import java.util.Hashtable;
 
+import org.apache.aries.rsa.core.event.EventProducer;
 import org.apache.aries.rsa.spi.DistributionProvider;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -49,9 +50,13 @@ public class DistributionProviderTracker extends ServiceTracker<DistributionProv
         LOG.debug("RemoteServiceAdmin Implementation is starting up");
         DistributionProvider provider = context.getService(reference);
         BundleContext apiContext = getAPIContext();
+        PackageUtil packageUtil = new PackageUtil(context);
+        EventProducer eventProducer = new EventProducer(context);
         RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(context, 
                                                                     apiContext, 
-                                                                    provider);
+                                                                    eventProducer,
+                                                                    provider,
+                                                                    packageUtil);
         RemoteServiceadminFactory rsaf = new RemoteServiceadminFactory(rsaCore);
         Dictionary<String, Object> props = new Hashtable<String, Object>();
         props.put(REMOTE_INTENTS_SUPPORTED, getPropertyNullSafe(reference, REMOTE_INTENTS_SUPPORTED));

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d6b354da/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java b/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
index 7fac146..23496fa 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
@@ -98,9 +98,11 @@ public class ExportRegistrationImpl implements ExportRegistration {
     }
 
     public ExportReference getExportReference() {
+        /* TODO check if we need to throw exception here
         if (exportReference == null) {
             throw new IllegalStateException(getException());
         }
+        */
         return closed ? null : exportReference;
     }
 

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d6b354da/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java b/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
index fe58bdf..daf9c9d 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
@@ -27,13 +27,15 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings("deprecation")
-public final class PackageUtil {
+public class PackageUtil {
 
     public static final Logger LOG = LoggerFactory.getLogger(PackageUtil.class);
+    private BundleContext bc;
 
-    private PackageUtil() {
+    public PackageUtil(BundleContext bc) {
+        this.bc = bc;
     }
-
+    
     /**
      * Tries to retrieve the version of iClass via the PackageAdmin.
      *
@@ -42,7 +44,7 @@ public final class PackageUtil {
      * @return the version of the interface or "0.0.0" if no version information could be found or an error
      *         occurred during the retrieval
      */
-    public static String getVersion(Class<?> iClass, BundleContext bc) {
+    public String getVersion(Class<?> iClass) {
         ServiceReference<PackageAdmin> paRef = bc.getServiceReference(PackageAdmin.class);
         if (paRef != null) {
             PackageAdmin pa = bc.getService(paRef);

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d6b354da/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
index 7b7b38d..2b2dedf 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
@@ -68,16 +68,26 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
 
     private final BundleContext bctx;
     private final EventProducer eventProducer;
-    private final ServiceListener exportedServiceListener;
+    private ServiceListener exportedServiceListener;
     private DistributionProvider provider;
     private BundleContext apictx;
+    private PackageUtil packageUtil;
 
-    public RemoteServiceAdminCore(BundleContext context, BundleContext apiContext, DistributionProvider provider) {
+    public RemoteServiceAdminCore(BundleContext context, 
+            BundleContext apiContext, 
+            EventProducer eventProducer,
+            DistributionProvider provider,
+            PackageUtil packageUtil) {
         this.bctx = context;
         this.apictx = apiContext;
-        this.eventProducer = new EventProducer(bctx);
+        this.eventProducer = eventProducer;
         this.provider = provider;
+        this.packageUtil = packageUtil;
         // listen for exported services being unregistered so we can close the export
+        createExportedServicesListener();
+    }
+
+    protected void createExportedServicesListener() {
         this.exportedServiceListener = new ServiceListener() {
             public void serviceChanged(ServiceEvent event) {
                 if (event.getType() == ServiceEvent.UNREGISTERING) {
@@ -87,7 +97,7 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
         };
         try {
             String filter = "(" + RemoteConstants.SERVICE_EXPORTED_INTERFACES + "=*)";
-            context.addServiceListener(exportedServiceListener, filter);
+            bctx.addServiceListener(exportedServiceListener, filter);
         } catch (InvalidSyntaxException ise) {
             throw new RuntimeException(ise); // can never happen
         }
@@ -329,7 +339,9 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
             List<ExportReference> ers = new ArrayList<ExportReference>();
             for (Collection<ExportRegistration> exportRegistrations : exportedServices.values()) {
                 for (ExportRegistration er : exportRegistrations) {
-                    ers.add(new ExportReferenceImpl(er.getExportReference()));
+                    if (er.getExportReference() != null) {
+                        ers.add(new ExportReferenceImpl(er.getExportReference()));
+                    }
                 }
             }
             return Collections.unmodifiableCollection(ers);
@@ -548,7 +560,9 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
 
     public void close() {
         removeImportRegistrations();
-        bctx.removeServiceListener(exportedServiceListener);
+        if (exportedServiceListener != null) {
+            bctx.removeServiceListener(exportedServiceListener);
+        }
     }
 
     static void overlayProperties(Map<String, Object> serviceProperties,
@@ -606,13 +620,11 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin {
         props.put(RemoteConstants.ENDPOINT_FRAMEWORK_UUID, frameworkUUID);
         for (Class<?> iface : ifaces) {
             String pkg = iface.getPackage().getName();
-            props.put(RemoteConstants.ENDPOINT_PACKAGE_VERSION_ + pkg, PackageUtil.getVersion(iface, bctx));
+            props.put(RemoteConstants.ENDPOINT_PACKAGE_VERSION_ + pkg, packageUtil.getVersion(iface));
         }
         return props;
     }
 
-
-
     private void copyEndpointProperties(Map<String, Object> sd, Map<String, Object> endpointProps) {
         Set<Map.Entry<String, Object>> keys = sd.entrySet();
         for (Map.Entry<String, Object> entry : keys) {

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d6b354da/rsa/src/main/java/org/apache/aries/rsa/core/event/EventProducer.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/event/EventProducer.java b/rsa/src/main/java/org/apache/aries/rsa/core/event/EventProducer.java
index 2ff8c4e..ae6f8f6 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/event/EventProducer.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/event/EventProducer.java
@@ -94,7 +94,7 @@ public class EventProducer {
     @SuppressWarnings({
      "rawtypes", "unchecked"
     })
-    private void notifyListeners(RemoteServiceAdminEvent rsae) {
+    protected void notifyListeners(RemoteServiceAdminEvent rsae) {
         try {
             ServiceReference[] listenerRefs = bctx.getServiceReferences(
                     RemoteServiceAdminListener.class.getName(), null);

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d6b354da/rsa/src/test/java/org/apache/aries/rsa/core/OverlayPropertiesTest.java
----------------------------------------------------------------------
diff --git a/rsa/src/test/java/org/apache/aries/rsa/core/OverlayPropertiesTest.java b/rsa/src/test/java/org/apache/aries/rsa/core/OverlayPropertiesTest.java
new file mode 100644
index 0000000..9b784cc
--- /dev/null
+++ b/rsa/src/test/java/org/apache/aries/rsa/core/OverlayPropertiesTest.java
@@ -0,0 +1,164 @@
+/**
+ * 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.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.osgi.framework.Constants;
+
+public class OverlayPropertiesTest {
+    
+    @Test
+    public void testOverlayProperties() {
+        Map<String, Object> sProps = new HashMap<String, Object>();
+        Map<String, Object> aProps = new HashMap<String, Object>();
+
+        RemoteServiceAdminCore.overlayProperties(sProps, aProps);
+        assertEquals(0, sProps.size());
+
+        sProps.put("aaa", "aval");
+        sProps.put("bbb", "bval");
+        sProps.put(Constants.OBJECTCLASS, new String[] {"X"});
+        sProps.put(Constants.SERVICE_ID, 17L);
+
+        aProps.put("AAA", "achanged");
+        aProps.put("CCC", "CVAL");
+        aProps.put(Constants.OBJECTCLASS, new String[] {"Y"});
+        aProps.put(Constants.SERVICE_ID.toUpperCase(), 51L);
+
+        Map<String, Object> aPropsOrg = new HashMap<String, Object>(aProps);
+        RemoteServiceAdminCore.overlayProperties(sProps, aProps);
+        assertEquals("The additional properties should not be modified", aPropsOrg, aProps);
+
+        assertEquals(5, sProps.size());
+        assertEquals("achanged", sProps.get("aaa"));
+        assertEquals("bval", sProps.get("bbb"));
+        assertEquals("CVAL", sProps.get("CCC"));
+        assertTrue("Should not be possible to override the objectClass property",
+                Arrays.equals(new String[] {"X"}, (Object[]) sProps.get(Constants.OBJECTCLASS)));
+        assertEquals("Should not be possible to override the service.id property",
+                17L, sProps.get(Constants.SERVICE_ID));
+    }
+    
+    @Test
+    public void testOverlayProperties2() {
+        Map<String, Object> original = new HashMap<String, Object>();
+
+        original.put("MyProp", "my value");
+        original.put(Constants.OBJECTCLASS, "myClass");
+
+        Map<String, Object> copy = new HashMap<String, Object>();
+        copy.putAll(original);
+
+        // nothing should change here
+        Map<String, Object> overload = new HashMap<String, Object>();
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size(), copy.size());
+        for (Object key : original.keySet()) {
+            assertEquals(original.get(key), copy.get(key));
+        }
+
+        copy.clear();
+        copy.putAll(original);
+
+        // a property should be added
+        overload = new HashMap<String, Object>();
+        overload.put("new", "prop");
+
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size() + 1, copy.size());
+        for (Object key : original.keySet()) {
+            assertEquals(original.get(key), copy.get(key));
+        }
+        assertNotNull(overload.get("new"));
+        assertEquals("prop", overload.get("new"));
+
+        copy.clear();
+        copy.putAll(original);
+
+        // only one property should be added
+        overload = new HashMap<String, Object>();
+        overload.put("new", "prop");
+        overload.put("NEW", "prop");
+
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size() + 1, copy.size());
+        for (Object key : original.keySet()) {
+            assertEquals(original.get(key), copy.get(key));
+        }
+        assertNotNull(overload.get("new"));
+        assertEquals("prop", overload.get("new"));
+
+        copy.clear();
+        copy.putAll(original);
+
+        // nothing should change here
+        overload = new HashMap<String, Object>();
+        overload.put(Constants.OBJECTCLASS, "assd");
+        overload.put(Constants.SERVICE_ID, "asasdasd");
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size(), copy.size());
+        for (Object key : original.keySet()) {
+            assertEquals(original.get(key), copy.get(key));
+        }
+
+        copy.clear();
+        copy.putAll(original);
+
+        // overwrite own prop
+        overload = new HashMap<String, Object>();
+        overload.put("MyProp", "newValue");
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size(), copy.size());
+        for (Object key : original.keySet()) {
+            if (!"MyProp".equals(key)) {
+                assertEquals(original.get(key), copy.get(key));
+            }
+        }
+        assertEquals("newValue", copy.get("MyProp"));
+
+        copy.clear();
+        copy.putAll(original);
+
+        // overwrite own prop in different case
+        overload = new HashMap<String, Object>();
+        overload.put("MYPROP", "newValue");
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size(), copy.size());
+        for (Object key : original.keySet()) {
+            if (!"MyProp".equals(key)) {
+                assertEquals(original.get(key), copy.get(key));
+            }
+        }
+        assertEquals("newValue", copy.get("MyProp"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/d6b354da/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
----------------------------------------------------------------------
diff --git a/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java b/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
index 4ef5102..09dffc2 100644
--- a/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
+++ b/rsa/src/test/java/org/apache/aries/rsa/core/RemoteServiceAdminCoreTest.java
@@ -18,10 +18,16 @@
  */
 package org.apache.aries.rsa.core;
 
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+import static org.hamcrest.Matchers.contains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
-import java.io.IOException;
 import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.Collection;
@@ -31,101 +37,104 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.aries.rsa.core.event.EventProducer;
 import org.apache.aries.rsa.spi.DistributionProvider;
 import org.apache.aries.rsa.spi.Endpoint;
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
 import org.easymock.IMocksControl;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.framework.Version;
 import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.ExportReference;
 import org.osgi.service.remoteserviceadmin.ExportRegistration;
 import org.osgi.service.remoteserviceadmin.ImportRegistration;
 import org.osgi.service.remoteserviceadmin.RemoteConstants;
 
 @SuppressWarnings({
-    "rawtypes", "unchecked", "deprecation"
+    "rawtypes", "unchecked"
    })
 public class RemoteServiceAdminCoreTest {
 
     private static final String MYCONFIG = "myconfig";
+    private IMocksControl c;
+    private BundleContext rsaContext;
+    private RemoteServiceAdminCore rsaCore;
+    private BundleContext apiContext;
+    private DummyProvider provider;
+    
+    @Before
+    public void setup() throws InvalidSyntaxException {
+        c = EasyMock.createControl();      
+        rsaContext = c.createMock(BundleContext.class);
+        Bundle b = createDummyRsaBundle(rsaContext);
+        expect(rsaContext.getProperty(Constants.FRAMEWORK_VERSION)).andReturn("1111").anyTimes();
+        expect(rsaContext.getProperty(Constants.FRAMEWORK_UUID)).andReturn("some_uuid1").anyTimes();
+
+        expect(rsaContext.getBundle()).andReturn(b).anyTimes();
+        apiContext = c.createMock(BundleContext.class);
+        provider = new DummyProvider();
+        PackageUtil packageUtil = new PackageUtil(rsaContext) {
+            @Override
+            public String getVersion(Class<?> iClass) {
+                return "1.0.0";
+            }
+        };
+        EventProducer eventProducer = new EventProducer(rsaContext) {
+            protected void notifyListeners(org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent rsae) {
+                // skip
+            };
+        };
+        rsaCore = new RemoteServiceAdminCore(rsaContext, apiContext, eventProducer, provider, packageUtil) {
+            protected void createExportedServicesListener() {
+                // Skip
+            }
+        };
+    }
 
     @Test
     public void testDontExportOwnServiceProxies() throws InvalidSyntaxException {
-        IMocksControl c = EasyMock.createControl();
-        Bundle b = c.createMock(Bundle.class);
-        BundleContext bc = c.createMock(BundleContext.class);
-
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
-        bc.addServiceListener(EasyMock.<ServiceListener>anyObject(), EasyMock.<String>anyObject());
-        EasyMock.expectLastCall().anyTimes();
-        bc.removeServiceListener(EasyMock.<ServiceListener>anyObject());
-        EasyMock.expectLastCall().anyTimes();
-
-        Dictionary<String, String> d = new Hashtable<String, String>();
-        EasyMock.expect(b.getHeaders()).andReturn(d).anyTimes();
-
-        ServiceReference sref = c.createMock(ServiceReference.class);
-        EasyMock.expect(sref.getBundle()).andReturn(b).anyTimes();
-        EasyMock.expect(sref.getPropertyKeys())
-            .andReturn(new String[]{"objectClass", "service.exported.interfaces"}).anyTimes();
-        EasyMock.expect(sref.getProperty("objectClass")).andReturn(new String[] {"a.b.C"}).anyTimes();
-        EasyMock.expect(sref.getProperty(RemoteConstants.SERVICE_IMPORTED)).andReturn(true).anyTimes();
-        EasyMock.expect(sref.getProperty("service.exported.interfaces")).andReturn("*").anyTimes();
-
-        DistributionProvider provider = c.createMock(DistributionProvider.class);
+        Map<String, Object> sProps = new HashMap<>();
+        sProps.put("objectClass", new String[] {"a.b.C"});
+        sProps.put(RemoteConstants.SERVICE_IMPORTED, true);
+        sProps.put("service.exported.interfaces", "*");
+        ServiceReference sref = mockServiceReference(sProps);
 
         c.replay();
 
-        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, provider);
-
-        // must return an empty List as sref if from the same bundle
         List<ExportRegistration> exRefs = rsaCore.exportService(sref, null);
 
         assertNotNull(exRefs);
         assertEquals(0, exRefs.size());
-
-        // must be empty
         assertEquals(rsaCore.getExportedServices().size(), 0);
 
         c.verify();
     }
 
     @Test
-    public void testImport() {
-        IMocksControl c = EasyMock.createNiceControl();
-        Bundle b = c.createMock(Bundle.class);
-        BundleContext bc = c.createMock(BundleContext.class);
-
-        Dictionary<String, String> d = new Hashtable<String, String>();
-        EasyMock.expect(b.getHeaders()).andReturn(d).anyTimes();
-
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
-        EasyMock.expect(b.getSymbolicName()).andReturn("BundleName").anyTimes();
-
+    public void testDoNotImportUnsupportedConfig() {
         EndpointDescription endpoint = creatEndpointDesc("unsupportedConfiguration");
-
-        DistributionProvider provider = c.createMock(DistributionProvider.class);
-        EasyMock.expect(provider.getSupportedTypes())
-            .andReturn(new String[]{MYCONFIG}).atLeastOnce();
+        
         c.replay();
 
-        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, provider);
-
-        // must be null as the endpoint doesn't contain any usable configurations
         assertNull(rsaCore.importService(endpoint));
-        // must be empty
         assertEquals(0, rsaCore.getImportedEndpoints().size());
+        
+        c.verify();
+    }
 
+    @Test
+    public void testImport() {
+        expect(apiContext.registerService(EasyMock.aryEq(new String[]{"es.schaaf.my.class"}), anyObject(), (Dictionary<String, ? >)anyObject())).andReturn(null);
+
+        c.replay();
         EndpointDescription endpoint2 = creatEndpointDesc(MYCONFIG);
 
         ImportRegistration ireg = rsaCore.importService(endpoint2);
@@ -156,29 +165,12 @@ public class RemoteServiceAdminCoreTest {
         c.verify();
     }
 
-
     @Test
     public void testImportWithMultipleInterfaces() {
-        IMocksControl c = EasyMock.createNiceControl();
-        Bundle b = c.createMock(Bundle.class);
-        BundleContext bc = c.createMock(BundleContext.class);
-
-        Dictionary<String, String> d = new Hashtable<String, String>();
-        EasyMock.expect(b.getHeaders()).andReturn(d).anyTimes();
+        expect(apiContext.registerService(EasyMock.aryEq(new String[]{"es.schaaf.my.class","java.lang.Runnable"}), anyObject(), (Dictionary<String, ? >)anyObject())).andReturn(null);
 
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
-
-        EasyMock.expect(bc.registerService(EasyMock.aryEq(new String[]{"es.schaaf.my.class","java.lang.Runnable"}), anyObject(), (Dictionary<String, ? >)anyObject())).andReturn(null);
-        EasyMock.expect(b.getSymbolicName()).andReturn("BundleName").anyTimes();
-
-        DistributionProvider provider = c.createMock(DistributionProvider.class);
-        EasyMock.expect(provider.getSupportedTypes())
-            .andReturn(new String[]{MYCONFIG}).atLeastOnce();
         c.replay();
 
-        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, provider);
-
-
         Map<String, Object> p = new HashMap<String, Object>();
         p.put(RemoteConstants.ENDPOINT_ID, "http://google.de");
         p.put(Constants.OBJECTCLASS, new String[] {
@@ -191,7 +183,6 @@ public class RemoteServiceAdminCoreTest {
         ImportRegistration ireg = rsaCore.importService(endpoint);
 
         assertNotNull(ireg);
-
         assertEquals(1, rsaCore.getImportedEndpoints().size());
 
         // lets import the same endpoint once more -> should get a copy of the ImportRegistration
@@ -210,32 +201,8 @@ public class RemoteServiceAdminCoreTest {
         c.verify();
     }
 
-    private EndpointDescription creatEndpointDesc(String configType) {
-        Map<String, Object> p = new HashMap<String, Object>();
-        p.put(RemoteConstants.ENDPOINT_ID, "http://google.de");
-        p.put(Constants.OBJECTCLASS, new String[] {
-            "es.schaaf.my.class"
-        });
-        p.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, configType);
-        EndpointDescription endpoint = new EndpointDescription(p);
-        return endpoint;
-    }
-
     @Test
     public void testExport() throws Exception {
-        BundleContext bc = EasyMock.createMock(BundleContext.class);
-        EasyMock.expect(bc.getProperty(Constants.FRAMEWORK_VERSION)).andReturn(null).anyTimes();
-        bc.addServiceListener(EasyMock.<ServiceListener>anyObject(), EasyMock.<String>anyObject());
-        EasyMock.expectLastCall().anyTimes();
-        bc.removeServiceListener(EasyMock.<ServiceListener>anyObject());
-        EasyMock.expectLastCall().anyTimes();
-        EasyMock.expect(bc.getServiceReferences(EasyMock.<String>anyObject(),
-                                                EasyMock.<String>anyObject())).andReturn(null).anyTimes();
-        EasyMock.expect(bc.getAllServiceReferences(EasyMock.<String>anyObject(),
-                                                   EasyMock.<String>anyObject())).andReturn(null).anyTimes();
-
-        Bundle b = createDummyRsaBundle(bc);
-
         final Map<String, Object> sProps = new HashMap<String, Object>();
         sProps.put("objectClass", new String[] {"java.lang.Runnable"});
         sProps.put("service.id", 51L);
@@ -243,442 +210,222 @@ public class RemoteServiceAdminCoreTest {
         sProps.put("service.exported.interfaces", "*");
         ServiceReference sref = mockServiceReference(sProps);
 
-        Runnable svcObject = EasyMock.createNiceMock(Runnable.class);
-        EasyMock.replay(svcObject);
-
-        EasyMock.expect(bc.getService(sref)).andReturn(svcObject).anyTimes();
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
-        EasyMock.expect(bc.createFilter("(service.id=51)"))
-            .andReturn(FrameworkUtil.createFilter("(service.id=51)")).anyTimes();
-        EasyMock.expect(bc.getProperty(org.osgi.framework.Constants.FRAMEWORK_UUID)).andReturn("1111");
-        EasyMock.expect(bc.getServiceReference(PackageAdmin.class)).andReturn(null);
-        EasyMock.expect(bc.getServiceReference(EventAdmin.class)).andReturn(null).atLeastOnce();
-        EasyMock.replay(bc);
-
-        Map<String, Object> eProps = new HashMap<String, Object>(sProps);
-        eProps.put("endpoint.id", "http://something");
-        eProps.put("service.imported.configs", new String[] {"org.apache.cxf.ws"});
-        final EndpointDescription epd = new EndpointDescription(eProps);
-        Endpoint er = new Endpoint() {
-            
-            @Override
-            public void close() throws IOException {
-            }
-            
-            @Override
-            public EndpointDescription description() {
-                return epd;
-            }
-        };
-
-        DistributionProvider handler = EasyMock.createMock(DistributionProvider.class);
-        EasyMock.expect(handler.exportService(anyObject(),
-                                              anyObject(BundleContext.class), 
-                                              anyObject(Map.class), isA(Class[].class))).andReturn(er);
-        EasyMock.replay(handler);
-
-        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, handler);
+        provider.endpoint = createEndpoint(sProps);
+        c.replay();
 
         // Export the service for the first time
-        List<ExportRegistration> ereg = rsaCore.exportService(sref, null);
-        assertEquals(1, ereg.size());
-        assertNull(ereg.get(0).getException());
-        assertSame(sref, ereg.get(0).getExportReference().getExportedService());
-        EndpointDescription endpoint = ereg.get(0).getExportReference().getExportedEndpoint();
+        List<ExportRegistration> eregs = rsaCore.exportService(sref, null);
+        assertEquals(1, eregs.size());
+        ExportRegistration ereg = eregs.iterator().next();
+        assertNull(ereg.getException());
+        assertSame(sref, ereg.getExportReference().getExportedService());
+        EndpointDescription endpoint = ereg.getExportReference().getExportedEndpoint();
 
         Map<String, Object> edProps = endpoint.getProperties();
         assertEquals("http://something", edProps.get("endpoint.id"));
         assertNotNull(edProps.get("service.imported"));
         assertTrue(Arrays.equals(new String[] {"java.lang.Runnable"},
                                  (Object[]) edProps.get("objectClass")));
-        assertTrue(Arrays.equals(new String[] {"org.apache.cxf.ws"},
+        assertTrue(Arrays.equals(new String[] {MYCONFIG},
                                  (Object[]) edProps.get("service.imported.configs")));
 
         // Ask to export the same service again, this should not go through the whole process again but simply return
         // a copy of the first instance.
-        final Map<String, Object> sProps2 = new HashMap<String, Object>();
-        sProps2.put("objectClass", new String[] {"java.lang.Runnable"});
-        sProps2.put("service.id", 51L);
-        sProps2.put("service.exported.interfaces", "*");
-        ServiceReference sref2 = mockServiceReference(sProps2);
-        Map<String, Object> props2 = new HashMap<String, Object>();
-        props2.put("myProp", "myVal");
-        List<ExportRegistration> ereg2 = rsaCore.exportService(sref2, props2);
-
-        assertEquals(1, ereg2.size());
-        assertNull(ereg2.get(0).getException());
-        assertEquals(ereg.get(0).getExportReference().getExportedEndpoint().getProperties(),
-                ereg2.get(0).getExportReference().getExportedEndpoint().getProperties());
+        ServiceReference sref2 = mockServiceReference(sProps);
+        List<ExportRegistration> eregs2 = rsaCore.exportService(sref2, null);
+        assertEquals(1, eregs2.size());
+        ExportRegistration ereg2 = eregs2.iterator().next();
+        assertNull(ereg2.getException());
+        assertEquals(ereg.getExportReference().getExportedEndpoint().getProperties(),
+                ereg2.getExportReference().getExportedEndpoint().getProperties());
 
         // Look at the exportedServices data structure
-        Field field = RemoteServiceAdminCore.class.getDeclaredField("exportedServices");
-        field.setAccessible(true);
-        Map<Map<String, Object>, Collection<ExportRegistration>> exportedServices =
-                (Map<Map<String, Object>, Collection<ExportRegistration>>) field.get(rsaCore);
+        Map<Map<String, Object>, Collection<ExportRegistration>> exportedServices = getInternalExportedServices();
 
         assertEquals("One service was exported", 1, exportedServices.size());
+        Collection<ExportRegistration> firstRegs = exportedServices.values().iterator().next();
         assertEquals("There are 2 export registrations (identical copies)",
-                2, exportedServices.values().iterator().next().size());
+                2, firstRegs.size());
 
         // Unregister one of the exports
-        rsaCore.removeExportRegistration((ExportRegistrationImpl) ereg.get(0));
+        rsaCore.removeExportRegistration((ExportRegistrationImpl) eregs.get(0));
         assertEquals("One service was exported", 1, exportedServices.size());
-        assertEquals("There 1 export registrations left",
-                1, exportedServices.values().iterator().next().size());
+        assertEquals("There 1 export registrations left", 1, firstRegs.size());
 
         // Unregister the other export
-        rsaCore.removeExportRegistration((ExportRegistrationImpl) ereg2.get(0));
+        rsaCore.removeExportRegistration((ExportRegistrationImpl) eregs2.get(0));
         assertEquals("No more exported services", 0, exportedServices.size());
     }
 
     @Test
     public void testExportWrongConfig() throws Exception {
-        BundleContext bc = EasyMock.createMock(BundleContext.class);
-        EasyMock.expect(bc.getProperty(Constants.FRAMEWORK_VERSION)).andReturn(null).anyTimes();
-        bc.addServiceListener(EasyMock.<ServiceListener>anyObject(), EasyMock.<String>anyObject());
-        EasyMock.expectLastCall().anyTimes();
-        bc.removeServiceListener(EasyMock.<ServiceListener>anyObject());
-        EasyMock.expectLastCall().anyTimes();
-        EasyMock.expect(bc.getServiceReferences(EasyMock.<String>anyObject(),
-                                                EasyMock.<String>anyObject())).andReturn(null).anyTimes();
-        EasyMock.expect(bc.getAllServiceReferences(EasyMock.<String>anyObject(),
-                                                   EasyMock.<String>anyObject())).andReturn(null).anyTimes();
-
-        Bundle b = createDummyRsaBundle(bc);
-
         final Map<String, Object> sProps = new HashMap<String, Object>();
         sProps.put("objectClass", new String[] {"java.lang.Runnable"});
         sProps.put("service.id", 51L);
         sProps.put("myProp", "myVal");
         sProps.put("service.exported.interfaces", "*");
+        sProps.put(RemoteConstants.SERVICE_EXPORTED_CONFIGS, "org.apache.cxf.ws");
         ServiceReference sref = mockServiceReference(sProps);
 
-        Runnable svcObject = EasyMock.createNiceMock(Runnable.class);
-        EasyMock.replay(svcObject);
-
-        EasyMock.expect((Runnable)bc.getService(sref)).andReturn(svcObject).anyTimes();
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
-        EasyMock.expect(bc.createFilter("(service.id=51)"))
-            .andReturn(FrameworkUtil.createFilter("(service.id=51)")).anyTimes();
-        EasyMock.expect(bc.getProperty(org.osgi.framework.Constants.FRAMEWORK_UUID)).andReturn("1111");
-        EasyMock.expect(bc.getServiceReference(PackageAdmin.class)).andReturn(null);
-        EasyMock.replay(bc);
-
-        Map<String, Object> eProps = new HashMap<String, Object>(sProps);
-        eProps.put("endpoint.id", "http://something");
-        eProps.put("service.imported.configs", new String[] {"org.apache.cxf.ws"});
-
-        DistributionProvider handler = EasyMock.createStrictMock(DistributionProvider.class);
-        EasyMock.expect(handler.getSupportedTypes()).andReturn(new String[]{"something"});
-        //export service should never be called since the exported confgi does not match
-        EasyMock.replay(handler);
+        c.replay();
+        List<ExportRegistration> ereg = rsaCore.exportService(sref, null);
 
-        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, handler);
-        Map<String, String> extraProperties = new HashMap<>();
-        extraProperties.put(RemoteConstants.SERVICE_EXPORTED_CONFIGS, "org.apache.cxf.ws");
-        // Export the service for the first time
-        List<ExportRegistration> ereg = rsaCore.exportService(sref, extraProperties);
+        // Service should not be exported as the exported config does not match
         assertEquals(0, ereg.size());
+        c.verify();
     }
 
     @Test
     public void testExportOneConfigSupported() throws Exception {
-        BundleContext bc = EasyMock.createMock(BundleContext.class);
-        EasyMock.expect(bc.getProperty(Constants.FRAMEWORK_VERSION)).andReturn(null).anyTimes();
-        bc.addServiceListener(EasyMock.<ServiceListener>anyObject(), EasyMock.<String>anyObject());
-        EasyMock.expectLastCall().anyTimes();
-        bc.removeServiceListener(EasyMock.<ServiceListener>anyObject());
-        EasyMock.expectLastCall().anyTimes();
-        EasyMock.expect(bc.getServiceReferences(EasyMock.<String>anyObject(),
-                                                EasyMock.<String>anyObject())).andReturn(null).anyTimes();
-        EasyMock.expect(bc.getAllServiceReferences(EasyMock.<String>anyObject(),
-                                                   EasyMock.<String>anyObject())).andReturn(null).anyTimes();
-
-        Bundle b = createDummyRsaBundle(bc);
-
         final Map<String, Object> sProps = new HashMap<String, Object>();
         sProps.put("objectClass", new String[] {"java.lang.Runnable"});
         sProps.put("service.id", 51L);
         sProps.put("myProp", "myVal");
         sProps.put("service.exported.interfaces", "*");
+        sProps.put(RemoteConstants.SERVICE_EXPORTED_CONFIGS, new String[]{MYCONFIG, "aconfig"});
         ServiceReference sref = mockServiceReference(sProps);
+        provider.endpoint = createEndpoint(sProps);
+        c.replay();
 
-        Runnable svcObject = EasyMock.createNiceMock(Runnable.class);
-        EasyMock.replay(svcObject);
-
-        EasyMock.expect((Runnable)bc.getService(sref)).andReturn(svcObject).anyTimes();
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
-        EasyMock.expect(bc.createFilter("(service.id=51)"))
-            .andReturn(FrameworkUtil.createFilter("(service.id=51)")).anyTimes();
-        EasyMock.expect(bc.getProperty(org.osgi.framework.Constants.FRAMEWORK_UUID)).andReturn("1111");
-        EasyMock.expect(bc.getServiceReference(PackageAdmin.class)).andReturn(null);
-        EasyMock.expect(bc.getServiceReference(EventAdmin.class)).andReturn(null).atLeastOnce();
-        EasyMock.replay(bc);
-
-        Map<String, Object> eProps = new HashMap<String, Object>(sProps);
-        eProps.put("endpoint.id", "http://something");
-        eProps.put("service.imported.configs", new String[] {"org.apache.cxf.ws","aconfig"});
-        final EndpointDescription epd = new EndpointDescription(eProps);
-        Endpoint er = new Endpoint() {
-
-            @Override
-            public void close() throws IOException {
-            }
-
-            @Override
-            public EndpointDescription description() {
-                return epd;
-            }
-        };
-
-        DistributionProvider handler = EasyMock.createStrictMock(DistributionProvider.class);
-        EasyMock.expect(handler.getSupportedTypes()).andReturn(new String[]{"something","aconfig"});
-        EasyMock.expect(handler.exportService(anyObject(),
-                                              anyObject(BundleContext.class),
-                                              anyObject(Map.class), isA(Class[].class))).andReturn(er);
-        //export service should never be called since the exported confgi does not match
-        EasyMock.replay(handler);
-
-        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, handler);
-        Map<String, Object> extraProperties = new HashMap<>();
-        extraProperties.put(RemoteConstants.SERVICE_EXPORTED_CONFIGS, new String[]{"org.apache.cxf.ws","aconfig"});
-        // Export the service for the first time
-        List<ExportRegistration> ereg = rsaCore.exportService(sref, extraProperties);
+        List<ExportRegistration> ereg = rsaCore.exportService(sref, null);
         assertEquals(1, ereg.size());
-    }
-
-    private Bundle createDummyRsaBundle(BundleContext bc) {
-        Bundle b = EasyMock.createNiceMock(Bundle.class);
-        EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
-        EasyMock.expect(b.getSymbolicName()).andReturn("rsabundle").anyTimes();
-        EasyMock.expect(b.getHeaders()).andReturn(new Hashtable<String, String>()).anyTimes();
-        EasyMock.replay(b);
-        return b;
+        ExportRegistration first = ereg.iterator().next();
+        EndpointDescription exportedEndpoint = first.getExportReference().getExportedEndpoint();
+        assertThat(exportedEndpoint.getConfigurationTypes(), contains(MYCONFIG));
     }
 
     @Test
     public void testExportException() throws Exception {
-        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
-
-        Bundle b = createDummyRsaBundle(bc);
-
         final Map<String, Object> sProps = new HashMap<String, Object>();
         sProps.put("objectClass", new String[] {"java.lang.Runnable"});
         sProps.put("service.id", 51L);
         sProps.put("service.exported.interfaces", "*");
         ServiceReference sref = mockServiceReference(sProps);
 
-        Runnable svcObject = EasyMock.createNiceMock(Runnable.class);
-        EasyMock.replay(svcObject);
-
-        EasyMock.expect(bc.getService(sref)).andReturn(svcObject).anyTimes();
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
-        EasyMock.replay(bc);
-
-        Map<String, Object> eProps = new HashMap<String, Object>(sProps);
-        eProps.put("endpoint.id", "http://something");
-        eProps.put("service.imported.configs", new String[] {"org.apache.cxf.ws"});
-
-        DistributionProvider handler = EasyMock.createMock(DistributionProvider.class);
-        EasyMock.expect(handler.exportService(anyObject(),
-                                              anyObject(BundleContext.class), 
-                                              anyObject(Map.class), isA(Class[].class))).andThrow(new TestException());
-        EasyMock.replay(handler);
-
-        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, handler);
+        provider.ex = new TestException();
 
         List<ExportRegistration> ereg = rsaCore.exportService(sref, sProps);
         assertEquals(1, ereg.size());
         assertTrue(ereg.get(0).getException() instanceof TestException);
 
-        // Look at the exportedServices data structure
+        Collection<ExportReference> exportedServices = rsaCore.getExportedServices();
+        assertEquals("No service was exported", 0, exportedServices.size());
+    }
+
+    @Test
+    public void testCreateEndpointProps() {
+        c.replay();
+        Map<String, Object> sd = new HashMap<String, Object>();
+        sd.put(org.osgi.framework.Constants.SERVICE_ID, 42);
+        Map<String, Object> props = rsaCore.createEndpointProps(sd, new Class[]{String.class});
+
+        Assert.assertFalse(props.containsKey(org.osgi.framework.Constants.SERVICE_ID));
+        assertEquals(42, props.get(RemoteConstants.ENDPOINT_SERVICE_ID));
+        assertEquals("some_uuid1", props.get(RemoteConstants.ENDPOINT_FRAMEWORK_UUID));
+        assertEquals(Arrays.asList("java.lang.String"),
+                     Arrays.asList((Object[]) props.get(org.osgi.framework.Constants.OBJECTCLASS)));
+        assertEquals("1.0.0", props.get("endpoint.package.version.java.lang"));
+        c.verify();
+    }
+
+    private Map<Map<String, Object>, Collection<ExportRegistration>> getInternalExportedServices()
+            throws NoSuchFieldException, IllegalAccessException {
         Field field = RemoteServiceAdminCore.class.getDeclaredField("exportedServices");
         field.setAccessible(true);
         Map<Map<String, Object>, Collection<ExportRegistration>> exportedServices =
                 (Map<Map<String, Object>, Collection<ExportRegistration>>) field.get(rsaCore);
+        return exportedServices;
+    }
 
-        assertEquals("One service was exported", 1, exportedServices.size());
-        assertEquals("There is 1 export registration",
-                1, exportedServices.values().iterator().next().size());
+    private Endpoint createEndpoint(final Map<String, Object> sProps) {
+        Map<String, Object> eProps = new HashMap<String, Object>(sProps);
+        eProps.put("endpoint.id", "http://something");
+        eProps.put("service.imported.configs", new String[] {MYCONFIG});
+        final EndpointDescription epd = new EndpointDescription(eProps);
+        Endpoint er = c.createMock(Endpoint.class);
+        expect(er.description()).andReturn(epd);
+        return er;
+    }
 
+    private Bundle createDummyRsaBundle(BundleContext bc) {
+        Bundle b = c.createMock(Bundle.class);
+        expect(b.getBundleContext()).andReturn(bc).anyTimes();
+        expect(b.getSymbolicName()).andReturn("rsabundle").anyTimes();
+        expect(b.getBundleId()).andReturn(10l).anyTimes();
+        expect(b.getVersion()).andReturn(new Version("1.0.0")).anyTimes();
+        expect(b.getHeaders()).andReturn(new Hashtable<String, String>()).anyTimes();
+        return b;
     }
 
-    private ServiceReference mockServiceReference(final Map<String, Object> sProps) throws ClassNotFoundException {
+    private ServiceReference mockServiceReference(final Map<String, Object> sProps) {
         BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
-
-        Bundle b = EasyMock.createNiceMock(Bundle.class);
-        EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
-        EasyMock.expect((Class)b.loadClass(Runnable.class.getName())).andReturn(Runnable.class);
-        EasyMock.replay(b);
-
-        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
+    
+        Bundle sb = EasyMock.createNiceMock(Bundle.class);
+        expect(sb.getBundleContext()).andReturn(bc).anyTimes();
+        try {
+            expect((Class)sb.loadClass(Runnable.class.getName())).andReturn(Runnable.class);
+        } catch (ClassNotFoundException e) {
+            throw new IllegalStateException(e.getMessage(), e);
+        }
+        EasyMock.replay(sb);
+    
+        expect(bc.getBundle()).andReturn(sb).anyTimes();
         EasyMock.replay(bc);
-
+    
         ServiceReference sref = EasyMock.createNiceMock(ServiceReference.class);
-        EasyMock.expect(sref.getBundle()).andReturn(b).anyTimes();
-        EasyMock.expect(sref.getPropertyKeys()).andReturn(sProps.keySet().toArray(new String[] {})).anyTimes();
-        EasyMock.expect(sref.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
+        expect(sref.getBundle()).andReturn(sb).anyTimes();
+        expect(sref.getPropertyKeys()).andReturn(sProps.keySet().toArray(new String[] {})).anyTimes();
+        expect(sref.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
             @Override
             public Object answer() throws Throwable {
                 return sProps.get(EasyMock.getCurrentArguments()[0]);
             }
         }).anyTimes();
         EasyMock.replay(sref);
+        
+        Runnable svcObject = EasyMock.createNiceMock(Runnable.class);
+        EasyMock.replay(svcObject);
+
         return sref;
     }
+    
+    private EndpointDescription creatEndpointDesc(String configType) {
+        Map<String, Object> p = new HashMap<String, Object>();
+        p.put(RemoteConstants.ENDPOINT_ID, "http://google.de");
+        p.put(Constants.OBJECTCLASS, new String[] {
+            "es.schaaf.my.class"
+        });
+        p.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, configType);
+        return new EndpointDescription(p);
+    }
 
     @SuppressWarnings("serial")
     private static class TestException extends RuntimeException {
     }
-    
-    @Test
-    public void testOverlayProperties() {
-        Map<String, Object> sProps = new HashMap<String, Object>();
-        Map<String, Object> aProps = new HashMap<String, Object>();
-
-        RemoteServiceAdminCore.overlayProperties(sProps, aProps);
-        assertEquals(0, sProps.size());
-
-        sProps.put("aaa", "aval");
-        sProps.put("bbb", "bval");
-        sProps.put(Constants.OBJECTCLASS, new String[] {"X"});
-        sProps.put(Constants.SERVICE_ID, 17L);
-
-        aProps.put("AAA", "achanged");
-        aProps.put("CCC", "CVAL");
-        aProps.put(Constants.OBJECTCLASS, new String[] {"Y"});
-        aProps.put(Constants.SERVICE_ID.toUpperCase(), 51L);
-
-        Map<String, Object> aPropsOrg = new HashMap<String, Object>(aProps);
-        RemoteServiceAdminCore.overlayProperties(sProps, aProps);
-        assertEquals("The additional properties should not be modified", aPropsOrg, aProps);
-
-        assertEquals(5, sProps.size());
-        assertEquals("achanged", sProps.get("aaa"));
-        assertEquals("bval", sProps.get("bbb"));
-        assertEquals("CVAL", sProps.get("CCC"));
-        assertTrue("Should not be possible to override the objectClass property",
-                Arrays.equals(new String[] {"X"}, (Object[]) sProps.get(Constants.OBJECTCLASS)));
-        assertEquals("Should not be possible to override the service.id property",
-                17L, sProps.get(Constants.SERVICE_ID));
-    }
-    
-    @Test
-    public void testOverlayProperties2() {
-        Map<String, Object> original = new HashMap<String, Object>();
-
-        original.put("MyProp", "my value");
-        original.put(Constants.OBJECTCLASS, "myClass");
-
-        Map<String, Object> copy = new HashMap<String, Object>();
-        copy.putAll(original);
 
-        // nothing should change here
-        Map<String, Object> overload = new HashMap<String, Object>();
-        RemoteServiceAdminCore.overlayProperties(copy, overload);
+    class DummyProvider implements DistributionProvider {
+        
+        Endpoint endpoint;
+        RuntimeException ex;
 
-        assertEquals(original.size(), copy.size());
-        for (Object key : original.keySet()) {
-            assertEquals(original.get(key), copy.get(key));
+        @Override
+        public String[] getSupportedTypes() {
+            return new String[]{MYCONFIG};
         }
 
-        copy.clear();
-        copy.putAll(original);
-
-        // a property should be added
-        overload = new HashMap<String, Object>();
-        overload.put("new", "prop");
-
-        RemoteServiceAdminCore.overlayProperties(copy, overload);
-
-        assertEquals(original.size() + 1, copy.size());
-        for (Object key : original.keySet()) {
-            assertEquals(original.get(key), copy.get(key));
-        }
-        assertNotNull(overload.get("new"));
-        assertEquals("prop", overload.get("new"));
-
-        copy.clear();
-        copy.putAll(original);
-
-        // only one property should be added
-        overload = new HashMap<String, Object>();
-        overload.put("new", "prop");
-        overload.put("NEW", "prop");
-
-        RemoteServiceAdminCore.overlayProperties(copy, overload);
-
-        assertEquals(original.size() + 1, copy.size());
-        for (Object key : original.keySet()) {
-            assertEquals(original.get(key), copy.get(key));
-        }
-        assertNotNull(overload.get("new"));
-        assertEquals("prop", overload.get("new"));
-
-        copy.clear();
-        copy.putAll(original);
-
-        // nothing should change here
-        overload = new HashMap<String, Object>();
-        overload.put(Constants.OBJECTCLASS, "assd");
-        overload.put(Constants.SERVICE_ID, "asasdasd");
-        RemoteServiceAdminCore.overlayProperties(copy, overload);
-
-        assertEquals(original.size(), copy.size());
-        for (Object key : original.keySet()) {
-            assertEquals(original.get(key), copy.get(key));
-        }
-
-        copy.clear();
-        copy.putAll(original);
-
-        // overwrite own prop
-        overload = new HashMap<String, Object>();
-        overload.put("MyProp", "newValue");
-        RemoteServiceAdminCore.overlayProperties(copy, overload);
-
-        assertEquals(original.size(), copy.size());
-        for (Object key : original.keySet()) {
-            if (!"MyProp".equals(key)) {
-                assertEquals(original.get(key), copy.get(key));
+        @Override
+        public Endpoint exportService(Object serviceO, BundleContext serviceContext,
+                Map<String, Object> effectiveProperties, Class[] exportedInterfaces) {
+            if (ex != null) {
+                throw ex;
             }
+            return endpoint;
         }
-        assertEquals("newValue", copy.get("MyProp"));
 
-        copy.clear();
-        copy.putAll(original);
-
-        // overwrite own prop in different case
-        overload = new HashMap<String, Object>();
-        overload.put("MYPROP", "newValue");
-        RemoteServiceAdminCore.overlayProperties(copy, overload);
-
-        assertEquals(original.size(), copy.size());
-        for (Object key : original.keySet()) {
-            if (!"MyProp".equals(key)) {
-                assertEquals(original.get(key), copy.get(key));
-            }
+        @Override
+        public Object importEndpoint(ClassLoader cl, BundleContext consumerContext, Class[] interfaces,
+                EndpointDescription endpoint) {
+            return null;
         }
-        assertEquals("newValue", copy.get("MyProp"));
-    }
-    
-    @Test
-    public void testCreateEndpointProps() {
-        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
-        EasyMock.expect(bc.getProperty("org.osgi.framework.uuid")).andReturn("some_uuid1");
-        EasyMock.replay(bc);
-
-        Map<String, Object> sd = new HashMap<String, Object>();
-        sd.put(org.osgi.framework.Constants.SERVICE_ID, 42);
-        DistributionProvider provider = null;
-        RemoteServiceAdminCore rsa = new RemoteServiceAdminCore(bc, bc, provider);
-        Map<String, Object> props = rsa.createEndpointProps(sd, new Class[]{String.class});
-
-        Assert.assertFalse(props.containsKey(org.osgi.framework.Constants.SERVICE_ID));
-        assertEquals(42, props.get(RemoteConstants.ENDPOINT_SERVICE_ID));
-        assertEquals("some_uuid1", props.get(RemoteConstants.ENDPOINT_FRAMEWORK_UUID));
-        assertEquals(Arrays.asList("java.lang.String"),
-                     Arrays.asList((Object[]) props.get(org.osgi.framework.Constants.OBJECTCLASS)));
-        assertEquals("0.0.0", props.get("endpoint.package.version.java.lang"));
     }
 }