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/02/01 15:29:13 UTC

aries-rsa git commit: [ARIES-1763] Change zookeeper discovery to EndpointEventListener

Repository: aries-rsa
Updated Branches:
  refs/heads/master 61e62f2ef -> 886a8289e


[ARIES-1763] Change zookeeper discovery to EndpointEventListener


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

Branch: refs/heads/master
Commit: 886a8289e876ad0987b5dc09aaa1740112208629
Parents: 61e62f2
Author: Christian Schneider <cs...@adobe.com>
Authored: Thu Feb 1 16:29:05 2018 +0100
Committer: Christian Schneider <cs...@adobe.com>
Committed: Thu Feb 1 16:29:05 2018 +0100

----------------------------------------------------------------------
 .../discovery/zookeeper/ZooKeeperDiscovery.java |   6 +-
 .../subscribe/EndpointListenerTracker.java      |  12 +-
 .../zookeeper/subscribe/InterfaceMonitor.java   |  16 ++-
 .../subscribe/InterfaceMonitorManager.java      | 116 +++++++++----------
 .../subscribe/InterfaceMonitorManagerTest.java  |  14 +--
 .../subscribe/InterfaceMonitorTest.java         |  13 +--
 .../aries/rsa/provider/tcp/TCPProvider.java     |  30 +++++
 .../rsa/provider/tcp/TcpProviderIntentTest.java |  70 +++++++++++
 .../rsa/core/RemoteServiceAdminInstance.java    |   1 +
 9 files changed, 189 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/ZooKeeperDiscovery.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/ZooKeeperDiscovery.java b/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/ZooKeeperDiscovery.java
