CAMEL-10169: support service lookup by service.pid in OSGi environment

Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/12224bdf
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/12224bdf
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/12224bdf

Branch: refs/heads/master
Commit: 12224bdf79cad6fa235e1a50a29a1457a8f4d718
Parents: fd1c7be
Author: Börcsök József <borcs...@sch.bme.hu>
Authored: Thu Jul 21 17:07:13 2016 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Tue Jul 26 10:51:03 2016 +0200

----------------------------------------------------------------------
 .../camel/core/osgi/OsgiServiceRegistry.java    | 34 +++++++++----
 .../camel/core/osgi/CamelMockBundleContext.java | 50 ++++++++++++++++++--
 .../camel/core/osgi/ServiceRegistryTest.java    |  6 ++-
 3 files changed, 76 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/12224bdf/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiServiceRegistry.java
----------------------------------------------------------------------
diff --git 
a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiServiceRegistry.java
 
b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiServiceRegistry.java
index b916355..e6712d6 100644
--- 
a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiServiceRegistry.java
+++ 
b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiServiceRegistry.java
@@ -28,12 +28,17 @@ import org.apache.camel.spi.Registry;
 import org.apache.camel.support.LifecycleStrategySupport;
 import org.apache.camel.util.ObjectHelper;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The OsgiServiceRegistry support to get the service object from the bundle 
context
  */
 public class OsgiServiceRegistry extends LifecycleStrategySupport implements 
