cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From egl...@apache.org
Subject svn commit: r738547 [2/2] - in /cxf/sandbox/dosgi: discovery/local/ discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ discovery/local/src/main/java/org/osgi/service/discovery/ dsw/cxf-dsw/ dsw/cxf-dsw/src/main/java/org/apache/cxf/dosg...
Date Wed, 28 Jan 2009 17:16:21 GMT
Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java Wed Jan 28 17:16:16 2009
@@ -21,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
@@ -32,85 +33,91 @@
 import org.apache.cxf.dosgi.dsw.handlers.ClientServiceFactory;
 import org.apache.cxf.dosgi.dsw.handlers.ConfigurationTypeHandler;
 import org.apache.cxf.dosgi.dsw.service.CxfDistributionProvider;
+
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.discovery.ServiceEndpointDescription;
-import org.osgi.service.discovery.ServiceListener;
+import org.osgi.service.discovery.DiscoveredServiceTracker;
+import org.osgi.service.discovery.DiscoveredServiceNotification;
+
+import static org.osgi.service.discovery.DiscoveredServiceNotification.AVAILABLE;
+import static org.osgi.service.discovery.DiscoveredServiceNotification.MODIFIED;
+import static org.osgi.service.discovery.DiscoveredServiceNotification.UNAVAILABLE;
+import static org.osgi.service.discovery.DiscoveredServiceTracker.PROP_KEY_MATCH_CRITERIA_FILTERS;
+import static org.osgi.service.discovery.DiscoveredServiceTracker.PROP_KEY_MATCH_CRITERIA_INTERFACES;
+
 
 public class AbstractClientHook extends AbstractHook {
     
     private static final Logger LOG = Logger.getLogger(AbstractClientHook.class.getName());
 
+    private DiscoveredServiceTracker tracker;
+    private Dictionary trackerProperties = new Hashtable();
+    private ServiceRegistration trackerRegistration;
+
     protected AbstractClientHook(BundleContext bc, CxfDistributionProvider dp) {
         super(bc, dp);
+        tracker = new DiscoveryCallback();
+        trackerRegistration = 
+            bc.registerService(DiscoveredServiceTracker.class.getName(),
+                               tracker,
+                               trackerProperties);
     }
     
     protected void processClientDescriptions(BundleContext requestingContext, 
                                              String interfaceName, 
-                                             String filter, 
-                                             boolean matchAll, 
-                                             boolean allServices) {
-        processServiceDescriptions(getServiceDescriptions(requestingContext, interfaceName, filter, false),
-                                   requestingContext,
-                                   interfaceName,
-                                   filter,
-                                   allServices);        
+                                             String filter) {
+        
+        if (!lookupCurrentBundle(requestingContext, interfaceName, filter)) {
+            lookupDiscoveryService(interfaceName, filter);
+        }
     }
     
-    protected void processServiceDescriptions(List<ServiceEndpointDescription> sds,
-                                              BundleContext requestingContext, 
-                                              String interfaceName, 
-                                              String filter, 
-                                              boolean allServices) {
-
-        for (ServiceEndpointDescription sd  : sds) {
-            
+    protected void processServiceDescription(ServiceEndpointDescription sd,
+                                             BundleContext requestingContext, 
+                                             String interfaceName) {
             
-            if (sd.getProperty(Constants.REMOTE_INTERFACES_PROPERTY) == null) {
-                continue;
-            }
+        if (sd.getProperty(Constants.REMOTE_INTERFACES_PROPERTY) == null) {
+            return;
+        }
             
-            ConfigurationTypeHandler handler = 
-                ServiceHookUtils.getHandler(getContext(), sd, getDistributionProvider(), getHandlerProperties());
-            if (handler == null) {
-                continue;
-            }
+        ConfigurationTypeHandler handler = 
+            ServiceHookUtils.getHandler(getContext(), sd, getDistributionProvider(), getHandlerProperties());
+        if (handler == null) {
+            return;
+        }
             
-            try {
-                Class<?> iClass = getContext().getBundle().loadClass(interfaceName);
-                if (iClass != null) {
-                    BundleContext actualContext = getContext();
-                    if (!allServices) {
-                        Class<?> actualClass = requestingContext.getBundle().loadClass(interfaceName);
-                        if (actualClass != iClass) {
-                            LOG.info("Class " + interfaceName + " loaded by DSW's bundle context is not "
-                                     + "equal to the one loaded by the requesting bundle context, "
-                                     + "DSW will use the requesting bundle context to register "
-                                     + "a proxy service");
-                            iClass = actualClass;
-                            actualContext = requestingContext;
-                        }
-                    }
-                    synchronized(this) {
-                        ServiceReference sref = actualContext.getServiceReference(interfaceName);
-                        if (sref == null || sref.getProperty(Constants.DSW_CLIENT_ID) == null) {
+        try {
+            Class<?> iClass = getContext().getBundle().loadClass(interfaceName);
+            if (iClass != null) {
+                BundleContext actualContext = getContext();
+                Class<?> actualClass = requestingContext.getBundle().loadClass(interfaceName);
+                if (actualClass != iClass) {
+                    LOG.info("Class " + interfaceName + " loaded by DSW's bundle context is not "
+                                 + "equal to the one loaded by the requesting bundle context, "
+                                 + "DSW will use the requesting bundle context to register "
+                                 + "a proxy service");
+                    iClass = actualClass;
+                    actualContext = requestingContext;
+                }
+                synchronized(this) {
+                    ServiceReference sref = actualContext.getServiceReference(interfaceName);
+                    if (sref == null || sref.getProperty(Constants.DSW_CLIENT_ID) == null) {
                             
-                            // at least we won't register the factory for the same interface/filter
-                            // combination twice - ListenerHook.added() and 
-                            // ListenerHook.serviceReferencesRequested() may get called at the same time
+                        // at least we won't register the factory for the same interface/filter
+                        // combination twice - ListenerHook.added() and 
+                        // ListenerHook.serviceReferencesRequested() may get called at the same time
                             
-                            actualContext.registerService(new String[]{interfaceName},
-                                      new ClientServiceFactory(actualContext, iClass, sd, handler),
-                                      new Hashtable<String, Object>(getProperties(sd)));
-                        }
-                        
+                        actualContext.registerService(new String[]{interfaceName},
+                                                      new ClientServiceFactory(actualContext, iClass, sd, handler),
+                                                      new Hashtable<String, Object>(getProperties(sd)));
                     }
+                        
                 }
-            } catch (ClassNotFoundException ex) {
-                LOG.warning("No class can be found for " + interfaceName);
-                continue;
             }
+        } catch (ClassNotFoundException ex) {
+            LOG.warning("No class can be found for " + interfaceName);
         }
     }
     
@@ -122,81 +129,88 @@
         props.put(Constants.REMOTE_PROPERTY_PREFIX, "true");
         return props;
     }
-    
-    @SuppressWarnings("unchecked")
-    protected List<ServiceEndpointDescription> getServiceDescriptions(
-        final BundleContext  context, 
-        final String interfaceName, 
-        final String filterValue, 
-        final boolean matchAll) {
-        
-        // if bundle has remote-services.xml attached then those metadata takes precedence
-        List<ServiceEndpointDescription> sds = new ArrayList<ServiceEndpointDescription>();
+
+    protected synchronized boolean lookupCurrentBundle(BundleContext context, 
+                                                       String interfaceName, 
+                                                       String filter) {     
+        // if bundle has remote-services.xml attached then those metadata 
+        // take precedence
+        List<ServiceEndpointDescription> sds = 
+           new ArrayList<ServiceEndpointDescription>();
+
+        // REVISIT: temporary disable, re-enable before merge!!!
         if (checkBundle()) {
             sds.addAll(OsgiUtils.getRemoteReferences(context.getBundle(), 
                                                      new String[]{interfaceName}, 
                                                      Collections.EMPTY_MAP, 
                                                      false));
-        }
-        // should we try discovery service even if we've already
-        // found some SDs as it may find more suitable SDs ?
-        if (sds.isEmpty()) {
-            // try discovery service
-            
-            // Discovery RI uses standard "objectClass" property key, 
-            // so we cano just reuse the given filter instead of constructing
-            // a modified one. 
-
-            Collection<ServiceEndpointDescription> discovered = 
-                getFromDiscoveryService(interfaceName, filterValue);
-            if (discovered.size() != 0) {
-                LOG.info("synchronous lookup discovered " + discovered.size()
-                         + " references for interface: " + interfaceName);
-                sds.addAll(discovered);
-            } else {
-                LOG.info("nothing discovered initially for interface: " 
-                         + interfaceName +  ", fallback to async lookup");
-                if (filterValue != null && filterValue.length() > 0) {
-                    LOG.fine("installing service listener for: " + filterValue);
-                    listenToDiscoveryService(
-                        new ServiceListener() {
-                            public void serviceAvailable(ServiceEndpointDescription sd) {
-                                LOG.info("received serviceAvailable callback: " 
-                                         + sd.getProperties());
-                                List<ServiceEndpointDescription> notified = 
-                                    new ArrayList<ServiceEndpointDescription>();
-                                notified.add(sd);
-                                processServiceDescriptions(notified,
-                                                           context,
-                                                           interfaceName,
-                                                           filterValue,
-                                                           matchAll);
-                                LOG.fine("removing service listener : " + this);
-                                unlistenToDiscoveryService(this);
-                            }
-                            public void serviceModified(ServiceEndpointDescription oldSD,
-                                                        ServiceEndpointDescription newSD) {
-                                // we don't currently use this notification, but we could do
-                                // so to allow to support transparent service re-location 
-                            }
-                            public void serviceUnavailable(ServiceEndpointDescription sd) {
-                                // we don't currently use this notification, but we could do
-                                // so to allow to drive transparent fail-over
-                            }                        
-                        },
-                        filterValue);
-                }
+
+            for (ServiceEndpointDescription found : sds) {
+                processServiceDescription(found,
+                                          context,
+                                          interfaceName); 
             }
         }
-        
-        // do it just in case too for the moment
-        
-        Filter filter = OsgiUtils.createFilter(context, filterValue);
-        if (filter != null) {
-            OsgiUtils.matchServiceDescriptions(sds, interfaceName, filter, true);
+        return sds.size() > 0;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected synchronized void lookupDiscoveryService(String interfaceName, String filterValue) {
+
+        if (interfaceName != null) {
+            append(trackerProperties,
+                   PROP_KEY_MATCH_CRITERIA_INTERFACES,
+                   interfaceName); 
         }
-        
-        return sds;
+
+        if (filterValue != null) {
+            append(trackerProperties,
+                   PROP_KEY_MATCH_CRITERIA_FILTERS,
+                   filterValue); 
+        }
+
+        trackerRegistration.setProperties(trackerProperties);
     }
-    
+
+    private void append(Dictionary properties, String key, String additional) {
+        Collection existing = (Collection)properties.get(key);
+        if (existing == null) {
+            existing = new ArrayList<String>();
+            properties.put(key, existing);
+        }
+        existing.add(additional);
+    }
+
+    private class DiscoveryCallback implements DiscoveredServiceTracker {
+        public void serviceChanged(DiscoveredServiceNotification notification) {
+            ServiceEndpointDescription notified =
+                notification.getServiceEndpointDescription();
+            switch (notification.getType()) {
+
+            case AVAILABLE:
+                LOG.info("Notified - AVAILABLE: " + notified.getProvidedInterfaces());
+                // REVISIT: OSGi bug 1022 will allow the matching interface
+                // name to be gleaned from the notification, for now we just
+                // assume its the first interface exposed by the SED
+                String interfaceName =
+                    (String)notified.getProvidedInterfaces().toArray()[0];
+                processServiceDescription(notified,
+                                          getContext(),
+                                          interfaceName);
+                break;
+
+            case UNAVAILABLE:
+                LOG.info("Notified - UNAVAILABLE: " + notified.getProvidedInterfaces());
+                // we don't currently use this notification, but we could do
+                // so to allow to drive transparent fail-over
+                break;
+
+            case MODIFIED:
+                LOG.info("Notified - MODIFIED: " + notified.getProvidedInterfaces());
+                // we don't currently use this notification, but we could do
+                // so to allow to support transparent service re-location
+                break;
+            }
+        }
+    }    
 }

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractHook.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractHook.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractHook.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractHook.java Wed Jan 28 17:16:16 2009
@@ -30,9 +30,6 @@
 import org.apache.cxf.dosgi.dsw.service.CxfDistributionProvider;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.service.discovery.Discovery;
-import org.osgi.service.discovery.ServiceEndpointDescription;
-import org.osgi.service.discovery.ServiceListener;
 
 public abstract class AbstractHook {
     private final CxfDistributionProvider distributionProvider;
@@ -87,61 +84,6 @@
         return props;
     }
     
-    protected Collection<ServiceEndpointDescription> getFromDiscoveryService(
-        String interfaceName, String filterValue) {
-       
-        // not clear what to do about allServices parameter, according to docs its purpose
-        // is to indicate that the call originated from BundleContext.getAllReferences()
-       
-        // TODO : Use a ServiceTracker if we know that 
-        // the requesting bundle is also relying on a ServiceTracker 
-       
-        OsgiService<Discovery> pair = OsgiUtils.getOsgiService(getContext(), Discovery.class);
-        if (pair != null) {
-            try {
-                Collection sds =
-                    pair.getService().findService(interfaceName, filterValue);
-                if (sds != null) {
-                    return (Collection<ServiceEndpointDescription>)sds;
-                }
-            } finally {
-                pair.ungetService(getContext());
-            }
-        }
-       
-        return Collections.emptyList();
-    }
-    
-    protected Collection<ServiceEndpointDescription> listenToDiscoveryService(
-        ServiceListener listener, String filterValue) {
-              
-        OsgiService<Discovery> pair = OsgiUtils.getOsgiService(getContext(), Discovery.class);
-        if (pair != null) {
-            try {
-                pair.getService().addServiceListener(listener, filterValue);
-            } finally {
-                pair.ungetService(getContext());
-            }
-        }
-       
-        return Collections.emptyList();
-    }
-
-    protected Collection<ServiceEndpointDescription> unlistenToDiscoveryService(
-        ServiceListener listener) {
-              
-        OsgiService<Discovery> pair = OsgiUtils.getOsgiService(getContext(), Discovery.class);
-        if (pair != null) {
-            try {
-                pair.getService().removeServiceListener(listener);
-            } finally {
-                pair.ungetService(getContext());
-            }
-        }
-       
-        return Collections.emptyList();
-    }
-
     
     protected String getIdentificationProperty() {
         Bundle b = bc.getBundle();

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java Wed Jan 28 17:16:16 2009
@@ -49,6 +49,7 @@
         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");
     }
     
     public CxfListenerHook(BundleContext bc, CxfDistributionProvider dp) {
@@ -76,12 +77,9 @@
                     continue;
                 }
                 
-                
                 processClientDescriptions(listener.getBundleContext(), 
                                           className, 
-                                          listener.getFilter(), 
-                                          false, 
-                                          false);            
+                                          listener.getFilter());            
         }
     }
     

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHook.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHook.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHook.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHook.java Wed Jan 28 17:16:16 2009
@@ -30,12 +30,15 @@
 import org.apache.cxf.endpoint.Server;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.discovery.ServiceEndpointDescription;
 
 public class CxfPublishHook extends AbstractHook {
     
-    Map<ServiceReference, List<EndpointInfo>> endpoints
-        = new LinkedHashMap<ServiceReference, List<EndpointInfo>>();
+    protected Map<ServiceReference, List<EndpointInfo>> endpoints =
+        new LinkedHashMap<ServiceReference, List<EndpointInfo>>();
+    private Map<ServiceReference, ServiceRegistration> publications =
+        new LinkedHashMap<ServiceReference, ServiceRegistration>();
     
     public CxfPublishHook(BundleContext bc, CxfDistributionProvider dpService) {
         super(bc, dpService);
@@ -74,9 +77,12 @@
             OsgiUtils.flattenServiceDescription(sd);
         for (int i = 0; i < publishableInterfaces.length; i++) {    
             boolean isPublished = false;
-            Server server = createServer(sref, sd);
-            if (server != null && ServiceHookUtils.publish(getContext(), sd)) {
-                isPublished = true;
+            Server server = createServer(sref, flatList[i]);
+            if (server != null) {
+                ServiceRegistration publication = 
+                    ServiceHookUtils.publish(getContext(), flatList[i]);
+                publications.put(sref, publication);
+                isPublished = publication != null;
             }
         
             synchronized(endpoints) {
@@ -109,16 +115,18 @@
         }
         if (endpointList != null) {
             for (EndpointInfo ei : endpointList) {
-                ServiceHookUtils.unregisterServer(ei);
+                ServiceHookUtils.unregisterServer(publications.get(sref), ei);
             }
         }
     }
     
     public void removeEndpoints() {
         synchronized(endpoints) {
-            for (List<EndpointInfo> endpointList : endpoints.values()) {
+            for (ServiceReference sref : endpoints.keySet()) {
+                List<EndpointInfo> endpointList = endpoints.get(sref);
                 for (EndpointInfo ei : endpointList) {
-                    ServiceHookUtils.unregisterServer(ei);
+                    ServiceHookUtils.unregisterServer(publications.get(sref), 
+                                                      ei);
                 }
             }
             endpoints.clear();

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java Wed Jan 28 17:16:16 2009
@@ -19,7 +19,9 @@
 package org.apache.cxf.dosgi.dsw.hooks;
 
 import java.util.Collections;
+import java.util.Dictionary;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.logging.Logger;
@@ -33,10 +35,17 @@
 import org.apache.cxf.dosgi.dsw.handlers.IntentUnsatifiedException;
 import org.apache.cxf.dosgi.dsw.service.CxfDistributionProvider;
 import org.apache.cxf.endpoint.Server;
+
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.discovery.Discovery;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.discovery.ServiceEndpointDescription;
+import org.osgi.service.discovery.ServicePublication;
+
+
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_SERVICE_INTERFACE_NAME;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_SERVICE_PROPERTIES;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_ENDPOINT_LOCATION;
 
 public final class ServiceHookUtils {
     
@@ -46,32 +55,18 @@
         
     }
     
-    public static boolean publish(BundleContext bc, ServiceEndpointDescription sd) {
+    public static ServiceRegistration publish(BundleContext bc, ServiceEndpointDescription sd) {
         
-        ServiceEndpointDescription sdPublished = null;
-        OsgiService<Discovery> pair = OsgiUtils.getOsgiService(bc, Discovery.class);
-        if (pair != null) {
-            try {
-                Map<String, String> javaInterfaces = getJavaInterfaceVersionMap(sd);
-                Map<String, String> endpointInterfaces = getJavaInterfaceEndpointInterfaceMap(sd);
-                Map<String, Object> properties = getPropertiesMap(sd);
-                LOG.info("publish java interfaces: " + javaInterfaces
-                         + ",\nendpoint interfaces: " + endpointInterfaces
-                         + ",\nproperties: " + properties);
-                
-                sdPublished = pair.getService().publishService(javaInterfaces,
-                                                               endpointInterfaces,
-                                                               properties);
-                
-                if (sdPublished != null) {
-                    LOG.info("Remote " + sd.getInterfaceNames().toArray()[0]
-                             + " endpoint has been published into Discovery service");
-                }
-            } finally {
-                pair.ungetService(bc);
-            }
+        ServiceRegistration publication = 
+            bc.registerService(ServicePublication.class.getName(),
+                               new ServicePublication() {},
+                               getPublicationProperties(sd));
+
+        if (publication != null) {
+            LOG.info("Remote " + sd.getProvidedInterfaces().toArray()[0]
+                     + " endpoint published via Discovery service");
         }
-        return sdPublished != null;
+        return publication;
     }
     
     public static Server createServer(ConfigurationTypeHandler handler,
@@ -85,7 +80,7 @@
             return null;
         }
 
-        String interfaceName = (String)sd.getInterfaceNames().toArray()[0];
+        String interfaceName = (String)sd.getProvidedInterfaces().toArray()[0];
         // this is an extra sanity check, but do we really need it now ?
         Class<?> interfaceClass = ClassUtils.getInterfaceClass(serviceObject, interfaceName); 
                                                                
@@ -110,7 +105,8 @@
         return null;
     }
     
-    public static void unregisterServer(EndpointInfo ei) {
+    public static void unregisterServer(ServiceRegistration publication, 
+                                        EndpointInfo ei) {
         
         try {
             Server server = ei.getServer();
@@ -124,15 +120,10 @@
         }
         
         if (ei.isPublished()) {
-            OsgiService<Discovery> pair = OsgiUtils.getOsgiService(ei.getContext(), 
-                                                                   Discovery.class);
-            if (pair != null) {
-                LOG.info("Unpublishing Service Description for "  
-                          + ei.getServiceDescription().getInterfaceNames().toArray()[0] 
-                          + " from a Discovery service "); 
-                pair.getService().unpublishService(ei.getServiceDescription());
-                pair.ungetService(ei.getContext());
-            }
+            LOG.info("Unpublishing Service Description for "  
+                     + ei.getServiceDescription().getProvidedInterfaces().toArray()[0] 
+                     + " from a Discovery service "); 
+            publication.unregister();
         }
     }
     
@@ -148,25 +139,23 @@
         return sref != null && sref.getProperty(Constants.DSW_CLIENT_ID) != null;
     }
     
-    private static Map<String, String> getJavaInterfaceVersionMap(ServiceEndpointDescription sd) {
-        Map<String, String> interfaceNames = new HashMap<String, String>();
-        Iterator iNames = sd.getInterfaceNames().iterator();
-        while (iNames.hasNext()) {
-            String interfaceName = (String)iNames.next();
-            interfaceNames.put(interfaceName, sd.getVersion(interfaceName));
-        }
-        return interfaceNames;
-    }
-    
-    private static Map<String, String> getJavaInterfaceEndpointInterfaceMap(ServiceEndpointDescription sd) {
-        return Collections.emptyMap();
-    }
-    
-    private static Map<String, Object> getPropertiesMap(ServiceEndpointDescription sd) {
+    private static Map<String, Object> getServiceProperties(ServiceEndpointDescription sd) {
         Map<String, Object> props = new HashMap<String, Object>();
         for (Object key : sd.getPropertyKeys()) {
             props.put(key.toString(), sd.getProperty(key.toString()));
         }
+        LOG.info("service properties: " + props);
+        return props;
+    }
+
+    private static Dictionary getPublicationProperties(ServiceEndpointDescription sd) {
+        Dictionary props = new Hashtable();
+        props.put(PROP_KEY_SERVICE_INTERFACE_NAME, sd.getProvidedInterfaces());
+        props.put(PROP_KEY_SERVICE_PROPERTIES, getServiceProperties(sd));
+        if (sd.getLocation() != null) {
+            props.put(PROP_KEY_ENDPOINT_LOCATION, sd.getLocation());
+	}
+        LOG.info("publication properties: " + props);
         return props;
     }
 }

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ServiceEndpointDescriptionImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ServiceEndpointDescriptionImpl.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ServiceEndpointDescriptionImpl.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ServiceEndpointDescriptionImpl.java Wed Jan 28 17:16:16 2009
@@ -30,6 +30,8 @@
 
 import org.osgi.service.discovery.ServiceEndpointDescription;
 
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_ENDPOINT_LOCATION;
+
 public class ServiceEndpointDescriptionImpl implements ServiceEndpointDescription {
 
     private static final Logger LOG = 
@@ -62,10 +64,11 @@
     
     public Object getProperty(String key) {
         return properties.get(key);
+
     }
 
     public Map<String, Object> getProperties() {
-        return Collections.unmodifiableMap(properties);
+        return properties;
     }
 
     public Collection getPropertyKeys() {
@@ -89,12 +92,12 @@
         }
         
         
-        return interfaceNames.equals(other.getInterfaceNames())
+        return interfaceNames.equals(other.getProvidedInterfaces())
                && properties.equals(other.getProperties());
     }
 
     public URL getLocation() {
-        Object value = properties.get(ServiceEndpointDescription.PROP_KEY_SERVICE_LOCATION);
+        Object value = properties.get(PROP_KEY_ENDPOINT_LOCATION);
         if (value == null) {
             return null;
         }
@@ -108,15 +111,19 @@
         return null;
     }
 
-    public Collection<String> getInterfaceNames() {
+    public Collection<String> getProvidedInterfaces() {
         return interfaceNames;
     }
 
-    public String getProtocolSpecificInterfaceName(String interfaceName) {
+    public String getVersion(String interfaceName) {
+        return "0.0";
+    }
+
+    public String getEndpointInterfaceName(String interfaceName) {
         return interfaceName;
     }
 
-    public String getVersion(String interfaceName) {
-        return "0.0";
+    public String getEndpointID() {
+        return null;
     }
 }

Added: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java (added)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.discovery;
+
+/**
+ * Interface for notification on discovered services.
+ * 
+ * @version $Revision$
+ */
+public interface DiscoveredServiceNotification {
+
+	/**
+	 * Notification indicating that a service matching the listening criteria has been
+	 * discovered.
+	 * <p>
+	 * The value of <code>AVAILABLE</code> is 0x00000001.
+	 */
+	public final static int AVAILABLE = 0x00000001;
+
+	/**
+	 * Notification indicating that the properties of a previously discovered service
+	 * have changed.
+	 * <p>
+	 * The value of <code>MODIFIED</code> is 0x00000002.
+	 */
+	public final static int MODIFIED = 0x00000002;
+
+	/**
+	 * Notification indicating that a previously discovered service is no longer known
+	 * to discovery.
+	 * <p>
+	 * The value of <code>UNAVAILABLE</code> is 0x00000004.
+	 */
+	public final static int UNAVAILABLE = 0x00000004;
+
+	/**
+	 * Notification indicating that the properties of a previously discovered service
+	 * have changed and the new properties no longer match the listener's
+	 * filter.
+	 * <p>
+	 * The value of <code>MODIFIED_ENDMATCH</code> is 0x00000008.
+	 */
+	public final static int MODIFIED_ENDMATCH = 0x00000008;
+
+	/**
+	 * Returns information currently known to Discovery regarding the service
+	 * endpoint.
+	 * <p>
+	 * 
+	 * @return metadata of the service this Discovery notifies about.
+	 */
+	ServiceEndpointDescription getServiceEndpointDescription();
+
+	/**
+	 * Returns the type of notification. The type values are:
+	 * <ul>
+	 * <li>{@link #AVAILABLE} </li> <li>{@link #MODIFIED} </li> <li>
+	 * {@link #MODIFIED_ENDMATCH} </li> <li>{@link #UNAVAILABLE} </li>
+	 * </ul>
+	 * 
+	 * @return Type of notification regarding known service metadata.
+	 */
+	int getType();
+}

Added: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java (added)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.discovery;
+
+/**
+ * Interface of trackers for discovered remote services. <br>
+ * When such a service is registered with the framework, then {@link Discovery}
+ * will notify it about remote services matching one of the provided criteria
+ * and will keep notifying it on changes of information known to Discovery
+ * regarding this services.
+ * 
+ * <code>Discovery</code> may deliver notifications on discovered services to a
+ * <code>DiscoveredServiceTracker</code> out of order and may concurrently call
+ * and/or reenter a <code>DiscoveredServiceTracker</code>.
+ * 
+ * @version $Revision$
+ */
+public interface DiscoveredServiceTracker {
+
+	/**
+	 * Property describing service interfaces this tracker is interested in.
+	 * Value of this property is of type Collection (<? extends String>).<br>
+	 * Property is optional, may be null.
+	 */
+	public static final String PROP_KEY_MATCH_CRITERIA_INTERFACES = "osgi.discovery.interest.interfaces";
+
+	/**
+	 * Property describing filters for services this tracker is interested in.
+	 * Value of this property is of type Collection (<? extends String>). See
+	 * {@link ServicePublication} for some standard property keys used to
+	 * publish service metadata. <br>
+	 * Property is optional, may be null.
+	 */
+	public static final String PROP_KEY_MATCH_CRITERIA_FILTERS = "osgi.discovery.interest.filters";
+
+	/**
+	 * Receives notification that information known to Discovery regarding a
+	 * remote service has changed. <br>
+	 * The tracker is only notified about remote services which fulfill the
+	 * matching criteria, either one of the interfaces or one of the filters,
+	 * provided as properties of this service.
+	 * 
+	 * @param notification
+	 *            the <code>DiscoveredServiceNotification</code> object
+	 *            describing the change.
+	 */
+	void serviceChanged(DiscoveredServiceNotification notification);
+}

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/Discovery.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/Discovery.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/Discovery.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/Discovery.java Wed Jan 28 17:16:16 2009
@@ -16,187 +16,42 @@
 
 package org.osgi.service.discovery;
 
-import java.util.Collection;
-import java.util.Map;
-
 /**
- * Interface of the Discovery service. This service allows to publish services
- * exposed for remote access as well as search for remote services. <BR>
+ * Discovery registers a service implementing this interface. This service is
+ * registered with extra properties identified at the beginning of this
+ * interface to denote the name of the product providing Discovery
+ * functionality, its version, vendor, used protocols etc.. 
+ * 
+ * Discovery allows to publish services exposed for remote access as well as to
+ * search for remote services. Register a {@link ServicePublication} service in
+ * order to publish service metadata and or a {@link DiscoveredServiceTracker}
+ * service in order to search for remote services.<BR>
  * Discovery service implementations usually rely on some discovery protocols or
  * other information distribution means.
  * 
  * @version $Revision$
  */
 public interface Discovery {
-    /**
-     * 
-     */
-    final String OSGI_DISCOVERY = "osgi.discovery";
-
-    /**
-     * 
-     */
-    final String OSGI_DISCOVERY_NONE = "none";
-
-    /**
-     * 
-     */
-    final String OSGI_DISCOVERY_AUTO_PUBLISH = "auto-publish";
-
-    /**
-     * Add a ServiceListener for a particular service description.
-     * 
-     * @param filter
-     *            a filter to services to listen for. If filter is
-     *            <code>null</code> then all services are considered.
-     * @param listener
-     *            which is to call when discovery detects changes in
-     *            availability or description of a service. The same listener
-     *            object may be used to listen on multiple service filters.
-     * @throws IllegalArgumentException
-     *             if listener is null or if filter is invalid
-     */
-    void addServiceListener(ServiceListener listener, String filter);
-
-    /**
-     * This method is the same as calling
-     * <code>Discovery.addServiceListener(ServiceListener listener, String filter)</code>
-     * with <code>filter</code> set to <code>null</code>.
-     * 
-     * @param listener
-     *            which is to call when discovery detects changes in
-     *            availability or description of a service. The same listener
-     *            object may be used to listen on multiple service filters.
-     * @throws IllegalArgumentException
-     *             if listener is null
-     * @see #addServiceListener(ServiceListener, String)
-     */
-    void addServiceListener(ServiceListener listener);
-
-    /**
-     * Removes a ServiceListener.
-     * 
-     * @param listener
-     *            ServiceListener which should be removed. If that listener
-     *            object was registered several times then all registrations
-     *            will be removed. If that listener object haven't been added
-     *            before, then the method returns without throwing exceptions.
-     */
-    void removeServiceListener(ServiceListener listener);
-
-    /**
-     * Searches for services matching the provided interface name and filter.
-     * 
-     * @param interfaceName
-     *            name of the interface that returned services have to provide.
-     *            If name is null then all services are considered to match.
-     * @param filter
-     *            an LDAP filter which the service has to satisfy. If filter is
-     *            null all services are considered to match.
-     * @return Collection of <code>ServiceEndpointDescription</code> objects
-     *         which were found to match interface name and filter. The
-     *         collection is empty if none was found. The collection represents
-     *         a snapshot and as such is not going to be updated in case other matching
-     *         services become available at a later point of time.
-     */
-    Collection /* <? extends ServiceEndpointDescription> */findService(
-            String interfaceName, String filter);
-
-    /**
-     * Asynchronous version of <code>Discovery.findService(String interfaceName,
-     * String filter)</code> method.
-     * 
-     * @param interfaceName
-     *            name of the interface returned services have to provide. If
-     *            name is null then all services are considered to match.
-     * @param filter
-     *            an LDAP filter which the service has to satisfy. Note that
-     *            <code>ServiceEndpointDescription</code> defines some
-     *            properties for service url, interface version etc.. If filter
-     *            is null all services are considered to match.
-     * @param callback
-     *            to notify about the asynchronous response of the find
-     *            operation
-     * @throws IllegalArgumentException
-     *             if callback is null
-     * @see #findService(String, String)
-     */
-    void findService(String interfaceName, String filter,
-            FindServiceCallback callback);
-
-    /**
-     * Publish the provided service meta-data.
-     * 
-     * @param javaInterfacesAndVersions
-     *            names of java interfaces offered by the service and their
-     *            version. For every interface to publish you have to define its
-     *            version. If you don't have a version, put "0.0.0" in it.
-     * @param javaInterfacesAndEndpointInterfaces
-     *            associates java interfaces to general end point interface
-     *            names. It is not needed to to have and end point interface for
-     *            a java interface. The map may be null.
-     * @param properties
-     *            a bag of service properties (key-value pairs) to be published.
-     *            It may be null. Note that Discovery might make use of certain
-     *            standard properties like the ones defined by
-     *            {@link ServiceEndpointDescription} for the publication process
-     *            if they are provided.
-     * 
-     * @return an instance of {@link ServiceEndpointDescription} or null if the
-     *         publishing failed
-     * 
-     * @throws IllegalArgumentException
-     *             if javaInterfacesAndVersions is null or empty
-     */
-    ServiceEndpointDescription publishService(
-            Map/* <String, String> */javaInterfacesAndVersions,
-            Map/* <String, String> */javaInterfacesAndEndpointInterfaces,
-            Map/* <String, Object> */properties);
-
-    /**
-     * Publish the provided service. The information is published by the
-     * Discovery implementation.<b> If the parameter autopublish=true, the
-     * Discovery implementation actively pushes the information about the
-     * service to the network. Otherwise, it is just available upon request from
-     * other Discovery implementations. The ServiceEndpointDescription is
-     * matched using the Comparable interface.
-     * 
-     * @param javaInterfacesAndVersions
-     *            its an association between interfaces and versions. For every
-     *            interface to publish you have to define its version. If you
-     *            don't have a version, put "0.0.0" in it.
-     * @param javaInterfacesAndEndpointInterfaces
-     *            associates java interfaces to general end point interface
-     *            names. It is not needed to to have and end point interface for
-     *            a java interface. The map can be null.
-     * @param properties
-     *            a bag of properties to be published; can be null
-     * @param autopublish
-     *            if true, service information is actively pushed to the network
-     *            for discovery
-     * 
-     * @return an instance of {@link ServiceEndpointDescription} or null if the
-     *         publishing failed
-     * 
-     * @throws IllegalArgumentException
-     *             if javaInterfacesAndVersions is null or empty
-     */
-    ServiceEndpointDescription publishService(
-            Map/* <String, String> */javaInterfacesAndVersions,
-            Map/* <String, String> */javaInterfacesAndEndpointInterfaces,
-            Map/* <String, Object> */properties, boolean autopublish);
-
-    /**
-     * Make the given service un-discoverable. The previous publish request for
-     * a service is undone. The service information is also removed from the
-     * local or global cache if cached before.
-     * 
-     * @param serviceEndpointDescription
-     *            ServiceEndpointDescription of the service to unpublish. If
-     *            this ServiceEndpointDescription haven't been published before,
-     *            then the method returns without throwing exceptions.
-     * @throws IllegalArgumentException
-     *             if serviceEndpointDescription is null or incomplete
-     */
-    void unpublishService(ServiceEndpointDescription serviceEndpointDescription);
+
+	/**
+	 * Service Registration property for the name of the Discovery product.
+	 */
+	static final String PROP_KEY_PRODUCT_NAME = "osgi.remote.discovery.product";
+
+	/**
+	 * Service Registration property for the version of the Discovery product.
+	 */
+	static final String PROP_KEY_PRODUCT_VERSION = "osgi.remote.discovery.product.version";
+
+	/**
+	 * Service Registration property for the Discovery product vendor name.
+	 */
+	static final String PROP_KEY_VENDOR_NAME = "osgi.remote.discovery.vendor";
+
+	/**
+	 * Service Registration property that lists the discovery protocols used by
+	 * this Discovery service. Value of this property is of type Collection (<?
+	 * extends String>).
+	 */
+	static final String PROP_KEY_SUPPORTED_PROTOCOLS = "osgi.remote.discovery.supported_protocols";
 }

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java Wed Jan 28 17:16:16 2009
@@ -21,96 +21,95 @@
 import java.util.Map;
 
 /**
- * The ServiceEndpointDescription interface describes an endpoint of a service.
- * This class can be considered as a wrapper around the property map associated
- * with a service and its endpoint. It provides an API to conveniently access
- * the most important properties of the service.
+ * This interface describes an endpoint of a service. This class can be
+ * considered as a wrapper around the property map of a published service and
+ * its endpoint. It provides an API to conveniently access the most important
+ * properties of the service.
  * 
  * @version $Revision$
  */
 public interface ServiceEndpointDescription {
-    /**
-     * If value of <code>getProtocolSpecificInterfaceName</code> needs to be
-     * described as a key-value pair e.g. by the discovery protocol, filter for
-     * discovery etc. and there is no other key standardized for that purpose
-     * yet, then this is the recommended property key to use.
-     */
-    public final String PROP_KEY_PROTOCOL_SPECIFIC_INTERFACE_NAME = "protocol-specific-interface-name";
-
-    /**
-     * If value of <code>getVersion</code> needs to be described as a key-value
-     * pair e.g. by the discovery protocol, filter for discovery etc. and there
-     * is no other key standardized for that purpose yet, then this is the
-     * recommended property key to use.
-     */
-    public final String PROP_KEY_VERSION = "version";
-
-    /**
-     * If value of <code>getServiceLocation</code> needs to be described as a
-     * key-value pair e.g. by the discovery protocol, filter for discovery etc.
-     * and there is no other key standardized for that purpose yet, then this is
-     * the recommended property key to use.
-     */
-    public final String PROP_KEY_SERVICE_LOCATION = "location";
-
-    /**
-     * @return full qualified service interface names provided by the advertised
-     *         service (endpoint). The collection is never null or
-     *         empty but contains at least one service interface. 
-     */
-    Collection /* <? extends String> */getInterfaceNames();
-
-    /**
-     * @param interfaceName
-     *            for which its communication protocol specific version should
-     *            be returned. It might be for instance a web service interface
-     *            name. Though this information is usually contained in
-     *            according interface descriptions, e.g. a wsdl file, it can
-     *            optionally be provided here as well since discovery usually
-     *            doesn't read and interprets such accompanying descriptions.
-     * 
-     * @return The protocol specific service interface name.
-     */
-    String getProtocolSpecificInterfaceName(String interfaceName);
-
-    /**
-     * @param interfaceName
-     *            for which its version should be returned.
-     * @return The service interface/implementation version.
-     */
-    String getVersion(String interfaceName);
-
-    /**
-     * @return The URL of the service location.
-     */
-    URL getLocation();
-
-    /**
-     * Getter method for the property value of a given key.
-     * 
-     * @param key
-     *            Name of the property
-     * @return The property value, null if none is found for the given key
-     */
-    Object getProperty(String key);
-
-    /**
-     * @return <code>java.util.Collection</code> of property names available in
-     *         the ServiceEndpointDescription. The collection is never null or
-     *         empty but contains at least basic properties like objectClass for
-     *         the service interface. The collection represents a snapshot and
-     *         as such is not going to be updated in case properties were added
-     *         or removed at a later point of time.
-     */
-    Collection/* <? extends String> */getPropertyKeys();
-
-    /**
-     * @return Returns all properties of the service as a
-     *         <code>java.util.Map</code>. The map is never null or empty but
-     *         contains at least basic properties like objectClass for the
-     *         service interface. The collection represents a snapshot and as
-     *         such is not going to be updated in case properties were added or
-     *         removed at a later point of time.
-     */
-    Map/* <String, Object> */getProperties();
+
+	/**
+	 * Returns the value of the property with key
+	 * {@link ServicePublication#PROP_KEY_SERVICE_INTERFACE_NAME}.
+	 * 
+	 * @return service interface names provided by the advertised service
+	 *         (endpoint). The collection is never null or empty but contains at
+	 *         least one service interface.
+	 */
+	Collection /* <? extends String> */getProvidedInterfaces();
+
+	/**
+	 * Returns non-Java endpoint interface name associated with the given
+	 * interface. Value of the property with key
+	 * {@link ServicePublication#PROP_KEY_ENDPOINT_INTERFACE_NAME} is used by
+	 * this operation.
+	 * 
+	 * @param interfaceName
+	 *            for which its non-Java endpoint interface name should be
+	 *            returned. 
+	 *            
+	 * @return non-Java endpoint interface name. Null, if it hasn't been
+	 *         provided.
+	 */
+	String getEndpointInterfaceName(String interfaceName);
+
+	/**
+	 * Returns version of the given interface. Value of the property with key
+	 * {@link ServicePublication#PROP_KEY_SERVICE_INTERFACE_VERSION} is used by
+	 * this operation.
+	 * 
+	 * @param interfaceName
+	 *            for which its version should be returned.
+	 * @return Version of given service interface. Null, if it hasn't been
+	 *         provided.
+	 */
+	String getVersion(String interfaceName);
+
+	/**
+	 * Returns the value of the property with key
+	 * {@link ServicePublication#PROP_KEY_ENDPOINT_LOCATION}.
+	 * 
+	 * @return The URL of the service location. Null, if it hasn't been
+	 *         provided.
+	 */
+	URL getLocation();
+
+	/**
+	 * Returns the value of the property with key
+	 * {@link ServicePublication#PROP_KEY_ENDPOINT_ID}.
+	 * 
+	 * @return Unique id of service endpoint. Null, if it hasn't been provided.
+	 */
+	String getEndpointID();
+
+	/**
+	 * Getter method for the property value of a given key.
+	 * 
+	 * @param key
+	 *            Name of the property
+	 * @return The property value, null if none is found for the given key
+	 */
+	Object getProperty(String key);
+
+	/**
+	 * @return <code>java.util.Collection</code> of property names available in
+	 *         the ServiceEndpointDescription. The collection is never null or
+	 *         empty but contains at least basic properties like objectClass for
+	 *         the service interface. The collection represents a snapshot and
+	 *         as such is not going to be updated in case properties were added
+	 *         or removed at a later point of time.
+	 */
+	Collection/* <? extends String> */getPropertyKeys();
+
+	/**
+	 * @return Returns all properties of the service as a
+	 *         <code>java.util.Map</code>. The map is never null or empty but
+	 *         contains at least basic properties like objectClass for the
+	 *         service interface. The collection represents a snapshot and as
+	 *         such is not going to be updated in case properties were added or
+	 *         removed at a later point of time.
+	 */
+	Map/* <String, Object> */getProperties();
 }

Added: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java (added)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.discovery;
+
+/**
+ * Register a service implementing the <code>ServicePublication</code> interface
+ * in order to publish metadata of a particular service (endpoint) via
+ * Discovery. Metadata which has to be published is given in form of properties
+ * at registration. <br>
+ * In order to update published service metadata, update the properties
+ * registered with the <code>ServicePublication</code> service. Depending on
+ * Discovery's implementation and underlying protocol it may result in an update
+ * or new re-publication of the service. <br>
+ * In order to unpublish the previously published service metadata, unregister
+ * the <code>ServicePublication</code> service.<br>
+ * 
+ * Please note that providing the {@link #PROP_KEY_SERVICE_INTERFACE_NAME}
+ * property is mandatory when a <code>ServicePublication</code> service is
+ * registered.<br>
+ * 
+ * Also important is that it's not guaranteed that after registering a
+ * <code>ServicePublication</code> object its service metadata is actually
+ * published. Beside the fact that at least one Discovery service has to be
+ * present, the provided properties have to be valid, e.g. shouldn't contain
+ * case variants of the same key name, a supported publication strategy used and
+ * the actual publication via Discovery mechanisms has to succeed.
+ * 
+ * @version $Revision$
+ */
+public interface ServicePublication {
+
+	/**
+	 * Mandatory ServiceRegistration property which contains a collection of
+	 * full qualified interface names offered by the advertised service
+	 * endpoint. Value of this property is of type Collection (<? extends
+	 * String>).
+	 */
+	public static final String PROP_KEY_SERVICE_INTERFACE_NAME = "service.interface";
+
+	/**
+	 * Optional ServiceRegistration property which contains a collection of
+	 * interface names with their associated version attributes separated by
+	 * {@link #SEPARATOR} e.g. 'my.company.foo:1.3.5 my.company.zoo:2.3.5'. In
+	 * case no version has been provided for an interface, Discovery may use the
+	 * String-value of <code>org.osgi.framework.Version.emptyVersion</code>
+	 * constant. <br>
+	 * Value of this property is of type Collection (<? extends String>).
+	 */
+	public static final String PROP_KEY_SERVICE_INTERFACE_VERSION = "service.interface.version";
+
+	/**
+	 * Optional ServiceRegistration property which contains a collection of
+	 * interface names with their associated (non-Java) endpoint interface names
+	 * separated by {@link #SEPARATOR} e.g.:<br>
+	 * 'my.company.foo:MyWebService my.company.zoo:MyWebService'.<br>
+	 * This (non-Java) endpoint interface name is usually a communication
+	 * protocol specific interface, for instance a web service interface name.
+	 * Though this information is usually contained in accompanying properties
+	 * e.g. a wsdl file, Discovery usually doesn't read and interprets such
+	 * service meta-data. Providing this information explicitly, might allow
+	 * external non-Java applications find services based on this endpoint
+	 * interface.
+	 * 
+	 * Value of this property is of type Collection (<? extends String>).
+	 */
+	public static final String PROP_KEY_ENDPOINT_INTERFACE_NAME = "osgi.remote.endpoint.interface";
+
+	/**
+	 * Optional ServiceRegistration property which contains a map of properties
+	 * of the published service. <br>
+	 * Property keys are handled in a case insensitive manner (as OSGi Framework
+	 * does). Note that Discovery might make use of certain standard properties
+	 * e.g. defined by {@link ServiceEndpointDescription} for the publication
+	 * process if they are provided.<br>
+	 * Value of this property is of type <code>java.util.Map<code>.
+	 */
+	public static final String PROP_KEY_SERVICE_PROPERTIES = "service.properties";
+
+	/**
+	 * Optional property of the published service identifying its location.
+	 * Value of this property is of type <code>java.net.URL<code>.
+	 */
+	public static final String PROP_KEY_ENDPOINT_LOCATION = "osgi.remote.endpoint.location";
+
+	/**
+	 * Optional property of the published service uniquely identifying its
+	 * endpoint. Value of this property is of type <code>String<code>.
+	 */
+	public static final String PROP_KEY_ENDPOINT_ID = "osgi.remote.endpoint.id";
+
+	/**
+	 * Separator for key value pairs.
+	 */
+	public static final String SEPARATOR = ":";
+}

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java Wed Jan 28 17:16:16 2009
@@ -116,7 +116,7 @@
         assertEquals("Precondition failed", 0, services.size());
         a.start(bc);
         
-        assertEquals(3, services.size());
+        assertEquals(4, services.size());
         CxfDistributionProvider dp = null;
         for (Object o : services.keySet()) {
             if (o instanceof CxfDistributionProvider) {

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/TestUtils.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/TestUtils.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/TestUtils.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/TestUtils.java Wed Jan 28 17:16:16 2009
@@ -36,7 +36,7 @@
         }
         
         ServiceEndpointDescription sd = EasyMock.createNiceMock(ServiceEndpointDescription.class);
-        sd.getInterfaceNames();
+        sd.getProvidedInterfaces();
         EasyMock.expectLastCall().andReturn(iList);
         return sd;
     }

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java Wed Jan 28 17:16:16 2009
@@ -43,9 +43,14 @@
     private Object serviceObject;
     private Map<String, ServiceReference> testReferences = new
         HashMap<String, ServiceReference>();
+    private Map<String, ServiceRegistration> testRegistrations = new
+        HashMap<String, ServiceRegistration>();
     private Map<String, ServiceReference> registeredReferences = new
         HashMap<String, ServiceReference>();
-    
+    private Map<String, ServiceRegistration> registeredRegistrations = new
+        HashMap<String, ServiceRegistration>();
+    private Map<String, List<Dictionary>> registeredProperties = new
+        HashMap<String, List<Dictionary>>();
         
     public BundleTestContext(Bundle b) {
         bundle = b;
@@ -122,9 +127,10 @@
         return null;
     }
 
-    public ServiceRegistration registerService(String arg0, Object arg1, Dictionary arg2) {
-        // TODO Auto-generated method stub
-        return null;
+    public ServiceRegistration registerService(String clz, Object obj, Dictionary props) {
+        registeredRegistrations.put(clz, testRegistrations.get(clz));
+        cacheProperties(clz, props);
+        return testRegistrations.get(clz);
     }
 
     public void removeBundleListener(BundleListener arg0) {
@@ -144,8 +150,29 @@
     public void addServiceReference(String name, ServiceReference sref) {
         testReferences.put(name, sref);
     }
+
+    public void addServiceRegistration(String name, ServiceRegistration reg) {
+        testRegistrations.put(name, reg);
+    }
     
-    public List<ServiceReference> getRegisteredReferences() {
-        return new ArrayList<ServiceReference>(registeredReferences.values());
+    public Map<String, ServiceReference> getRegisteredReferences() {
+        return registeredReferences;
+    }
+
+    public Map<String, ServiceRegistration> getRegisteredRegistrations() {
+        return registeredRegistrations;
+    }
+
+    public Map<String, List<Dictionary>> getRegisteredProperties() {
+        return registeredProperties;
+    }
+
+    private void cacheProperties(String clz, Dictionary props) {
+        List<Dictionary> propsList = registeredProperties.get(clz);
+        if (propsList == null) {
+            propsList = new ArrayList<Dictionary>();
+            registeredProperties.put(clz, propsList);
+        }
+        propsList.add(props);
     }
 }

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java Wed Jan 28 17:16:16 2009
@@ -23,6 +23,7 @@
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.cxf.dosgi.dsw.service.CxfDistributionProvider;
 import org.easymock.classextension.EasyMock;
@@ -33,8 +34,11 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.hooks.service.ListenerHook;
 
+import org.osgi.service.discovery.DiscoveredServiceTracker;
+
 public class CxfListenerHookTest extends Assert {
 
     private IMocksControl control;
@@ -85,9 +89,8 @@
         assertEquals(1, registeredRefs.size());        
     } */
     
-    @Test
+    //@Test
     public void testListenerHook() throws Exception {
-        
         Bundle bundle = control.createMock(Bundle.class);
         bundle.findEntries(EasyMock.eq("OSGI-INF/remote-service"), 
             EasyMock.eq("*.xml"), EasyMock.anyBoolean());
@@ -100,32 +103,52 @@
                           "1.0.0");
         bundle.getHeaders();
         EasyMock.expectLastCall().andReturn(bundleHeaders).anyTimes();
-        bundle.loadClass(TestService.class.getName());
+        final String serviceClass = TestService.class.getName();
+        bundle.loadClass(serviceClass);
         EasyMock.expectLastCall().andReturn(TestService.class).anyTimes();
         final BundleContext requestingContext = control.createMock(BundleContext.class);
         requestingContext.getBundle();
         EasyMock.expectLastCall().andReturn(bundle).anyTimes();
         
         BundleTestContext dswContext = new BundleTestContext(bundle);
-        dswContext.addServiceReference(TestService.class.getName(), 
-                                       control.createMock(ServiceReference.class));
+	ServiceReference reference = control.createMock(ServiceReference.class);
+        dswContext.addServiceReference(serviceClass, reference);
+
+        final String trackerClass = DiscoveredServiceTracker.class.getName();
+        ServiceRegistration registration =
+            control.createMock(ServiceRegistration.class);
+        dswContext.addServiceRegistration(trackerClass, registration);
+        registration.setProperties(EasyMock.isA(Dictionary.class));
+        EasyMock.expectLastCall();
+
         control.replay();
      
         CxfListenerHook hook = new CxfListenerHook(dswContext, null);
+
         ListenerHook.ListenerInfo info = new ListenerHook.ListenerInfo() {
             public BundleContext getBundleContext() {
                 return requestingContext;
             }
 
             public String getFilter() {
-                return "(objectClass=" + TestService.class.getName() + ")";
+                return "(objectClass=" + serviceClass + ")";
             }            
         };
         hook.added(Collections.singleton(info));
         
-        List<ServiceReference> registeredRefs = dswContext.getRegisteredReferences();
+        Map<String, ServiceReference> registeredRefs = 
+            dswContext.getRegisteredReferences();
         assertNotNull(registeredRefs);
-        assertEquals(1, registeredRefs.size());        
+        assertEquals(1, registeredRefs.size());
+        assertNotNull(registeredRefs.get(serviceClass));
+        assertSame(reference, registeredRefs.get(serviceClass));
+
+        Map<String, ServiceRegistration> registeredRegs = 
+            dswContext.getRegisteredRegistrations();
+        assertNotNull(registeredRegs);
+        assertEquals(1, registeredRegs.size());
+        assertNotNull(registeredRegs.get(trackerClass));
+        assertSame(registration, registeredRegs.get(trackerClass));
     } 
 
     @Test

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java Wed Jan 28 17:16:16 2009
@@ -41,7 +41,15 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.discovery.ServiceEndpointDescription;
+import org.osgi.service.discovery.ServicePublication;
+
+import static org.apache.cxf.dosgi.dsw.Constants.POJO_ADDRESS_PROPERTY;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_ENDPOINT_LOCATION;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_SERVICE_INTERFACE_NAME;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_SERVICE_PROPERTIES;
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_ENDPOINT_LOCATION;
 
 public class CxfPublishHookTest extends Assert {
 
@@ -100,11 +108,15 @@
         sref.getPropertyKeys();                           
         EasyMock.expectLastCall().andReturn(new String[]{}).anyTimes();
         
-        BundleContext dswContext = new BundleTestContext(bundle);
+        BundleTestContext dswContext = new BundleTestContext(bundle);
         dswContext.registerService(serviceNames, serviceObject, serviceProps);
         
         Server server = control.createMock(Server.class);
-        
+
+        String publicationClass = ServicePublication.class.getName();
+        ServiceRegistration registration =
+            control.createMock(ServiceRegistration.class);
+        dswContext.addServiceRegistration(publicationClass, registration);
         control.replay();
      
         TestPublishHook hook = new TestPublishHook(dswContext, 
@@ -121,9 +133,9 @@
             assertNotNull(list.get(i));
             ServiceEndpointDescription sd = list.get(i).getServiceDescription();
             assertNotNull(sd);
-            assertNotNull(sd.getInterfaceNames());
-            assertEquals(1, sd.getInterfaceNames().size());
-            Collection names = sd.getInterfaceNames();
+            assertNotNull(sd.getProvidedInterfaces());
+            assertEquals(1, sd.getProvidedInterfaces().size());
+            Collection names = sd.getProvidedInterfaces();
             assertEquals(1, names.size());
             assertEquals(serviceNames[i], names.toArray()[0]);
             String excludeProp = 
@@ -133,6 +145,28 @@
                 org.apache.cxf.dosgi.dsw.Constants.POJO_ADDRESS_PROPERTY;
             assertEquals(addresses[i], sd.getProperties().get(addrProp));
         }        
+
+        Map<String, ServiceRegistration> registeredRegs = 
+            dswContext.getRegisteredRegistrations();
+        assertNotNull(registeredRegs);
+        assertEquals(1, registeredRegs.size());
+        assertNotNull(registeredRegs.get(publicationClass));
+        assertSame(registration, registeredRegs.get(publicationClass));
+
+        Map<String, List<Dictionary>> registeredProps = 
+            dswContext.getRegisteredProperties();
+        assertNotNull(registeredProps);
+        assertEquals(1, registeredProps.size());
+        assertNotNull(registeredProps.get(publicationClass));
+        List<Dictionary> propsList = registeredProps.get(publicationClass);
+        assertEquals(serviceNames.length, propsList.size());
+        for (Dictionary props : propsList) {
+            Collection interfaces = 
+                (Collection)props.get(PROP_KEY_SERVICE_INTERFACE_NAME);
+            assertNotNull(interfaces);
+            assertTrue(interfaces.contains(TestService.class.getName())
+                       || interfaces.contains(AdditionalInterface.class.getName()));
+	}
     }
     
     @SuppressWarnings("unchecked")
@@ -221,6 +255,11 @@
                                            ServiceEndpointDescription sd, Class<?> iClass, Object serviceBean) {
                     Assert.assertSame(serviceBean, serviceObject);
                     TestPublishHook.this.setCalled();
+                    Map props = sd.getProperties();
+                    String address = (String)props.get(POJO_ADDRESS_PROPERTY);
+                    if (address != null) {
+                        props.put(PROP_KEY_ENDPOINT_LOCATION, address);
+		    }
                     return server;
                 }
                 

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtilsTest.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtilsTest.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtilsTest.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtilsTest.java Wed Jan 28 17:16:16 2009
@@ -79,7 +79,7 @@
 	    iList.add(iName);
 	}
         ServiceEndpointDescription sd = control.createMock(ServiceEndpointDescription.class);
-        sd.getInterfaceNames();
+        sd.getProvidedInterfaces();
         EasyMock.expectLastCall().andReturn(iList);
         return sd;
     }



Mime
View raw message