Repository: aries-rsa
Updated Branches:
  refs/heads/master 8ddac37a6 -> 2792d5d64


[DOSGI-122] Implement FindHook


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

Branch: refs/heads/master
Commit: 2792d5d64bdef7abfcba815ada6bcf051126730b
Parents: 8ddac37
Author: Christian Schneider <ch...@die-schneider.net>
Authored: Wed Nov 9 21:18:21 2016 +0100
Committer: Christian Schneider <ch...@die-schneider.net>
Committed: Wed Nov 9 21:18:21 2016 +0100

----------------------------------------------------------------------
 .../aries/rsa/itests/felix/RsaTestBase.java     |   9 +-
 .../rsa/itests/felix/tcp/TestFindHook.java      | 114 +++++++++++++++++++
 .../topologymanager/importer/FilterHelper.java  |  35 ++++++
 .../importer/ListenerHookImpl.java              |  30 +----
 .../topologymanager/importer/RSFindHook.java    |  70 ++++++++++++
 .../importer/TopologyManagerImport.java         |   5 +-
 .../importer/FilterHelperTest.java              |   9 ++
 .../importer/TopologyManagerImportTest.java     |   2 +-
 8 files changed, 242 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/2792d5d6/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/RsaTestBase.java
----------------------------------------------------------------------
diff --git 
a/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/RsaTestBase.java 
b/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/RsaTestBase.java
index 1368f41..811ae61 100644
--- 
a/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/RsaTestBase.java
+++ 
b/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/RsaTestBase.java
@@ -81,6 +81,10 @@ public class RsaTestBase {
         }
     }
 