Registry {
+    private static final Logger LOG = 
LoggerFactory.getLogger(OsgiCamelContextHelper.class);
     private final BundleContext bundleContext;
     private final Queue<ServiceReference<?>> serviceReferenceQueue = new 
ConcurrentLinkedQueue<ServiceReference<?>>();
     
@@ -62,18 +67,29 @@ public class OsgiServiceRegistry extends 
LifecycleStrategySupport implements Reg
     }
 
     /**
-     * It's only support to look up the ServiceReference with Class name
+     * It's only support to look up the ServiceReference with Class name or 
service PID
      */
     public Object lookupByName(String name) {
         Object service = null;
-        if (service == null) {
-            ServiceReference<?> sr = bundleContext.getServiceReference(name);  
          
-            if (sr != null) {
-                // Need to keep the track of Service
-                // and call ungetService when the camel context is closed 
-                serviceReferenceQueue.add(sr);
-                service = bundleContext.getService(sr);
-            } 
+        ServiceReference<?> sr = bundleContext.getServiceReference(name);
+        if (sr != null) {
+            // Need to keep the track of Service
+            // and call ungetService when the camel context is closed 
+            serviceReferenceQueue.add(sr);
+            service = bundleContext.getService(sr);
+        } else {
+            // trying to lookup service by PID if not found by name
+            try {
+                ServiceReference<?>[] refs = 
bundleContext.getServiceReferences((String)null, "(" + Constants.SERVICE_PID + 
"=" + name + ")");
+                if (refs != null && refs.length > 0) {
+                    // just return the first one
+                    sr = refs[0];
+                    serviceReferenceQueue.add(sr);
+                    service = bundleContext.getService(sr);
+                }
+            } catch (InvalidSyntaxException ex) {
+                LOG.error("Invalid filter to lookup bean", ex);
+            }
         }
         return service;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/12224bdf/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/CamelMockBundleContext.java
----------------------------------------------------------------------
diff --git 
a/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/CamelMockBundleContext.java
 
b/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/CamelMockBundleContext.java
index b6a410f..0c16ae1 100644
--- 
a/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/CamelMockBundleContext.java
+++ 
b/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/CamelMockBundleContext.java
@@ -35,6 +35,8 @@ import org.springframework.osgi.mock.MockBundleContext;
 import org.springframework.osgi.mock.MockServiceReference;
 
 public class CamelMockBundleContext extends MockBundleContext {
+    
+    public static final String SERVICE_PID_PREFIX = "test.";
 
     public CamelMockBundleContext(Bundle bundle) {
         super(bundle);
@@ -42,9 +44,13 @@ public class CamelMockBundleContext extends 
MockBundleContext {
 
     public Object getService(@SuppressWarnings("rawtypes") ServiceReference 
reference) {
         String[] classNames = (String[]) 
reference.getProperty(Constants.OBJECTCLASS);        
-        if (classNames[0].equals("org.apache.camel.core.osgi.test.MyService")) 
{
+        String classNames0 = classNames != null ? classNames[0] : null;
+        String pid = (String)reference.getProperty(Constants.SERVICE_PID);
+        if (classNames0 != null && 
classNames0.equals("org.apache.camel.core.osgi.test.MyService")) {
+            return new MyService();
+        } else if (pid != null && pid.equals(SERVICE_PID_PREFIX + 
"org.apache.camel.core.osgi.test.MyService")) {
             return new MyService();
-        } else if (classNames[0].equals(ComponentResolver.class.getName())) {
+        } else if (classNames0 != null && 
classNames0.equals(ComponentResolver.class.getName())) {
             return new ComponentResolver() {
                 public Component resolveComponent(String name, CamelContext 
context) throws Exception {
                     if (name.equals("file_test")) {
@@ -53,7 +59,7 @@ public class CamelMockBundleContext extends MockBundleContext 
{
                     return null;
                 }
             };
-        } else if (classNames[0].equals(LanguageResolver.class.getName())) {
+        } else if (classNames0 != null && 
classNames0.equals(LanguageResolver.class.getName())) {
             return new LanguageResolver() {
                 public Language resolveLanguage(String name, CamelContext 
context) {
                     if (name.equals("simple")) {
@@ -66,6 +72,36 @@ public class CamelMockBundleContext extends 
MockBundleContext {
             return null;
         }    
     }
+
+    public ServiceReference getServiceReference(String clazz) {
+        // lookup Java class if clazz contains dot (.) symbol
+        if (clazz.contains(".")) {
+            try {
+                final Class c = Class.forName(clazz);
+                return super.getServiceReference(clazz);
+            } catch (ClassNotFoundException ex) {
+                return null; // class not found so no service reference is 
returned
+            }
+        } else {
+            return super.getServiceReference(clazz);
+        }
+    }
+    
+    private static void addServicePID(ServiceReference[] srs, String filter) {
+        for (ServiceReference sr : srs) {
+            if (sr instanceof MockServiceReference) {
+                Dictionary properties = new Hashtable();
+                String pid = filter.replace("(" + Constants.SERVICE_PID + "=", 
"").replace(")", "");
+                properties.put(Constants.SERVICE_PID, pid);
+                for (String key : sr.getPropertyKeys()) {
+                    if (properties.get(key) == null) {
+                        properties.put(key, sr.getProperty(key));
+                    }
+                }
+                ((MockServiceReference)sr).setProperties(properties);
+            }
+        }
+    }
     
     @SuppressWarnings("rawtypes")
     public ServiceReference[] getServiceReferences(String clazz, String 
filter) throws InvalidSyntaxException {
@@ -73,7 +109,13 @@ public class CamelMockBundleContext extends 
MockBundleContext {
         if (filter != null && filter.indexOf("name=test") > 0) {
             return null;
         } else {
-            return super.getServiceReferences(clazz, filter);
+            ServiceReference[] srs = super.getServiceReferences(clazz, filter);
+            
+            // set service.pid property by filter
+            if (filter != null && filter.indexOf(Constants.SERVICE_PID + "=") 
> 0) {
+                addServicePID(srs, filter);
+            }
+            return srs;
         }
     }
    

http://git-wip-us.apache.org/repos/asf/camel/blob/12224bdf/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/ServiceRegistryTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/ServiceRegistryTest.java
 
b/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/ServiceRegistryTest.java
index 5fc3d61..78578fb 100644
--- 
a/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/ServiceRegistryTest.java
+++ 
b/components/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/ServiceRegistryTest.java
@@ -39,7 +39,11 @@ public class ServiceRegistryTest extends 
CamelOsgiTestSupport {
         Object service = 
context.getRegistry().lookupByName(MyService.class.getName());
         assertNotNull("MyService should not be null", service);
         assertTrue("It should be the instance of MyService ", service 
instanceof MyService);
-
+        
+        Object serviceByPid = 
context.getRegistry().lookupByName(CamelMockBundleContext.SERVICE_PID_PREFIX + 
MyService.class.getName());
+        assertNotNull("MyService should not be null", serviceByPid);
+        assertTrue("It should be the instance of MyService ", serviceByPid 
instanceof MyService);
+        
         Map<String, MyService> collection = 
context.getRegistry().findByTypeWithName(MyService.class);
         assertNotNull("MyService should not be null", collection);
         assertNotNull("There should have one MyService.", 
collection.get(MyService.class.getName()));

Reply via email to