index 085c074..0e03722 100644
--- a/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/ZooKeeperDiscovery.java
+++ b/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/ZooKeeperDiscovery.java
@@ -33,7 +33,7 @@ import org.apache.zookeeper.ZooKeeper;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedService;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
 import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,7 +47,7 @@ public class ZooKeeperDiscovery implements Watcher, ManagedService {
     private final BundleContext bctx;
 
     private PublishingEndpointListenerFactory endpointListenerFactory;
-    private ServiceTracker<EndpointListener, EndpointListener> endpointListenerTracker;
+    private ServiceTracker<EndpointEventListener, EndpointEventListener> endpointListenerTracker;
     private InterfaceMonitorManager imManager;
     private ZooKeeper zkClient;
     private boolean closed;
@@ -62,7 +62,7 @@ public class ZooKeeperDiscovery implements Watcher, ManagedService {
     public synchronized void updated(Dictionary<String, ?> configuration) throws ConfigurationException {
         LOG.debug("Received configuration update for Zookeeper Discovery: {}", configuration);
         // make changes only if config actually changed, to prevent unnecessary ZooKeeper reconnections
-        if (!ZooKeeperDiscovery.toMap(configuration).equals(ZooKeeperDiscovery.toMap(curConfiguration))) {
+        if (!toMap(configuration).equals(toMap(curConfiguration))) {
             stop(false);
             curConfiguration = configuration;
             // config is null if it doesn't exist, is being deleted or has not yet been loaded

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/EndpointListenerTracker.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/EndpointListenerTracker.java b/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/EndpointListenerTracker.java
index 5909ee0..6e6ed1b 100644
--- a/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/EndpointListenerTracker.java
+++ b/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/EndpointListenerTracker.java
@@ -20,36 +20,36 @@ package org.apache.aries.rsa.discovery.zookeeper.subscribe;
 
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
 import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * Tracks interest in EndpointListeners. Delegates to InterfaceMonitorManager to manage
  * interest in the scopes of each EndpointListener.
  */
-public class EndpointListenerTracker extends ServiceTracker<EndpointListener, EndpointListener> {
+public class EndpointListenerTracker extends ServiceTracker<EndpointEventListener, EndpointEventListener> {
     private final InterfaceMonitorManager imManager;
 
     public EndpointListenerTracker(BundleContext bctx, InterfaceMonitorManager imManager) {
-        super(bctx, EndpointListener.class, null);
+        super(bctx, EndpointEventListener.class, null);
         this.imManager = imManager;
     }
 
     @Override
-    public EndpointListener addingService(ServiceReference<EndpointListener> endpointListener) {
+    public EndpointEventListener addingService(ServiceReference<EndpointEventListener> endpointListener) {
         imManager.addInterest(endpointListener);
         return null;
     }
 
     @Override
-    public void modifiedService(ServiceReference<EndpointListener> endpointListener, EndpointListener service) {
+    public void modifiedService(ServiceReference<EndpointEventListener> endpointListener, EndpointEventListener service) {
         // called when an EndpointListener updates its service properties,
         // e.g. when its interest scope is expanded/reduced
         imManager.addInterest(endpointListener);
     }
 
     @Override
-    public void removedService(ServiceReference<EndpointListener> endpointListener, EndpointListener service) {
+    public void removedService(ServiceReference<EndpointEventListener> endpointListener, EndpointEventListener service) {
         imManager.removeInterest(endpointListener);
     }
 

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitor.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitor.java b/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitor.java
index bf68081..6972989 100644
--- a/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitor.java
+++ b/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitor.java
@@ -34,7 +34,8 @@ import org.apache.zookeeper.Watcher;
 import org.apache.zookeeper.ZooKeeper;
 import org.apache.zookeeper.data.Stat;
 import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.EndpointEvent;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,7 +56,7 @@ public class InterfaceMonitor implements Watcher, StatCallback {
 
     private final String znode;
     private final ZooKeeper zk;
-    private final EndpointListener endpointListener;
+    private final EndpointEventListener endpointListener;
     private final boolean recursive;
     private volatile boolean closed;
 
@@ -64,7 +65,7 @@ public class InterfaceMonitor implements Watcher, StatCallback {
 
     private EndpointDescriptionParser parser;
 
-    public InterfaceMonitor(ZooKeeper zk, String objClass, EndpointListener endpointListener, String scope) {
+    public InterfaceMonitor(ZooKeeper zk, String objClass, EndpointEventListener endpointListener, String scope) {
         this.zk = zk;
         this.znode = Utils.getZooKeeperPath(objClass);
         this.recursive = objClass == null || objClass.isEmpty();
@@ -152,7 +153,8 @@ public class InterfaceMonitor implements Watcher, StatCallback {
     public synchronized void close() {
         closed = true;
         for (EndpointDescription endpoint : nodes.values()) {
-            endpointListener.endpointRemoved(endpoint, null);
+            EndpointEvent event = new EndpointEvent(EndpointEvent.REMOVED, endpoint);
+            endpointListener.endpointChanged(event, null);
         }
         nodes.clear();
     }
@@ -170,7 +172,8 @@ public class InterfaceMonitor implements Watcher, StatCallback {
         // whatever is left in prevNodes now has been removed from Discovery
         LOG.debug("processChildren done. Nodes that are missing now and need to be removed: {}", prevNodes.values());
         for (EndpointDescription endpoint : prevNodes.values()) {
-            endpointListener.endpointRemoved(endpoint, null);
+            EndpointEvent event = new EndpointEvent(EndpointEvent.REMOVED, endpoint);
+            endpointListener.endpointChanged(event, null);
         }
         nodes = newNodes;
     }
@@ -204,7 +207,8 @@ public class InterfaceMonitor implements Watcher, StatCallback {
                     LOG.debug("Properties: {}", endpoint.getProperties());
                     if (prevEndpoint == null) {
                         // This guy is new
-                        endpointListener.endpointAdded(endpoint, null);
+                        EndpointEvent event = new EndpointEvent(EndpointEvent.ADDED, endpoint);
+                        endpointListener.endpointChanged(event, null);
                     } else if (!prevEndpoint.getProperties().equals(endpoint.getProperties())) {
                         // TODO
                     }

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManager.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManager.java b/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManager.java
index 857588c..26e4462 100644
--- a/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManager.java
+++ b/discovery/zookeeper/src/main/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManager.java
@@ -38,15 +38,16 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
 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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Manages the EndpointListeners and the scopes they are interested in.
- * For each scope with interested EndpointListeners an InterfaceMonitor is created.
+ * Manages the EndpointEventListeners and the scopes they are interested in.
+ * For each scope with interested EndpointEventListeners an InterfaceMonitor is created.
  * The InterfaceMonitor calls back when it detects added or removed external Endpoints.
- * These events are then forwarded to all interested EndpointListeners.
+ * These events are then forwarded to all interested EndpointEventListeners.
  */
 public class InterfaceMonitorManager {
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceMonitorManager.class);
@@ -54,15 +55,15 @@ public class InterfaceMonitorManager {
 
     private final BundleContext bctx;
     private final ZooKeeper zk;
-    // map of EndpointListeners and the scopes they are interested in
-    private final Map<ServiceReference<EndpointListener>, List<String>> endpointListenerScopes =
-            new HashMap<ServiceReference<EndpointListener>, List<String>>();
+    // map of EndpointEventListeners and the scopes they are interested in
+    private final Map<ServiceReference<EndpointEventListener>, List<String>> EndpointEventListenerScopes =
+            new HashMap<ServiceReference<EndpointEventListener>, List<String>>();
     // map of scopes and their interest data
     private final Map<String, Interest> interests = new HashMap<String, Interest>();
 
     protected static class Interest {
-        List<ServiceReference<EndpointListener>> endpointListeners = 
-            new CopyOnWriteArrayList<ServiceReference<EndpointListener>>();
+        List<ServiceReference<EndpointEventListener>> EndpointEventListeners = 
+            new CopyOnWriteArrayList<ServiceReference<EndpointEventListener>>();
         InterfaceMonitor monitor;
     }
 
@@ -71,26 +72,26 @@ public class InterfaceMonitorManager {
         this.zk = zk;
     }
 
-    public void addInterest(ServiceReference<EndpointListener> endpointListener) {
-        if (isOurOwnEndpointListener(endpointListener)) {
-            LOG.debug("Skipping our own EndpointListener");
+    public void addInterest(ServiceReference<EndpointEventListener> EndpointEventListener) {
+        if (isOurOwnEndpointEventListener(EndpointEventListener)) {
+            LOG.debug("Skipping our own EndpointEventListener");
             return;
         }
-        List<String> scopes = getScopes(endpointListener);
+        List<String> scopes = getScopes(EndpointEventListener);
         LOG.debug("adding Interests: {}", scopes);
         
         for (String scope : scopes) {
             String objClass = getObjectClass(scope);
-            addInterest(endpointListener, scope, objClass);
+            addInterest(EndpointEventListener, scope, objClass);
         }
     }
 
-    private static boolean isOurOwnEndpointListener(ServiceReference<EndpointListener> endpointListener) {
+    private static boolean isOurOwnEndpointEventListener(ServiceReference<EndpointEventListener> EndpointEventListener) {
         return Boolean.parseBoolean(String.valueOf(
-                endpointListener.getProperty(ZooKeeperDiscovery.DISCOVERY_ZOOKEEPER_ID)));
+                EndpointEventListener.getProperty(ZooKeeperDiscovery.DISCOVERY_ZOOKEEPER_ID)));
     }
 
-    public synchronized void addInterest(ServiceReference<EndpointListener> endpointListener, 
+    public synchronized void addInterest(ServiceReference<EndpointEventListener> EndpointEventListener, 
                                          String scope, String objClass) {
         // get or create interest for given scope and add listener to it
         Interest interest = interests.get(scope);
@@ -98,35 +99,36 @@ public class InterfaceMonitorManager {
             // create interest, add listener and start monitor
             interest = new Interest();
             interests.put(scope, interest);
-            interest.endpointListeners.add(endpointListener); // add it before monitor starts so we don't miss events
+            interest.EndpointEventListeners.add(EndpointEventListener); // add it before monitor starts so we don't miss events
             interest.monitor = createInterfaceMonitor(scope, objClass, interest);
             interest.monitor.start();
         } else {
             // interest already exists, so just add listener to it
-            if (!interest.endpointListeners.contains(endpointListener)) {
-                interest.endpointListeners.add(endpointListener);
+            if (!interest.EndpointEventListeners.contains(EndpointEventListener)) {
+                interest.EndpointEventListeners.add(EndpointEventListener);
             }
             // notify listener of all known endpoints for given scope
-            // (as EndpointListener contract requires of all added/modified listeners)
+            // (as EndpointEventListener contract requires of all added/modified listeners)
             for (EndpointDescription endpoint : interest.monitor.getEndpoints()) {
-                notifyListeners(endpoint, scope, true, Arrays.asList(endpointListener));
+                EndpointEvent event = new EndpointEvent(EndpointEvent.ADDED, endpoint);
+                notifyListeners(event, scope, Arrays.asList(EndpointEventListener));
             }
         }
 
         // add scope to listener's scopes list
-        List<String> scopes = endpointListenerScopes.get(endpointListener);
+        List<String> scopes = EndpointEventListenerScopes.get(EndpointEventListener);
         if (scopes == null) {
             scopes = new ArrayList<String>(1);
-            endpointListenerScopes.put(endpointListener, scopes);
+            EndpointEventListenerScopes.put(EndpointEventListener, scopes);
         }
         if (!scopes.contains(scope)) {
             scopes.add(scope);
         }
     }
 
-    public synchronized void removeInterest(ServiceReference<EndpointListener> endpointListener) {
-        LOG.info("removing EndpointListener interests: {}", endpointListener);
-        List<String> scopes = endpointListenerScopes.get(endpointListener);
+    public synchronized void removeInterest(ServiceReference<EndpointEventListener> EndpointEventListener) {
+        LOG.info("removing EndpointEventListener interests: {}", EndpointEventListener);
+        List<String> scopes = EndpointEventListenerScopes.get(EndpointEventListener);
         if (scopes == null) {
             return;
         }
@@ -134,46 +136,44 @@ public class InterfaceMonitorManager {
         for (String scope : scopes) {
             Interest interest = interests.get(scope);
             if (interest != null) {
-                interest.endpointListeners.remove(endpointListener);
-                if (interest.endpointListeners.isEmpty()) {
+                interest.EndpointEventListeners.remove(EndpointEventListener);
+                if (interest.EndpointEventListeners.isEmpty()) {
                     interest.monitor.close();
                     interests.remove(scope);
                 }
             }
         }
-        endpointListenerScopes.remove(endpointListener);
+        EndpointEventListenerScopes.remove(EndpointEventListener);
     }
 
     protected InterfaceMonitor createInterfaceMonitor(final String scope, String objClass, final Interest interest) {
         // holding this object's lock in the callbacks can lead to a deadlock with InterfaceMonitor
-        EndpointListener endpointListener = new EndpointListener() {
+        EndpointEventListener listener = new EndpointEventListener() {
 
-            public void endpointRemoved(EndpointDescription endpoint, String matchedFilter) {
-                notifyListeners(endpoint, scope, false, interest.endpointListeners);
-            }
-
-            public void endpointAdded(EndpointDescription endpoint, String matchedFilter) {
-                notifyListeners(endpoint, scope, true, interest.endpointListeners);
+            @Override
+            public void endpointChanged(EndpointEvent event, String filter) {
+                notifyListeners(event, scope, interest.EndpointEventListeners);
             }
         };
-        return new InterfaceMonitor(zk, objClass, endpointListener, scope);
+        return new InterfaceMonitor(zk, objClass, listener, scope);
     }
 
-    private void notifyListeners(EndpointDescription endpoint, String currentScope, boolean isAdded,
-            List<ServiceReference<EndpointListener>> endpointListeners) {
-        for (ServiceReference<EndpointListener> endpointListenerRef : endpointListeners) {
-            EndpointListener service = bctx.getService(endpointListenerRef);
+    private void notifyListeners(EndpointEvent event, String currentScope,
+            List<ServiceReference<EndpointEventListener>> EndpointEventListeners) {
+        EndpointDescription endpoint = event.getEndpoint();
+        for (ServiceReference<EndpointEventListener> EndpointEventListenerRef : EndpointEventListeners) {
+            EndpointEventListener service = bctx.getService(EndpointEventListenerRef);
             try {
-                EndpointListener endpointListener = (EndpointListener)service;
+                EndpointEventListener EndpointEventListener = (EndpointEventListener)service;
                 LOG.trace("matching {} against {}", endpoint, currentScope);
                 if (matchFilter(bctx, currentScope, endpoint)) {
                     LOG.debug("Matched {} against {}", endpoint, currentScope);
-                    notifyListener(endpoint, currentScope, isAdded, endpointListenerRef.getBundle(),
-                                   endpointListener);
+                    notifyListener(event, currentScope, EndpointEventListenerRef.getBundle(),
+                                   EndpointEventListener);
                 }
             } finally {
                 if (service != null) {
-                    bctx.ungetService(endpointListenerRef);
+                    bctx.ungetService(EndpointEventListenerRef);
                 }
             }
         }
@@ -194,18 +194,14 @@ public class InterfaceMonitorManager {
     }
 
 
-    private void notifyListener(EndpointDescription endpoint, String currentScope, boolean isAdded,
-                                Bundle endpointListenerBundle, EndpointListener endpointListener) {
-        if (endpointListenerBundle == null) {
+    private void notifyListener(EndpointEvent event, String currentScope,
+                                Bundle listenerBundle, EndpointEventListener listener) {
+        EndpointDescription endpoint = event.getEndpoint();
+        if (listenerBundle == null) {
             LOG.info("listening service was unregistered, ignoring");
-        } else if (isAdded) {
-            LOG.info("calling EndpointListener.endpointAdded: " + endpointListener + " from bundle "
-                    + endpointListenerBundle.getSymbolicName() + " for endpoint: " + endpoint);
-            endpointListener.endpointAdded(endpoint, currentScope);
         } else {
-            LOG.info("calling EndpointListener.endpointRemoved: " + endpointListener + " from bundle "
-                    + endpointListenerBundle.getSymbolicName() + " for endpoint: " + endpoint);
-            endpointListener.endpointRemoved(endpoint, currentScope);
+            LOG.info("Calling endpointchanged from bundle {} for endpoint {} ", listenerBundle.getSymbolicName(), endpoint);
+            listener.endpointChanged(event, currentScope);
         }
     }
 
@@ -214,7 +210,7 @@ public class InterfaceMonitorManager {
             interest.monitor.close();
         }
         interests.clear();
-        endpointListenerScopes.clear();
+        EndpointEventListenerScopes.clear();
     }
 
     /**
@@ -227,12 +223,12 @@ public class InterfaceMonitorManager {
     /**
      * Only for test case!
      */
-    protected synchronized Map<ServiceReference<EndpointListener>, List<String>> getEndpointListenerScopes() {
-        return endpointListenerScopes;
+    protected synchronized Map<ServiceReference<EndpointEventListener>, List<String>> getEndpointListenerScopes() {
+        return EndpointEventListenerScopes;
     }
 
     protected List<String> getScopes(ServiceReference<?> sref) {
-        return Utils.removeEmpty(StringPlus.normalize(sref.getProperty(EndpointListener.ENDPOINT_LISTENER_SCOPE)));
+        return Utils.removeEmpty(StringPlus.normalize(sref.getProperty(EndpointEventListener.ENDPOINT_LISTENER_SCOPE)));
     }
     
     public static String getObjectClass(String scope) {

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java b/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
index 41684eb..84eca09 100644
--- a/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
+++ b/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
@@ -34,7 +34,7 @@ import org.junit.Test;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
 
 public class InterfaceMonitorManagerTest {
 
@@ -42,8 +42,8 @@ public class InterfaceMonitorManagerTest {
     public void testEndpointListenerTrackerCustomizer() {
         IMocksControl c = EasyMock.createNiceControl();
         BundleContext ctx = c.createMock(BundleContext.class);
-        ServiceReference<EndpointListener> sref = createService(c, "(objectClass=mine)", "mine");
-        ServiceReference<EndpointListener> sref2 = createService(c, "(objectClass=mine)", "mine");
+        ServiceReference<EndpointEventListener> sref = createService(c, "(objectClass=mine)", "mine");
+        ServiceReference<EndpointEventListener> sref2 = createService(c, "(objectClass=mine)", "mine");
         ZooKeeper zk = c.createMock(ZooKeeper.class);
         InterfaceMonitorManager eltc = new InterfaceMonitorManager(ctx, zk);
 
@@ -87,10 +87,10 @@ public class InterfaceMonitorManagerTest {
     }
 
     @SuppressWarnings("unchecked")
-    private ServiceReference<EndpointListener> createService(IMocksControl c, String scope, String objectClass) {
-        ServiceReference<EndpointListener> sref = c.createMock(ServiceReference.class);
+    private ServiceReference<EndpointEventListener> createService(IMocksControl c, String scope, String objectClass) {
+        ServiceReference<EndpointEventListener> sref = c.createMock(ServiceReference.class);
         final Dictionary<String, String> props = new Hashtable<>();
-        props.put(EndpointListener.ENDPOINT_LISTENER_SCOPE, scope);
+        props.put(EndpointEventListener.ENDPOINT_LISTENER_SCOPE, scope);
         props.put(Constants.OBJECTCLASS, objectClass);
         String[] keys = Collections.list(props.keys()).toArray(new String[]{});
         EasyMock.expect(sref.getPropertyKeys()).andReturn(keys).anyTimes();
@@ -102,7 +102,7 @@ public class InterfaceMonitorManagerTest {
         return sref;
     }
 
-    private void assertScopeIncludes(ServiceReference<EndpointListener> sref, InterfaceMonitorManager imm) {
+    private void assertScopeIncludes(ServiceReference<EndpointEventListener> sref, InterfaceMonitorManager imm) {
         List<String> srefScope = imm.getEndpointListenerScopes().get(sref);
         assertEquals(1, srefScope.size());
         assertEquals("(objectClass=mine)", srefScope.get(0));

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorTest.java b/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
index 3a54399..e2ecece 100644
--- a/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
+++ b/discovery/zookeeper/src/test/java/org/apache/aries/rsa/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
@@ -18,11 +18,11 @@
  */
 package org.apache.aries.rsa.discovery.zookeeper.subscribe;
 
-import java.util.Collections;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
 
-import junit.framework.TestCase;
+import java.util.Collections;
 
-import org.apache.aries.rsa.discovery.zookeeper.subscribe.InterfaceMonitor;
 import org.apache.aries.rsa.discovery.zookeeper.util.Utils;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.WatchedEvent;
@@ -32,10 +32,9 @@ import org.apache.zookeeper.ZooKeeper;
 import org.apache.zookeeper.data.Stat;
 import org.easymock.EasyMock;
 import org.easymock.IMocksControl;
-import org.osgi.service.remoteserviceadmin.EndpointListener;
+import org.osgi.service.remoteserviceadmin.EndpointEventListener;
 
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
+import junit.framework.TestCase;
 
 public class InterfaceMonitorTest extends TestCase {
 
@@ -49,7 +48,7 @@ public class InterfaceMonitorTest extends TestCase {
         String interf = "es.schaaf.test";
         String node = Utils.getZooKeeperPath(interf);
 
-        EndpointListener endpointListener = c.createMock(EndpointListener.class);
+        EndpointEventListener endpointListener = c.createMock(EndpointEventListener.class);
         InterfaceMonitor im = new InterfaceMonitor(zk, interf, endpointListener, scope);
         zk.exists(eq(node), eq(im), eq(im), EasyMock.anyObject());
         EasyMock.expectLastCall().once();

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
----------------------------------------------------------------------
diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
index 4ae654f..113965e 100644
--- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
+++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
@@ -21,18 +21,28 @@ package org.apache.aries.rsa.provider.tcp;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Proxy;
 import java.net.URI;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.aries.rsa.spi.DistributionProvider;
 import org.apache.aries.rsa.spi.Endpoint;
 import org.apache.aries.rsa.spi.IntentUnsatisfiedException;
+import org.apache.aries.rsa.util.StringPlus;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.remoteserviceadmin.EndpointDescription;
 import org.osgi.service.remoteserviceadmin.RemoteConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @SuppressWarnings("rawtypes")
 public class TCPProvider implements DistributionProvider {
     private static final String TCP_CONFIG_TYPE = "aries.tcp";
+    private static final String[] SUPPORTED_INTENTS = { "osgi.basic", "osgi.sync"};
+    
+    private Logger logger = LoggerFactory.getLogger(TCPProvider.class);
 
     @Override
     public String[] getSupportedTypes() {
@@ -44,10 +54,30 @@ public class TCPProvider implements DistributionProvider {
                                   BundleContext serviceContext,
                                   Map<String, Object> effectiveProperties,
                                   Class[] exportedInterfaces) {
+
         effectiveProperties.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, getSupportedTypes());
+        Set<String> intents = getCombinedIntents(effectiveProperties);
+        intents.removeAll(Arrays.asList(SUPPORTED_INTENTS));
+        if (!intents.isEmpty()) {
+            logger.warn("Unsupported intents found: {}. Not exporting service", intents);
+            return null;
+        }
         return new TcpEndpoint(serviceO, effectiveProperties);
     }
 
+    private Set<String> getCombinedIntents(Map<String, Object> effectiveProperties) {
+        Set<String> combinedIntents = new HashSet<>();
+        List<String> intents = StringPlus.normalize(effectiveProperties.get(RemoteConstants.SERVICE_EXPORTED_INTENTS));
+        if (intents != null) {
+            combinedIntents.addAll(intents);
+        }
+        List<String> intentsExtra = StringPlus.normalize(effectiveProperties.get(RemoteConstants.SERVICE_EXPORTED_INTENTS_EXTRA));
+        if (intentsExtra != null) {
+            combinedIntents.addAll(intentsExtra);
+        }
+        return combinedIntents;
+    }
+
     @Override
     public Object importEndpoint(ClassLoader cl, 
                                  BundleContext consumerContext, 

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderIntentTest.java
----------------------------------------------------------------------
diff --git a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderIntentTest.java b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderIntentTest.java
new file mode 100644
index 0000000..c339ca6
--- /dev/null
+++ b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderIntentTest.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.provider.tcp;
+
+import static org.hamcrest.Matchers.nullValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.rsa.provider.tcp.myservice.MyService;
+import org.apache.aries.rsa.provider.tcp.myservice.MyServiceImpl;
+import org.apache.aries.rsa.spi.Endpoint;
+import org.apache.aries.rsa.util.EndpointHelper;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+
+public class TcpProviderIntentTest {
+    Class<?>[] exportedInterfaces;
+    private BundleContext bc;
+    private TCPProvider provider;
+    private MyService myService;
+    
+    @Before
+    public void before() {
+        exportedInterfaces = new Class[] {MyService.class};
+        bc = EasyMock.mock(BundleContext.class);
+        provider = new TCPProvider();
+        myService = new MyServiceImpl();
+    }
+    
+    @Test
+    public void unknownIntent() {
+        Map<String, Object> props = new HashMap<String, Object>();
+        EndpointHelper.addObjectClass(props, exportedInterfaces);
+        props.put(RemoteConstants.SERVICE_EXPORTED_INTENTS, "unknown");
+        Endpoint ep = provider.exportService(myService, bc, props, exportedInterfaces);
+        Assert.assertThat("Service should not be exported as intent is not supported", ep, nullValue());
+    }
+    
+    @Test
+    public void unknownIntentExtra() {
+        Map<String, Object> props = new HashMap<String, Object>();
+        EndpointHelper.addObjectClass(props, exportedInterfaces);
+        props.put(RemoteConstants.SERVICE_EXPORTED_INTENTS_EXTRA, "unknown");
+        Endpoint ep = provider.exportService(myService, bc, props, exportedInterfaces);
+        Assert.assertThat("Service should not be exported as intent is not supported", ep, nullValue());
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/886a8289/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminInstance.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminInstance.java b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminInstance.java
index 1b1c8da..cd435ba 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminInstance.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminInstance.java
@@ -38,6 +38,7 @@ import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
 
 public class RemoteServiceAdminInstance implements RemoteServiceAdmin {
 
+    // Context of the bundle requesting the RemoteServiceAdmin
     private final BundleContext bctx;
     private final RemoteServiceAdminCore rsaCore;