+    protected static Option echoTcpAPI() {
+        return mvn("org.apache.aries.rsa.examples.echotcp", 
"org.apache.aries.rsa.examples.echotcp.api");
+    }
+    
     protected static Option echoTcpConsumer() {
         return CoreOptions.composite(
         mvn("org.apache.felix", "org.apache.felix.scr"),
@@ -109,10 +113,13 @@ public class RsaTestBase {
                          mvn("org.apache.aries.rsa", 
"org.apache.aries.rsa.spi"),
                          mvn("org.apache.aries.rsa", 
"org.apache.aries.rsa.topology-manager"),
                          mvn("org.apache.aries.rsa.discovery", 
"org.apache.aries.rsa.discovery.local")
-                         // 
CoreOptions.vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005")
         );
     }
     
+    protected static Option debug() {
+        return 
CoreOptions.vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005");
+    }
+    
     protected static Option rsaDiscoveryConfig() {
         return composite(
                          mvn("org.apache.aries.rsa.discovery", 
"org.apache.aries.rsa.discovery.config")

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/2792d5d6/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/tcp/TestFindHook.java
----------------------------------------------------------------------
diff --git 
a/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/tcp/TestFindHook.java
 
b/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/tcp/TestFindHook.java
new file mode 100644
index 0000000..f866f7b
--- /dev/null
+++ 
b/itests/felix/src/test/java/org/apache/aries/rsa/itests/felix/tcp/TestFindHook.java
@@ -0,0 +1,114 @@
+package org.apache.aries.rsa.itests.felix.tcp;
+/**
+ * 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.
+ */
+
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeoutException;
+
+import javax.inject.Inject;
+
+import org.apache.aries.rsa.examples.echotcp.api.EchoService;
+import org.apache.aries.rsa.itests.felix.RsaTestBase;
+import org.apache.aries.rsa.itests.felix.ServerConfiguration;
+import org.apache.aries.rsa.itests.felix.TwoContainerPaxExam;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+@RunWith(TwoContainerPaxExam.class)
+public class TestFindHook extends RsaTestBase {
+
+    @Inject
+    BundleContext context;
+
+    @ServerConfiguration
+    public static Option[] remoteConfig() throws IOException {
+        return new Option[] {
+            rsaCore(),
+            rsaDiscoveryZookeeper(),
+            rsaTcp(),
+            echoTcpService(),
+            configZKServer(),
+            configZKDiscovery(),
+        };
+    }
+
+    @Configuration
+    public static Option[] configure() throws Exception {
+        return new Option[] {
+                rsaCore(),
+                rsaDiscoveryZookeeper(),
+                rsaTcp(),
+                echoTcpAPI(),
+                configZKDiscovery()
+        };
+    }
+    
+    public <T> T tryTo(String message, Callable<T> func) throws 
TimeoutException {
+        return tryTo(message, func, 5000);
+    }
+    
+    public <T> T tryTo(String message, Callable<T> func, long timeout) throws 
TimeoutException {
+        Throwable lastException = null;
+        long startTime = System.currentTimeMillis();
+        while (System.currentTimeMillis() - startTime < timeout) {
+            try {
+                T result = func.call();
+                if (result != null) {
+                    return result;
+                }
+                lastException = null;
+            } catch (Throwable e) {
+                lastException = e;
+            }
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                continue;
+            }
+        }
+        TimeoutException ex = new TimeoutException("Timeout while trying to " 
+ message);
+        if (lastException != null) {
+            ex.addSuppressed(lastException);
+        }
+        throw ex;
+    }
+
+    @Test
+    public void testFind() throws Exception {
+        Thread.sleep(1000); // FIXME Why does it only work if we wait? 
+        ServiceReference<EchoService> ref = tryTo("get EchoService", new 
Callable<ServiceReference<EchoService>>() {
+
+            @Override
+            public ServiceReference<EchoService> call() throws Exception {
+                Collection<ServiceReference<EchoService>> refs = 
context.getServiceReferences(EchoService.class, null);
+                return (refs.size() > 0)? refs.iterator().next() : null;
+            }
+        }, 10000);
+        Assert.assertNotNull(ref);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/2792d5d6/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/FilterHelper.java
----------------------------------------------------------------------
diff --git 
a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/FilterHelper.java
 
b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/FilterHelper.java
index 77b0abb..98cb94d 100644
--- 
a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/FilterHelper.java
+++ 
b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/FilterHelper.java
@@ -18,6 +18,8 @@
  */
 package org.apache.aries.rsa.topologymanager.importer;
 
+import java.util.HashSet;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import org.osgi.framework.Constants;
@@ -39,4 +41,37 @@ public final class FilterHelper {
         }
         return null;
     }
+    
+    private static final Set<String> SYSTEM_PACKAGES;
+    static {
+        SYSTEM_PACKAGES = new HashSet<String>();
+        SYSTEM_PACKAGES.add("org.osgi.service");
+        SYSTEM_PACKAGES.add("org.apache.felix");
+        SYSTEM_PACKAGES.add("org.ops4j.pax.logging");
+        SYSTEM_PACKAGES.add("ch.ethz.iks.slp");
+        SYSTEM_PACKAGES.add("org.ungoverned.osgi.service");
+        
SYSTEM_PACKAGES.add("org.springframework.osgi.context.event.OsgiBundleApplicationContextListener");
+        SYSTEM_PACKAGES.add("java.net.ContentHandler");
+    }
+    
+    public static boolean isClassExcluded(String className) {
+        if (className == null) {
+            return true;
+        }
+
+        for (String p : SYSTEM_PACKAGES) {
+            if (className.startsWith(p)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    public static String getFullFilter(String objectClass, String filter) {
+        if (objectClass == null) {
+            return filter;
+        }
+        String nameFilter = String.format("(objectClass=%s)", objectClass); 
+        return (filter == null) ? nameFilter : String.format("(&%s%s)", 
nameFilter, filter);
+    }
 }

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/2792d5d6/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImpl.java
----------------------------------------------------------------------
diff --git 
a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImpl.java
 
b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImpl.java
index 6766fc1..1ca1d19 100644
--- 
a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImpl.java
+++ 
b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/ListenerHookImpl.java
@@ -19,8 +19,6 @@
 package org.apache.aries.rsa.topologymanager.importer;
 
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
 
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -37,19 +35,6 @@ public class ListenerHookImpl implements ListenerHook {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(ListenerHookImpl.class);
 
-    // From the old impl.
-    private static final Set<String> SYSTEM_PACKAGES;
-    static {
-        SYSTEM_PACKAGES = new HashSet<String>();
-        SYSTEM_PACKAGES.add("org.osgi.service");
-        SYSTEM_PACKAGES.add("org.apache.felix");
-        SYSTEM_PACKAGES.add("org.ops4j.pax.logging");
-        SYSTEM_PACKAGES.add("ch.ethz.iks.slp");
-        SYSTEM_PACKAGES.add("org.ungoverned.osgi.service");
-        
SYSTEM_PACKAGES.add("org.springframework.osgi.context.event.OsgiBundleApplicationContextListener");
-        SYSTEM_PACKAGES.add("java.net.ContentHandler");
-    }
-
     private final BundleContext bctx;
     private final ServiceInterestListener serviceInterestListener;
     private final String frameworkUUID;
@@ -78,7 +63,7 @@ public class ListenerHookImpl implements ListenerHook {
                 continue;
             }
 
-            if (isClassExcluded(className)) {
+            if (FilterHelper.isClassExcluded(className)) {
                 LOG.debug("Skipping import request for excluded class [{}]", 
className);
                 continue;
             }
@@ -100,19 +85,6 @@ public class ListenerHookImpl implements ListenerHook {
         }
     }
 
-    private static boolean isClassExcluded(String className) {
-        if (className == null) {
-            return true;
-        }
-
-        for (String p : SYSTEM_PACKAGES) {
-            if (className.startsWith(p)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     String extendFilter(String filter) {
         return "(&" + filter + "(!(" + RemoteConstants.ENDPOINT_FRAMEWORK_UUID 
+ "=" + frameworkUUID + ")))";
     }

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/2792d5d6/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/RSFindHook.java
----------------------------------------------------------------------
diff --git 
a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/RSFindHook.java
 
b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/RSFindHook.java
new file mode 100644
index 0000000..722cee2
--- /dev/null
+++ 
b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/RSFindHook.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.importer;
+
+import java.util.Collection;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.hooks.service.FindHook;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RSFindHook implements FindHook {
+    private static final Logger LOG = 
LoggerFactory.getLogger(RSFindHook.class);
+    
+    private BundleContext bctx;
+    private String frameworkUUID;
+    private ServiceInterestListener serviceInterestListener;
+
+    public RSFindHook(BundleContext bc, ServiceInterestListener 
serviceInterestListener) {
+        this.bctx = bc;
+        this.frameworkUUID = bctx.getProperty(Constants.FRAMEWORK_UUID);
+        this.serviceInterestListener = serviceInterestListener;
+    }
+
+    @Override
+    public void find(BundleContext context, String name, String filter, 
boolean allServices,
+                     Collection<ServiceReference<?>> references) {
+        if (context.equals(bctx)) {
+            LOG.debug("ListenerHookImpl: skipping request from myself");
+            return;
+        }
+        
+        String fullFilter = FilterHelper.getFullFilter(name, filter);
+        
+        if (fullFilter == null) {
+            LOG.debug("skipping empty filter");
+            return;
+        }
+        String className = name != null ? name : 
FilterHelper.getObjectClass(fullFilter);
+        if (FilterHelper.isClassExcluded(className)) {
+            LOG.debug("Skipping import request for excluded class [{}]", 
className);
+            return;
+        }
+        String exFilter = extendFilter(fullFilter);
+        serviceInterestListener.addServiceInterest(exFilter);
+    }
+
+    String extendFilter(String filter) {
+        return "(&" + filter + "(!(" + RemoteConstants.ENDPOINT_FRAMEWORK_UUID 
+ "=" + frameworkUUID + ")))";
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/2792d5d6/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 3b98710..54a1c56 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
@@ -33,6 +33,7 @@ import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.hooks.service.FindHook;
 import org.osgi.framework.hooks.service.ListenerHook;
 import org.osgi.service.remoteserviceadmin.EndpointDescription;
 import org.osgi.service.remoteserviceadmin.EndpointListener;
@@ -59,6 +60,7 @@ public class TopologyManagerImport implements 
EndpointListener, RemoteServiceAdm
     private final BundleContext bctx;
     private Set<RemoteServiceAdmin> rsaSet;
     private final ListenerHookImpl listenerHook;
+    private RSFindHook findHook;
 
     /**
      * If set to false only one service is imported for each import interest 
even it multiple services are
@@ -88,18 +90,19 @@ public class TopologyManagerImport implements 
EndpointListener, RemoteServiceAdm
     private final Map<String /* filter */, List<ImportRegistration>> 
importedServices
         = new HashMap<String, List<ImportRegistration>>();
     
-
     public TopologyManagerImport(BundleContext bc) {
         this.rsaSet = new HashSet<RemoteServiceAdmin>();
         bctx = bc;
         endpointListenerManager = new EndpointListenerManager(bctx, this);
         execService = new ThreadPoolExecutor(5, 10, 50, TimeUnit.SECONDS, new 
LinkedBlockingQueue<Runnable>());
         listenerHook = new ListenerHookImpl(bc, this);
+        findHook = new RSFindHook(bc, this);
     }
     
     public void start() {
         bctx.registerService(RemoteServiceAdminListener.class, this, null);
         bctx.registerService(ListenerHook.class, listenerHook, null);
+        bctx.registerService(FindHook.class, findHook, null);
         endpointListenerManager.start();
     }
 

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/2792d5d6/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/FilterHelperTest.java
----------------------------------------------------------------------
diff --git 
a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/FilterHelperTest.java
 
b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/FilterHelperTest.java
index 5644073..cf4ab00 100644
--- 
a/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/FilterHelperTest.java
+++ 
b/topology-manager/src/test/java/org/apache/aries/rsa/topologymanager/importer/FilterHelperTest.java
@@ -39,6 +39,15 @@ public class FilterHelperTest {
         Assert.assertEquals(className, objClass);
     }
     
+    @Test
+    public void testGetFullFilter() {
+        String filter = "(a=b)";
+        String objectClass = "my.Test";
+        Assert.assertEquals(filter, FilterHelper.getFullFilter(null, filter));
+        Assert.assertEquals("(objectClass=my.Test)", 
FilterHelper.getFullFilter(objectClass, null));
+        Assert.assertEquals("(&(objectClass=my.Test)(a=b))", 
FilterHelper.getFullFilter(objectClass, filter));
+    }
+    
     class InnerClass {
     }
 

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/2792d5d6/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 dc17486..07fb0ae 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
@@ -58,7 +58,7 @@ public class TopologyManagerImportTest {
         EasyMock.expect(bc.registerService(EasyMock.anyObject(Class.class),
                                            EasyMock.anyObject(),
                                            
(Dictionary)EasyMock.anyObject())).andReturn(sreg).anyTimes();
-        
EasyMock.expect(bc.getProperty(Constants.FRAMEWORK_UUID)).andReturn("myid");
+        
EasyMock.expect(bc.getProperty(Constants.FRAMEWORK_UUID)).andReturn("myid").atLeastOnce();
 
         EndpointDescription endpoint = c.createMock(EndpointDescription.class);
         RemoteServiceAdmin rsa = c.createMock(RemoteServiceAdmin.class);

Reply via email to