Return-Path: Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: (qmail 63301 invoked from network); 28 Jan 2009 17:16:52 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 28 Jan 2009 17:16:52 -0000 Received: (qmail 96081 invoked by uid 500); 28 Jan 2009 17:16:52 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 95974 invoked by uid 500); 28 Jan 2009 17:16:52 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 95965 invoked by uid 99); 28 Jan 2009 17:16:51 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Jan 2009 09:16:51 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Jan 2009 17:16:45 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 694A123889F3; Wed, 28 Jan 2009 17:16:24 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@cxf.apache.org From: eglynn@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090128171624.694A123889F3@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 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(getProperties(sd))); - } - + actualContext.registerService(new String[]{interfaceName}, + new ClientServiceFactory(actualContext, iClass, sd, handler), + new Hashtable(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 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 sds = new ArrayList(); + + protected synchronized boolean lookupCurrentBundle(BundleContext context, + String interfaceName, + String filter) { + // if bundle has remote-services.xml attached then those metadata + // take precedence + List sds = + new ArrayList(); + + // 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 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 notified = - new ArrayList(); - 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(); + 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 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 pair = OsgiUtils.getOsgiService(getContext(), Discovery.class); - if (pair != null) { - try { - Collection sds = - pair.getService().findService(interfaceName, filterValue); - if (sds != null) { - return (Collection)sds; - } - } finally { - pair.ungetService(getContext()); - } - } - - return Collections.emptyList(); - } - - protected Collection listenToDiscoveryService( - ServiceListener listener, String filterValue) { - - OsgiService pair = OsgiUtils.getOsgiService(getContext(), Discovery.class); - if (pair != null) { - try { - pair.getService().addServiceListener(listener, filterValue); - } finally { - pair.ungetService(getContext()); - } - } - - return Collections.emptyList(); - } - - protected Collection unlistenToDiscoveryService( - ServiceListener listener) { - - OsgiService 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> endpoints - = new LinkedHashMap>(); + protected Map> endpoints = + new LinkedHashMap>(); + private Map publications = + new LinkedHashMap(); 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 endpointList : endpoints.values()) { + for (ServiceReference sref : endpoints.keySet()) { + List 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 pair = OsgiUtils.getOsgiService(bc, Discovery.class); - if (pair != null) { - try { - Map javaInterfaces = getJavaInterfaceVersionMap(sd); - Map endpointInterfaces = getJavaInterfaceEndpointInterfaceMap(sd); - Map 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 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 getJavaInterfaceVersionMap(ServiceEndpointDescription sd) { - Map interfaceNames = new HashMap(); - Iterator iNames = sd.getInterfaceNames().iterator(); - while (iNames.hasNext()) { - String interfaceName = (String)iNames.next(); - interfaceNames.put(interfaceName, sd.getVersion(interfaceName)); - } - return interfaceNames; - } - - private static Map getJavaInterfaceEndpointInterfaceMap(ServiceEndpointDescription sd) { - return Collections.emptyMap(); - } - - private static Map getPropertiesMap(ServiceEndpointDescription sd) { + private static Map getServiceProperties(ServiceEndpointDescription sd) { Map props = new HashMap(); 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 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 getInterfaceNames() { + public Collection 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. + *

+ * The value of AVAILABLE is 0x00000001. + */ + public final static int AVAILABLE = 0x00000001; + + /** + * Notification indicating that the properties of a previously discovered service + * have changed. + *

+ * The value of MODIFIED is 0x00000002. + */ + public final static int MODIFIED = 0x00000002; + + /** + * Notification indicating that a previously discovered service is no longer known + * to discovery. + *

+ * The value of UNAVAILABLE 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. + *

+ * The value of MODIFIED_ENDMATCH is 0x00000008. + */ + public final static int MODIFIED_ENDMATCH = 0x00000008; + + /** + * Returns information currently known to Discovery regarding the service + * endpoint. + *

+ * + * @return metadata of the service this Discovery notifies about. + */ + ServiceEndpointDescription getServiceEndpointDescription(); + + /** + * Returns the type of notification. The type values are: + *

    + *
  • {@link #AVAILABLE}
  • {@link #MODIFIED}
  • + * {@link #MODIFIED_ENDMATCH}
  • {@link #UNAVAILABLE}
  • + *
+ * + * @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.
+ * 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. + * + * Discovery may deliver notifications on discovered services to a + * DiscoveredServiceTracker out of order and may concurrently call + * and/or reenter a DiscoveredServiceTracker. + * + * @version $Revision$ + */ +public interface DiscoveredServiceTracker { + + /** + * Property describing service interfaces this tracker is interested in. + * Value of this property is of type Collection ().
+ * 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 (). See + * {@link ServicePublication} for some standard property keys used to + * publish service metadata.
+ * 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.
+ * 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 DiscoveredServiceNotification 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.
+ * 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.
* 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 - * null 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 - * Discovery.addServiceListener(ServiceListener listener, String filter) - * with filter set to null. - * - * @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 ServiceEndpointDescription 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 /* */findService( - String interfaceName, String filter); - - /** - * Asynchronous version of Discovery.findService(String interfaceName, - * String filter) 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 - * ServiceEndpointDescription 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/* */javaInterfacesAndVersions, - Map/* */javaInterfacesAndEndpointInterfaces, - Map/* */properties); - - /** - * Publish the provided service. The information is published by the - * Discovery implementation. 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/* */javaInterfacesAndVersions, - Map/* */javaInterfacesAndEndpointInterfaces, - Map/* */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 (). + */ + 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 getProtocolSpecificInterfaceName 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 getVersion 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 getServiceLocation 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 /* */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 java.util.Collection 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/* */getPropertyKeys(); - - /** - * @return Returns all properties of the service as a - * java.util.Map. 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/* */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 /* */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 java.util.Collection 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/* */getPropertyKeys(); + + /** + * @return Returns all properties of the service as a + * java.util.Map. 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/* */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 ServicePublication 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.
+ * In order to update published service metadata, update the properties + * registered with the ServicePublication service. Depending on + * Discovery's implementation and underlying protocol it may result in an update + * or new re-publication of the service.
+ * In order to unpublish the previously published service metadata, unregister + * the ServicePublication service.
+ * + * Please note that providing the {@link #PROP_KEY_SERVICE_INTERFACE_NAME} + * property is mandatory when a ServicePublication service is + * registered.
+ * + * Also important is that it's not guaranteed that after registering a + * ServicePublication 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 (). + */ + 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 org.osgi.framework.Version.emptyVersion + * constant.
+ * Value of this property is of type Collection (). + */ + 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.:
+ * 'my.company.foo:MyWebService my.company.zoo:MyWebService'.
+ * 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 (). + */ + 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.
+ * 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.
+ * Value of this property is of type java.util.Map. + */ + 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 java.net.URL. + */ + 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 String. + */ + 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 testReferences = new HashMap(); + private Map testRegistrations = new + HashMap(); private Map registeredReferences = new HashMap(); - + private Map registeredRegistrations = new + HashMap(); + private Map> registeredProperties = new + HashMap>(); 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 getRegisteredReferences() { - return new ArrayList(registeredReferences.values()); + public Map getRegisteredReferences() { + return registeredReferences; + } + + public Map getRegisteredRegistrations() { + return registeredRegistrations; + } + + public Map> getRegisteredProperties() { + return registeredProperties; + } + + private void cacheProperties(String clz, Dictionary props) { + List propsList = registeredProperties.get(clz); + if (propsList == null) { + propsList = new ArrayList(); + 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 registeredRefs = dswContext.getRegisteredReferences(); + Map registeredRefs = + dswContext.getRegisteredReferences(); assertNotNull(registeredRefs); - assertEquals(1, registeredRefs.size()); + assertEquals(1, registeredRefs.size()); + assertNotNull(registeredRefs.get(serviceClass)); + assertSame(reference, registeredRefs.get(serviceClass)); + + Map 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 registeredRegs = + dswContext.getRegisteredRegistrations(); + assertNotNull(registeredRegs); + assertEquals(1, registeredRegs.size()); + assertNotNull(registeredRegs.get(publicationClass)); + assertSame(registration, registeredRegs.get(publicationClass)); + + Map> registeredProps = + dswContext.getRegisteredProperties(); + assertNotNull(registeredProps); + assertEquals(1, registeredProps.size()); + assertNotNull(registeredProps.get(publicationClass)); + List 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; }